NULL
est-il assimilé à une valeur fausse ?!
sur un nombre négatif ?a[i] = i++
?i++
vaut i
?i++ * i++
?&&
et ||
?_Bool
défini dans <stdbool.h>
. Cet en-tête contient
également les définitions de true
et false
.
Une macro bool
est souvent définie comme équivalent à
_Bool
.
Rappelons également qu'en C, une valeur est « fausse » si elle est
nulle (ou équivalent), et « vraie » sinon. Les définitions de
true
et false
suivent cette règle. Ainsi, la
valeur entière de true
est 1
et celle de
false
est 0
.
NULL
est-il assimilé à une valeur fausse ?NULL
est apparentée à un 0
.
Les écritures if(p != NULL)
et if(p)
sont donc équivalentes. De même, if(p == NULL)
est
équivalent à if(!p)
.
Voir aussi les questions 10.1 et 7.5.
!
sur un nombre négatif ?!
sur un nombre négatif donne bien ce que l'on
attend, à savoir 0
.
Voir aussi la question 10.1.
a[i] = i++
?++
modifie la valeur de i
, alors que
celle-ci est utilisée ailleurs dans l'expression.
C'est ce que l'on appelle un « effet de bords ».
i++
vaut i
?i++
vaut i
, avant
l'incrémentation. Toutefois, rien ne dit dans quel sens est
calculée l'expression a[i] = i++
.
Est-ce le i++
qui est évalué avant le a[i]
, ou
le contraire ?
On n'en sait rien, c'est pourquoi l'on dit que c'est un
comportement indéfini.
i++ * i++
?
a = f() + g() * h();
b = (f() + g()) * h();
Les parenthèses dans la deuxième expression modifient l'ordre d'évaluation de l'addition et de la multiplication. Par contre, l'ordre dans lequel seront évaluées les fonctions est indéfini, dans l'une ou l'autre des deux expressions. Cela ne dépend que du compilateur.
Pour forcer un ordre d'évaluation, il faut utiliser une écriture séquentielle, avec des variables temporaires.
tf = f();
tg = g();
th = h();
b = (tf + tg) * th;
On a alors un comportement parfaitement défini sur toutes les cibles, quel que soit le compilateur.
&&
et ||
?
long double
, l'autre
est converti en un long double
.
double
,
l'autre est converti en un double
.
float
,
l'autre est converti en un float
.
char
et
short
sont convertis en int
.
long
, l'autre
est converti en un long
.
long long
.
Cela se complique dans le cas d'opérandes unsigned
.
Les comparaisons entre valeurs signées et non signées dépendent de
la machine et de la taille des différents types.
Quand le compilateur prévient que le membre gauche d'une affectation n'est pas une lvalue, c'est souvent parce que l'on ne voulait pas faire une affectation, mais une comparaison (cf. 15.5).
faq-fclc 5/3/2002 (8h 59:05)