Im C Code

char a[][10]={"AIZEN","GINJO","ISHIDA","PERNIDA","GRIMMJOW"};
char (*ptr)[10]=a;
while(*ptr!='\0'){
    printf("%s\n",*ptr);
    ptr++;
}

Die Schleife wird 31 Mal ausgeführt, was der Anzahl der Zeichen im Array a entspricht. Wenn ich die Zeile 3 als ändere

while((*ptr)[10]!='\0'){

Die Schleife wird fünfmal ausgeführt und druckt die Namen im Array. Warum Ist das [10] in dieser Schleife hier notwendig? Selbst wenn ich anstelle von Zeigern den Index (while(a[i]!='\0')) verwende, muss ich dasselbe tun, um die richtige Ausgabe zu erhalten.

Ich denke, das Array sieht folgendermaßen aus: Bildbeschreibung hier eingeben Ich denke also, eine [5] wird automatisch zu \0 und die Schleife endet.

-1
Adnan 22 Feb. 2020 im 11:46

3 Antworten

Beste Antwort

Nun, dein Programm ist falsch.

ptr ist ein Zeiger auf ein Array (mit 10 Zeichen). *ptr ist also ein Array mit 10 Zeichen. Es ist also nicht sinnvoll, *ptr mit \0 zu vergleichen, da *ptr nicht null ist.

Wenn Sie den Vergleich durchführen, zeigt *ptr zuerst auf "AIZEN", nach dem Inkrement auf "GINJO" und so weiter. Für jedes Inkrement von ptr wird *ptr einfach um 10 erhöht. Nach 5 Inkrementen greifen Sie außerhalb des Arrays zu, wenn Sie printf("%s\n",*ptr); ausführen. Das ist undefiniertes Verhalten und alles kann passieren.

Ich versuche es

while(*ptr != '\0'){
    printf("%s\n",*ptr);
    printf("%p\n",(void*)ptr);
    printf("%p\n",(void*)*ptr);
    ptr++;
}

Kann zu einer solchen Ausgabe führen

AIZEN
0x7ffd162228c0
0x7ffd162228c0
GINJO
0x7ffd162228ca
0x7ffd162228ca
ISHIDA
0x7ffd162228d4
0x7ffd162228d4
PERNIDA
0x7ffd162228de
0x7ffd162228de
GRIMMJOW
0x7ffd162228e8
0x7ffd162228e8

0x7ffd162228f2
0x7ffd162228f2

0x7ffd162228fc
0x7ffd162228fc

0x7ffd16222906
0x7ffd16222906
P@
0x7ffd16222910
0x7ffd16222910
nɜ
0x7ffd1622291a
0x7ffd1622291a

Hier sehen Sie, wie die Zeiger inkrementieren und dass die print-Anweisung alle möglichen seltsamen Dinge erzeugt (aufgrund eines undefinierten Verhaltens, aber es könnte auch das Programm zum Absturz gebracht haben).

Sie können Ihr Programm wie folgt ändern:

int main(void) {
    char a[][10]={"AIZEN","GINJO","ISHIDA","PERNIDA","GRIMMJOW", ""};  // Notice
                                                                       // the empty string
                                                                       // to stop
                                                                       // the loop
    char (*ptr)[10]=a;
    while(**ptr !='\0'){       // Notice **
        printf("%s\n",*ptr);
        printf("%p\n",(void*)ptr);
        ptr++;
    }
    return 0;
}

Das heißt: 1) Hinzufügen einer leeren Zeichenfolge zum Array und 2) Dereferenzieren des Zeigers, um nach einem NUL zu suchen (d. H. Der Zeichenfolgenbeendigung)

Beachten Sie auch, dass in Ihrem zweiten Beispiel (*ptr)[10]!='\0' ebenfalls kein Sinn ergibt. Sie greifen auf das 11. Element im Array (auch als Zeichenfolge bezeichnet) zu, das Array besteht jedoch nur aus 10 Elementen.

2
4386427 22 Feb. 2020 im 09:40

Sieh dir das an,

#include<stdio.h>

int main()
{
    char a[][10]={"AIZEN","GINJO","ISHIDA","PERNIDA","GRIMMJOW"};
    char (*ptr)[10]=a;
    for(int i=0;i<5;i++,ptr++)
        printf("%s\n",ptr);
    return 0;
}

In deinem Code

   while(*ptr!='\0');

Ptr ist nicht auf null gekommen

Oder ändern

char a[][10]={"AIZEN","GINJO","ISHIDA","PERNIDA","GRIMMJOW",""}; //string literels are NULL terminated by the compiler

while(**ptr!='\0');

Hinweis:

 *ptr refer to initial address of string

 **ptr refer to address of character in the string
0
Sri lakshmi kanthan 22 Feb. 2020 im 09:26

Es gibt zwei Probleme:

  1. Der Test while (*ptr != '\0') {...} macht nicht das, was Sie denken. Der Grund, warum der Code kompiliert wird, ist, dass die Zeichenkonstante '\0' leider auch als Nullzeigerkonstante (*) betrachtet werden kann. Was Sie meinten, war wahrscheinlich, das Zeichen mit while (**ptr != '\0') {...} zu vergleichen.

  2. Das Array char a[][10]={...} enthält nur so viele Elemente, wie Sie deklarieren. Wenn Sie es beenden möchten, müssen Sie am Ende ein zusätzliches "" Element hinzufügen. Auf diese Weise wird das zusätzliche leere Element von der Schleifenbedingung erkannt.

Der Zugriff außerhalb des Arrays, während Ihr Code ausgeführt wird, ist ein undefiniertes Verhalten und alles kann passieren (einschließlich 31-maliger Schleife).

(*) Der vom Standard verwendete Wortlaut lautet "Ein ganzzahliger Konstantenausdruck mit dem Wert 0 oder ein solcher Ausdruck vom Typ void * wird als Nullzeigerkonstante bezeichnet". Zeichen in C sind Ganzzahlen und daher ist '\0' ein ganzzahliger konstanter Ausdruck mit dem Wert 0. Gute Compiler sollten dennoch vor diesem Fall warnen, da dies ein häufiger Fehler ist (z. B. gcc -Wall warnt explizit über eine möglicherweise fehlende Dereferenzierung).

3
6502 22 Feb. 2020 im 09:11