Comparaison de cordes en C avec le signe égal

J’ai ce code:

char *name = "George" if(name == "George") printf("It's George") 

Je pensais que les chaînes c ne pouvaient pas être comparées avec le signe == et je dois utiliser strcmp . Pour une raison inconnue, lorsque je comstack avec gcc (version 4.7.3), ce code fonctionne. Je pensais que c’était faux parce que c’est comme comparer des pointeurs alors j’ai cherché dans Google et beaucoup de gens disent que c’est faux et que comparer avec == ne peut pas être fait. Alors, pourquoi cette méthode de comparaison fonctionne?

Je pensais que les chaînes c ne pouvaient pas être comparées avec le signe == et je dois utiliser strcmp

Droite.

Je pensais que c’était faux parce que c’est comme comparer des pointeurs alors j’ai cherché dans google et beaucoup de gens disent que c’est faux et comparer avec == ne peut pas être fait

C’est vrai aussi.

Alors, pourquoi cette méthode de comparaison fonctionne?

Cela ne fonctionne pas. Cela semble seulement fonctionner.

Cela s’explique sans doute par une optimisation du compilateur: les deux littéraux de chaîne étant identiques, le compilateur en génère réellement une seule et utilise le même pointeur / tableau à chaque fois que le littéral de chaîne est référencé.

Juste pour fournir une référence à la réponse de @ H2CO3:

C11 6.4.5 Littéraux de chaîne

Il n’est pas précisé si ces tableaux sont distincts à condition que leurs éléments aient les valeurs appropriées. Si le programme tente de modifier un tel tableau, le comportement n’est pas défini.

Cela signifie que dans votre exemple, name (un littéral de chaîne “George”) et "George" peuvent et peuvent ne pas partager le même emplacement, cela dépend de l’implémentation. Donc, ne comptez pas sur cela, cela peut entraîner des résultats différents sur d’autres machines.

La comparaison que vous avez effectuée compare l’ emplacement des deux chaînes plutôt que leur contenu. Il se trouve que votre compilateur a décidé de ne créer qu’un seul littéral contenant les caractères "George" . Cela signifie que l’emplacement de la chaîne stockée dans name et l’emplacement du deuxième "George" sont les mêmes. La comparaison renvoie donc une valeur non nulle.

Toutefois, le compilateur n’est pas tenu de le faire – il pourrait tout aussi bien créer deux littéraux de chaîne différents, avec des emplacements différents mais le même contenu, et la comparaison renverrait alors zéro.

Cela échouera, car vous comparez deux pointeurs différents de deux chaînes distinctes. Si ce code fonctionne toujours, cela résulte d’une lourde optimisation de GCC, qui ne conserve qu’une copie pour l’optimisation de la taille.

Utilisez strcmp() . Lien .

Si vous comparez deux chaînes, vous comparez les adresses de base de ces chaînes et non les caractères réels de ces chaînes. pour comparer des chaînes, utilisez les fonctions de bibliothèque strcmp() et strcasecmp() ou écrivez un programme comme celui-ci. ci-dessous n’est pas un code complet, il faut juste une logique pour la comparaison de chaînes.

 void mystrcmp(const char *source,char *dest) { for(i=0;source[i] != '\0';i++) dest[i] = source[i]; dest[i] = 0; }