En C, le prototype de la fonction de valeur absolue (qui accepte un flottant) est
float fabsf( float );
Pourquoi ce prototype n'accepte-t-il pas une valeur constante, comme ceci:
float fabsf( float const );
fabsf ne changera pas la valeur de l'entrée, n'est-ce pas?
Si j'ai une fonction qui accepte une entrée et appelle fabsf, suis-je obligé d'éviter de spécifier l'entrée comme const?
Quelle est la façon appropriée de gérer l'exactitude de const dans cette situation?
c
function
const
pass-by-value
user24205
la source
la source
const
est redondant ici, que pensez-vous qu'il se passe?const
n'a aucun sens.float const x = -1.0; float y = fabsf(x);
il me semble que lefabsf
fait d' accepter des entrées const. Il n'y a aucun moyen de dire "vous pouvez me passer unefloat
valeur mais vous ne pouvez pas passer uneconst float
." (Et comme nous le voyons dans les réponses, C ne fournit pas un moyen d' exiger que l'entrée d'une fonction soit afloat const
.)Réponses:
Éditer
Comme MM l'a commenté, sur les paramètres des prototypes, le
const
est ignoré. La source éditée de la réponse originale (voir ci-dessous) montre ceci:Il n'y a aucun message d'erreur.
Quoi qu'il en soit, je vais laisser l'original en place dans l'espoir que cela puisse aider.
Original
Le
const
paramètre at a rend ce paramètre en lecture seule à l'intérieur de la fonction.Par exemple:
Cette source ne se compilera pas sans message d'erreur.
La fonction
correct()
lira la valeur donnée, changera son signe et renverra la valeur négative.La fonction
erroneous()
semble faire la même chose, sauf qu'il y a une affectation au paramètre. Mais comme le paramètre est,const
ce n'est pas autorisé.Ensuite, la fonction
changer()
fonctionnera comme les deux avant, mais elle ne donne aucune erreur.Regardons le site de l'appel:
La variable
f
donnée en argument sera copiée dans le paramètrevalue
. Il ne changera jamais même s'ilchanger()
sera appelé.Vous voudrez peut-être regarder les paramètres comme une sorte de variables locales. En fait, ils sont principalement traités comme cela dans le code machine généré.
Alors, pourquoi voyez-vous
const
parfois? Vous le voyez si un pointeur est défini comme paramètre.Lorsque vous ne voulez pas que la valeur pointée soit modifiée, vous devez ajouter
const
; mais faites-le à la bonne position!la source
float fabsf( float const );
n'a rien à voir avec l'implémentation de la fonction (qui n'a pas à répéter leconst
), en fait, ilconst
est ignoré entièrement dans le prototypeC utilise le passage par valeur. La valeur du paramètre d'une fonction est une copie de l'argument que vous donnez.
Il est correct de copier les flotteurs const et non const, et le résultat est un flotteur non const.
C'est similaire à l'affectation:
En fait, le langage spécifie que la valeur d'une expression ne peut jamais être
const
, c'est-à-dire quand une valeur est lue dans une variable, cette valeur n'est pasconst
même si la variable l'était.la source
Étant donné que le langage C utilise la sémantique de passage par valeur, tout argument que vous lui passez, bien qu'il puisse être modifié en interne, n'affecte pas directement la valeur que vous transmettez.
Cela signifie que du point de vue de l'appelant,
float fabsf( float );
etfloat fabsf( const float );
sont les mêmes. Il est donc inutile de faire le paramètreconst
.Il peut être judicieux d'utiliser
const
le paramètre si vous passez un pointeur, par exemple:Cette fonction, malgré ce que son nom l'indique, peut déréférencer le pointeur donné et modifier ce qu'il pointe, c'est
str[0] = 'x'
-à- dire pour entraîner un changement visible par la fonction appelante. Si cette fonction était définie comme ceci:L'appelant est assuré que la fonction ne peut effectuer aucune modification sur ce qui
str
pointe vers.la source
((char*)str)[0] = 'f'
. Laconst ... *
liste des arguments n'est donc qu'une "déclaration d'intention".Pour ajouter une perspective d'avocat linguistique:
Cela signifie que ces deux sont compatibles:
Par conséquent, vous pouvez écrire le prototype avec ou sans
const
(ce qui signifie sans plus de sens; moins à taper / lire) et pouvez ajouterconst
la définition de fonction si vous voulez éviter de modifier accidentellement le paramètre (copié - appeler par valeur!) À l'intérieur des fonctions corps.la source