2 votes

Si je change p!=nullptr en *p!='\0', alors cela fonctionne, mais pourquoi ?

Mon IDE est Xcode. Le code suivant ne peut pas s'exécuter comme prévu. Bien que nullptr soit recommandé dans la norme plus récente de C++.

#include
using namespace std;

int count_x(char * p, char x)
{
    if(p==nullptr)return 0;
    int count = 0;
    for (; p!=nullptr; ++p)
        if(*p == x)
            ++count;

    return count;
}

int main()
{
    char str[] = "Je suis une petite fille dans le petit monde !";

    cout<<"le nombre de t dans la chaîne est "<

``

Le code ci-dessus peut être compilé avec succès, mais lorsque je l'ai exécuté, je n'ai pas pu obtenir la sortie attendue. En mode débogage, j'ai découvert que la boucle for ne s'arrêtait pas. J'ai donc modifié le code comme suit :

#include
using namespace std;

int count_x(char * p, char x)
{
    if(p==nullptr)return 0;
    int count = 0;
    for (; *p!='\0'; ++p)
        if(*p == x)
            ++count;

    return count;
}

int main()
{
    char str[] = "Je suis une petite fille dans le petit monde !";

    cout<<"le nombre de t dans la chaîne est "<

`

Après avoir changé p!=nullptr en *p!='\0', le code a fonctionné correctement et la sortie attendue a été obtenue. Bien que le code semble fonctionner, je ne comprends toujours pas la raison de l'échec ou du succès.

Pouvez-vous me donner quelques indices ou suggestions? Merci.

` ``

3voto

user2079303 Points 4916

La seule différence est de changer nullptr en '\0'.

Il y a une autre différence:

 p!=nullptr
*p!='\0'
^
|
+---- ici même, une opération de déréférencement

Je ne comprends toujours pas la raison de l'échec...

J'ai réalisé que la boucle for ne s'arrêtait pas.

Votre condition est de vous arrêter lorsque la valeur de p est nullptr (c'est-à-dire zéro). Mais vous ne faites qu'incrémenter p, comment pourrait-il jamais atteindre zéro? Il n'atteindra jamais zéro avant que vous ayez survolé la chaîne.

Je ne comprends toujours pas la raison du...succès.

Dans votre tentative réussie, la condition finale n'est pas de comparer le pointeur, mais de comparer la valeur pointée au caractère de fin de chaîne nul. Cela fonctionne tant que la chaîne de caractères est null terminée.


Note supplémentaire: Même si le pointeur nul et le caractère nul ont le même nom (null), et la même valeur (0), ils ont des types différents et sont des concepts distincts.

2voto

Mohit Jain Points 6202

Le type de nullptr est std::nullptr_t. Il s'agit d'un littéral de pointeur générique qui peut se convertir en n'importe quel type.
Le type de '\0' est char. Il est utilisé dans les chaines de caractères de style C pour marquer la fin de la chaine.
Ils peuvent avoir la même valeur sur votre plateforme mais ce sont des types différents. Il est mauvais de comparer par exemple 0 km à 0 kg.


Maintenant, le vrai problème dans votre code est p == nullptr. Vous ne pouvez pas vous attendre à ce que le pointeur devienne nullptr (pointant vers rien) juste en l'incrémentant.

La seule différence est de changer nullptr en '\0'.

Non, vous avez également changé p en *p.

0voto

ashish bansal Points 229

Considérer

int test = NULL;

et

int *test = NULL;

Les deux codes ci-dessus seront capables de fonctionner. (Bien que la première ligne ci-dessus affichera un avertissement concernant la conversion de NULL en un type non-pointeur)

Cependant,

nullptr est vraiment un "pointeur nul" et toujours un pointeur. Si vous essayez de l'assigner à un entier, cela causera une erreur

int test = nullptr;

Mais cela fonctionnera si c'est

int *test = nullptr;

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