58 votes

'\ 0' évalue faux, "\ 0" évalue vrai

Inspiré d'un programme décrit dans la section 5.5 de K & R :

 void strcpy(char *s, char *t)
{
    while(*s++ = *t++);
}
 

Programme C

 if ('\0') { printf("\'\\0\' -> true \n"); }
else      { printf("\'\\0\' -> false\n"); }

if ("\0") { printf("\"\\0\" -> true \n"); }
else      { printf("\"\\0\" -> false\n"); }
 

empreintes

 '\0' -> false
"\0" -> true
 

Pourquoi '\0' et "\0" évaluent-ils différemment en C?

Clang version 3.8.0

118voto

immibis Points 5859

Rappelez-vous comment les littéraux de chaîne en C - "\0" est un tableau de caractères contenant deux octets zéro (celui que vous avez demandé, et de l'implicite à la fin). Lors de l'évaluation de l' if test, il se désintègre en un pointeur sur son premier caractère. Ce pointeur n'est pas NULL, il est donc considéré comme le vrai lorsqu'il est utilisé comme une condition.

'\0' est le nombre zéro, l'équivalent d'un peu 0. C'est un entier qui est égal à zéro, il est donc considérée comme fausse quand il est utilisé comme une condition.

39voto

Cool Guy Points 12684

Tout d'abord, vous devez garder à l'esprit que, dans C,

  • Le zéro est faux et non nulle est vraie.
  • Pour les types de pointeur, NULL est faux et non-NULL est vrai.

'\0', comme d'autres l'ont dit, est le même que le nombre entier littéral 0 , et il est donc faux (Voir le premier point ci-dessus pour savoir pourquoi).

"\0" est un littéral de chaîne qui contient deux \0 personnages (que vous avez explicitement ajoutée et de l'autre, ce qui est implicite et sera ajouté par le compilateur). La chaîne de caractères littérale sera stocké quelque part dans la mémoire en lecture seule. Lorsque vous utilisez "\0", il est converti en un pointeur sur son premier élément. Ce qui est communément appelé "tableau de décroissance". (C'est la raison pour laquelle des trucs comme char* str = "string"; travaux).

Donc, vous êtes effectivement la vérification de l'adresse du premier caractère de la chaîne littérale. Depuis l'adresse de la chaîne littérale sera toujours le non-NULL, le si sera toujours vrai (Voir le deuxième point ci-dessus pour savoir pourquoi).


: Cette "désintégration" des tableaux n'est pas toujours le cas. Voir l' Exception de la gamme pour ne pas se désintégrer en un pointeur?

15voto

FedeWar Points 527

'\0' est un nombre: 0 , de sorte qu'il est évalué comme faux ( 0 = faux, !0 = vrai).

Mais "\0" est un pointeur sur une section en lecture seule où la chaîne réelle est stockée. Le pointeur n'est pas NULL c'est vrai.

3voto

fluter Points 7990

Tout d'abord, en regardant les deux conditions, '\0' est une constante de type entier, ce qui dénote le caractère null C, qui est le même que 0. Alors qu' "\0" est un littéral de chaîne, qui contient 2 octets, celui spécifié et le terminateur null byte implicitement ajouté. Étant une chaîne littérale, le pointeur ne peut pas être NULL.

Deuxièmement, en C, pour la condition de if déclaration, tout ce non-zéro est évaluée comme true, et le zéro est évalué comme false.

Selon cette règle, il sera clair que l' '\0' est false, et "\0" évalué comme true.

1voto

Bora Points 497

Tout d'abord, veuillez noter que la valeur hexadécimale de Faux est - 0x00 et Vrai, c'est une valeur autre que 0 x 00.

"\0" est une chaîne de caractères avec un caractère et un Terminateur Null '\0' à la fin. C'est donc un personnage, qui pointe vers un tableau de 2 octets: ['\0', '\0']. Dans ce tableau, le premier est le caractère et l'autre est le terminateur null.

Après la compilation (sans optimisation), ce pointeur de caractère est affecté temporairement à une adresse dans la mémoire pointant vers le premier octet de ces deux octets. Cette adresse peut être, par exemple, 0x18A6 en hexadécimal. Ainsi, le compilateur (la plupart d'entre eux) écrit en fait ces deux valeurs pour la mémoire. Parce qu'une chaîne est en fait l'adresse du premier octet de la chaîne, notre expression est interprétée comme 0x18A6 != false . Donc, il est évident 0x18A6 != 0x00 est Vrai.

'\0' est tout simplement 0x00 en hexadécimal. 0x00 != 0x00 est Faux.

Cette réponse est écrite pour les 8 bits de données de l'architecture avec l'adressage 16 bits. J'espère que ça aide.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X