list[]={1,2,3,4,5,6,7};
Genau, das hat Länge 7
Weil man bei 0 zu zählen anfangt, von liste[0] bis liste[6] sind 7 Stück.
Der Wert in liste[0] ist 1, liste[1] ist 2...liste[6] ist dann eben 7.
(Zu "liste": Eigentlich ist es ja ein Array. Eine Liste ist das Zeug mit next)
list[5]={1,2,3}
Hat 5 Elemente, davon 0, 1 und 2 belegt, genau.
Element 3 und 4 sind aber nicht unbedingt 0, sondern irgendein Wert.
Wenn man 0 drinhaben will muss man das extra reinschreiben.
Ok, lionq und Cromon haben recht 
Es ist 0
Jede Variable muss ja irgendwo im Speicher sein.
Die ganzen möglichen Plätze für Variablen im Speicher sind durchnummeriert.
Wenn man jetzt also ein
hat könnte das i an Stelle 1288 sein, dort ist dann 10 gespeichert.
Wo die Variablen hinkommen bzw. wo noch unbenutzter Platz frei ist
wird vom Compiler/Betriebssystem verwaltet.
Da braucht man sich selbst keine Sorgen darum machen.
(Die Platznummern sind immer ganze positive Zahlen.
Immer int´s. Auch wenn dort floats oder sonst was gespeichert sind)
Man kann die Platznummer ("Adresse") im Programm herausfinden,
indem man ein & vor den Variablennamen schreibt.
C++:
printf("%d", i); //Gibt den Wert 10 aus
printf("%d", &i); //Gibt die Adresse 1288 aus
Ein Pointer ist jetzt eigentlich ein normales int, mit der Besonderheit,
dass es dazu gedacht ist, Speicheradressen als Wert zu haben.
Da Adressen aber nur normale int-mäßige Zahlen sind,
kann man den Pointer zunächst ganz normal als int verwenden:
C++:
int *p; //Beim Anlegen einen * als Kennzeichnung für "Pointer"
p = 9876; //Nur mal als Beispiel
printf("%d", p); //Gibt 9876 aus. Klar
Was den Pointer jetzt besonders macht:
Mit *p kann man auf den Wert zugreifen, der die Adresse im Pointer hat.
C++:
printf("%d", *p); //Gibt den Wert auf Adresse 9876 aus
//Weil 9876 ja der Wert von p ist
Man kann also irgendwelche Speicheradressen einfach als Zahl in p reingeben
und dann per *p auf den Wert dieser Adresse zugreifen.
(In der Praxis ist es problematisch,
irgendwelche Adressen zu nehmen,
wenn man nicht weiß, was dort eigentlich ist.)
Um das int i von oben herzunehmen (Wert 10, Adresse 1288):
C++:
p = 1288; //könnte man machen
p= &i; //oder man holt sich die Adresse von i so
printf("%d", *p); //Gibt 10 aus. An Adresse 1288 ist ja der Zehner vom i
*p = 11; //Damit ist i jetzt 11
printf("%d", i); //11
Welche Pointerart man hat
C++:
int *pi;
float *pf;
char *pc;
...
hat keine Auswirkung darauf, dass die Adressenzahl drin immer ein int ist.
Der Unterschied ist, welche Varialenart man dort an dieser Adresse dann hat.
Wie Pointer jetzt mit Arrays zusammenhängen:
Die vielen Werte des Arrays sind im Speicher genau "hintereinander",
dh. wenn der erste Wert ([0]) auf Adresse 1200 ist sind die nächsten eben 1201, 1202...
Angenommen, das geht von 1200 bis inklusive 1209
Das, was du da als arr im Programm hast ist dann "nur" ein Pointer auf das Startelement.
Also ein
(zusätzlich wird natürlich irgendwo festgemacht, dass die Adressen
1200 bis 1209 besetzt sind, nciht für neue Variablen frei).
Den ersten der 10 Werte (eigentlich arr[0]) bekommt man in der Pointervariante mit *arr
arr[1] wäre *(arr + 1). Also 1200+1=1201, davon der Inhalt
arr[7] ist *(arr + 7) ...
(arr[0] ist eigentlich nicht nur *arr, sondern *(arr+0)
Macht nur keinen Unterschied, ob 0 dazugerechnet wird.)
Und das arr[bla] im Code ist in Wirklichkeit nur eine Kurzschreibweise für *(arr + bla)
Wird ganz real vom Computer so gemacht.
Das ist übrigens auch der Grund, warum man bei den Arrayelementnummern bei 0 beginnt.
Das Startelement ist auf (Startadresse +
0)