2016-05-06 8 views
0

Ich versuche, durch eine Reihe von ganzen Zahlen Schleife mit Zeigern mit dem folgenden Code:Extra-Nummer, während sie durch ein Array in C Looping ++

#include <iostream> 

int main (int argc, char ** argv) 
{ 
    int ar[] = {1,1,2,3,5,8,13,21,34,55}; 
    char s[] = "string"; 

    std::cout << "Print fibonacci until ten using pointers" << std::endl; 
    for (int * p = ar; *p; p++) 
    { 
     std::cout << *p << std::endl; 
    } 

    // for (char * cp = s; *cp; cp++) 
    //  std::cout << "char is " << *cp << std::endl; 

    return 0; 
} 

Auf diesen Code ausgeführt wird, erhalte ich alle 10 Elemente sowie eine Reihe, . Aber beim Auskommentieren der zweiten for-Schleife und erneutem Ausführen verschwinden die Zahlen.

Kann jemand erklären, warum das passiert? Bei Bedarf wird der Code in einer 64-Bit-Linux-Box kompiliert.

+0

Sie erwarten ein mit Null abgeschlossenes Array, terminierten es jedoch nicht null. 'int ar [] = {1,1,2,3,5,8,13,21,34,55, 0};' –

+1

@ πάνταῥεῖ Warum schreiben Sie eine Antwort in den Kommentaren? –

Antwort

3

Sie haben Glück, die Schleife überhaupt gestoppt; Du hättest deine ganze Nachbarschaft in die Luft jagen können!

Ihre Schleife erwartet eine "Null", um die Array-Iteration zu beenden, aber Ihr Array hat keine. Ihre Schleife wird also immer weiter über das Ende des Arrays hinausgehen, bis Gott weiß was. Die praktischen Ergebnisse hängen von zu vielen praktischen Faktoren ab, die entweder vorhersehbar oder nützlich erklärt werden können.

Ich nehme an, dass dies eine Übung ist, weil die Verwendung von "Null-Terminierung", um über eine int-Array zu iterieren ist mächtig eigenartig. In der Realität würde man nur schreiben:

for (auto x : ar) 
    std::cout << x << '\n'; 
} 
+0

Gibt es eine Bedeutung für die Nummer? Normalerweise spucken Zeigerfehler Zufallszahlen aus, was ich versucht habe. – Rudra

+0

@Rudra: Sie sind nie _random_; Sie sind im Allgemeinen "was auch immer an diesem Ort in Erinnerung ist". Die Sache ist, dass Computer so sehr kompliziert sind, dass der Versuch, zu bestimmen, warum dieser spezielle Wert zufällig an diesem bestimmten Ort im Speicher ist, viel mehr Aufwand erfordert, als nützlich ist. Stattdessen bleiben wir einfach bei den Abstraktionen, die durch die Sprachspezifikation definiert sind, und sagen: "Wir hätten jede beliebige Nummer oder Nummer oder ein Katzen-Emoji oder eine fliegende elektrische Rübe sehen können", um wirklich nach Hause zu fahren, wenn Sie vorbeikommen Am Ende deines Arrays hast du alle vernünftigen Rechte an Logik aufgegeben. :) –

+0

Hahaha Das klärte es gut auf. – Rudra

2

Sie rufen eine undefined behavior auf.

Die erste for Schleifenbeendigungsbedingung ist *p. Es versucht also, auf den Speicher zuzugreifen, der sich hinter dem befindet, was tatsächlich von ar gehört. Ihre Schleife wird dann ausgeführt, bis sie einen Speicherplatz findet, der 0 enthält (lesen Sie false), bevor Sie beenden. In Ihrem Fall lief es nur eine zusätzliche Zeit (Glück Sie!). An meinem Ende lief es vier weitere Male bevor es endete.

Sie müssen Schleife nur so oft wie die Größe des Arrays, die sizeof(ar)/sizeof(ar[0]) ist

0

Stellen Sie sicher, dass Sie Null beendet haben:

int ar[] = {1,1,2,3,5,8,13,21,34,55, 0}; 
0

Nun, tatsächlich diese in einem anderen Ergebnis auf einer anderen Maschine oder einem anderen Zustand führen. Derjenige, der dies bewirkt, dass Ihre für Anweisung

for (int * p = ar; *p; p++) 
{ 
    std::cout << *p << std::endl; 
} 

Hier legen Sie *p als bedingtes verwendeten für die for-Schleife laufen zu halten. Wie wir wissen, behandeln C++ die Nummer> 0 als true und 0 als false. Während in der for-Anweisung überprüft Ihr Programm die nächste Speicheradresse, wenn der Wert in dieser Adresse Null ist oder nicht (True oder False). Und wie Sie wissen, ist der Wert der nächsten Adresse in diesem speziellen Fall auf Ihrem bestimmten PC 4196368. So geht die for-Schleife weiter, bis der Wert der nächsten Adresse Null ist. Sie können dies beim Drucken der Adresse sehen.

for (int * p = ar; *p; p++) 
{ 
    std::cout << *p << " " << p << std::endl; 
} 

Sie wissen, wird hier, dass Ihr Code die nächste Adresse überprüfen seinen Wert ein, um zu sehen, ob es in der Tat nicht Null ist, wird die Schleife fortgesetzt.