PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C++, Pointer, Arrays und eine Anwendung, die ich nicht verstehe.


DoWe
2010-11-15, 16:37:13
Grüße liebe Community.

Im zuge meines Physikstudiums müssen wir via C++ eine ganz simple Codeanalyse machen. Thema heute: Array und Pointer für BoonS.

Frage: What does the following code output, and why?


#include<iostream>
int main ()
{

int a[] = {5, 6, 2, 3, 1, 4, 0};
int *p = a;

do {

std::cout << *p << " ";
std::cout << a +*p << "\n";
p = a +*p;

} while (p != a);

return 0;
}


Output sieht bei mir folgendermaßen aus:


5 4 1 6 0

Die Ausgabe ist mir schleierhaft. Ich weiß, dass der Code folgendes tut:

Initialisiert das Array a mit den Einträgen ...
Initialisiert Pointer auf Adresse des Eintrages a[0]
Do Schleife Dereferenziert P
????


Genau dan der Operation p = a + *p haperts am Verständnis.
Ich würde jetzt tippen, dass der Pointer um die Adresse des Arrayanfangs inkrementiert wird, aber irgendwie ergibt das auch nach paar eingefügten "std::cout" an verschiedenen stellen zur Ermittlung der Adressen keinen Sinn.

Ich wäre für eine kleine Gedangenstütze dankbar!

Grüße
DoWe

del_4901
2010-11-15, 17:19:01
Derjehnige dere das geschrieben hat haelt sich wohl fuer einen besonders schlauen B00N?

Kannst du dich mal bitte beschweren, das es kreuzgefaehrlich ist solchen code zu verwenden geschweige ihn denn fuer die Lehre zu verwenden!!! Ich programmier bestimmt schon sehr lange C++ und hab schon vieles verbrochen, aber das schiesst echt den Vogel ab!

Die Schleife terminiert uebrigens nur weil der letzte eintrag im Array 0 ist, wenn den Eintrag jemand aendert, dann liesst das Programm froehlich im Speicher umher, bis es auf die naechste 0 trifft.

Achja und man terminiert eine Zeile nicht mit "\n" sondern mit std::endl sonst gehn keine Zeilenumbrueche unter Linux.

patermatrix
2010-11-15, 17:47:38
Genau dan der Operation p = a + *p haperts am Verständnis.

Es addiert den Wert von *p auf die Adresse 'a'.

Z.B. ist im ersten Durchlauf

*p: 5 (1. Eintrag des Arrays)
a: Adresse des ersten Eintrages
Somit ergibt a + *p

p = a + *p = (Adresse des Arrays) + 5 (-> verschiebe p um 5 Einträge)
*p = *(a + 5) = 4 (6. Eintrag des Arrays, wird im 2. Durchgang ausgegeben)

DoWe
2010-11-15, 18:12:57
3 mal darfst du raten, aus welcher Uni diese Aufgaben verbockt werden...

Die "Programmierung für Mathematiker und Naturwissenschaftler" Vorlesung an der ETH-Z ist die reinste Unverschämtheit. Ich habe in Frankfurt bereits 2 Semester PRG bei den Informatikern gehört, und ich dacht dass diese nicht zu unterbieten wäre.

Übrigens weiß ich nicht wirklich, wass die Leute von mir wollen. Wenn der Code eine Demonstration von Arrays und Pointern darstellen soll, hätte ich einfach den Pointer auf a initialisiert und ihn durch die Indizes "inkrementieren". Dann noch 2 Kommentare, dass Arrays in C++ in der Regel einen festen Speicherbereich bei deklaration zugewiesen bekommen und dass die Pointer durch die Arrays "iterieren".

Coda
2010-11-15, 18:45:18
Achja und man terminiert eine Zeile nicht mit "\n" sondern mit std::endl sonst gehn keine Zeilenumbrueche unter Linux.
Wat? Blödsinn! Der einzige Unterschied ist, dass std::endl flusht.

Ich verstehe auch nicht was an dem Code so übel sein soll. Es ist halt eine gute Hirnübung um Pointer, Dereferenzierung und Offset-Rechnung zu kapieren. Schön ist natürlich was anderes.

AwesomeSauce
2010-11-15, 18:48:31
@AlphaTier
Was ist denn an diesem Beispiel so gefährlich? Natürlich abgesehen davon, dass es nur mit einer Null als letztes Element im Array terminiert. Ist halt Pointer-Arithmetik...

EDIT
Brainfart. Das letzte Element muss natürlich keine Null sein. Mindestens ein Element im Array muss aber eine Null sein, damit das Programm terminiert, sonst rattert er weiter bis zur nächsten Null. Hast du ja oben bereits geschrieben:redface:

Gast
2010-11-16, 08:46:15
Der Code ist wirklich etwas übel. Im Vector a dürfen nur Werte stehen, die die Vector Grenzen nicht überschreiten, mindestens ein Element muss 0 und man muss natürlich zur 0 ersteinmal kommen. Aber egal, solle ja eine Verständnisaufgabe sein.

Brillus
2010-11-17, 01:00:31
@AlphaTier
Was ist denn an diesem Beispiel so gefährlich? Natürlich abgesehen davon, dass es nur mit einer Null als letztes Element im Array terminiert. Ist halt Pointer-Arithmetik...

EDIT
Brainfart. Das letzte Element muss natürlich keine Null sein. Mindestens ein Element im Array muss aber eine Null sein, damit das Programm terminiert, sonst rattert er weiter bis zur nächsten Null. Hast du ja oben bereits geschrieben:redface:
es darf auch kein negative zahl im array sein bzw keine zahl >= länge des Arrays(oder zumindest darf man keine solche zahl treffen)

Langenscheiss
2010-11-17, 01:47:54
@Dowe
Gut, das wir hier an der RWTH mit Java angefangen haben. Die Umgewöhnung auf C++ fällt/fiel mir nicht mehr schwer, aber Pointer(-Arithmetik) musste man nicht sofort lernen, sondern man konnte sich direkt auf die OO-Dinge konzentrieren. Als Physik-Erstie ohne Programmier-Erfahrung interessieren mich intelligentes Speicher-Management (bei Java kann man quasi gar nicht entscheiden, was wo (Stack,Heap) angelegt wird und wann Speicher aufm Heap freigegeben werden soll) und die Zeiger-Typen nicht so wirklich. Call/Pass-by-reference bzw. by-copy ist einheitlich festgelegt und so weiter und so fort..., halt vieles irgendwo einfacher, man hat für den Anfang/fürs Lernen aber genug Flexibilität.
Andererseits braucht man Grundkenntnisse in C++ für Root, was ja im physikalischen Praktikum sehr wichtig ist, wenn man nicht auf Krücken wie Maple oder nicht billige Produkte wie Mathematica zurückgreifen will.

SimonX
2010-11-17, 12:43:00
@DoWe

Das ist eine optimierte Statemachine:


> p = a +*p;
>
> } while (p != a);

Verschiebe den State und brich ab, wenn State==0

Wenn jetzt zum State auch noch eine Zusatzinfo existiert, dann macht das Beispiel sogar Sinn.