C: Zeiger auf Zeiger und ein Mehrdimensionales Array
Hallo zusammen,
ich habe mal folgendes mini Programm in C geschrieben um mir die Übergabe von Mehdimensionalen Array an doppel Zeiger klar zu machen.
Code:
#include <stdio.h>
#include <stdlib.h>
#define S 10
#define C 10
//////////// fill ////////////////
void output(int **feld) {
int i, j;
for(i = 0; i < 9; i++) {
for(j = 0; j < 9; j++) {
printf(" %3d ", feld[i][j]);
}
printf("\n");
}
printf("\n");
}
////////////////////main/////////////////
int main(void){
int array[S][C];
int i, j;
for(j=0; j <= 9; j++){
for(i=0; i<=9 ;i++)
array[i][j] = i+j;
}
output(array[][S]);
return EXIT_SUCCESS;
}
Leider bekomme ich es nicht hin das Array richtig an den Zeiger zu Über geben. Könnte mir jemand dabei helfen zu verstehen wie man das richtig macht ??
man sollte mit den Board-Tags umgehen können, dann klappts auch mit dem Code-Block
Zitat:
Zitat von
peschmae
Code:
[...]
output(&array[0][0]);
[...]
Nein, das klappt nicht. So bekommt man die Adresse der Stelle im Speicher wo der Wert des ersten Elements liegt. Die ist aber nicht gleich dem Anfang der Folge wo die Zeiger auf die Unterbereiche liegen (logisch, weil auch die Zeiger Platz im Speicher brauchen).
Einfaches Beispiel, unter der Annahme, dass der Vektor wie folgt erstellt wurde und dass das Zielsystem nen 8bit Adressbus hat und sizeof(int) == 1 (Anm. auf i386-Architekturen ist das beides allerdings in Wirklichkeit 32bit breit, AFAIK, aber dann muss ich so viel tippen ;)):
Code:
int foo[2][2];
foo[0][0] = 1;
foo[0][1] = 2;
foo[1][0] = 3;
foo[1][1] = 4;
Im Speicher würde das in etwa so aussehen (die Hexzahlen vor den Doppelpunkten sind die Adressen, die Zahlen dahinter die Werte, nach dem Nummernzeichen steht wie man den Wert und die Adresse ansprechen würde):
Code:
0x01: 0xa1 # wert = foo[0], adresse = &foo[0]
0x02: 0xd1 # wert = foo[1], adresse = &foo[1]
...
0xa1: 0x01 # wert = foo[0][0], adresse = &foo[0][0]
0xa2: 0x02 # wert = foo[0][1], adresse = &foo[0][1]
...
0xd1: 0x03 # wert = foo[1][0], adresse = &foo[1][0]
0xd2: 0x04 # wert = foo[1][1], adresse = &foo[1][1]
Die Lücken (...) hab ich bewusst da eingebaut, damits besser verständlich wird, was da passiert, diese können in der Realität da sein, müssen es aber nicht.
Wie man also deutlich sehen kann würdest du mit deinem Vorschlag auf mein Beispiel bezogen 0xa1 an die Funktion übergeben, währen diese aber auf Grund der Deklarationen davon ausgeht, das sie im Speicher unter der Adresse 0xa1 einen Zeiger findet der zwar auf einen Bereich zeigt wo zwei Integerwerte liegen (und an der Folgeadresse 0xa2 wieder usf.), aber eben keine zwei Integer direkt. In 0x01, was der Wert an dieser Adresse ist, liegt aber in der angenommenen Konstellation eigentlich kein Integerwert sondern eben ein Zeiger (0xa1, dieser würde aber als Integer Interpretiert werden und als Ausgabe käme eine 161 statt der erwarteten 1. dann eine 209 statt der 2, dann wieder eine 209 und schliesslich wird versucht auf 0x03 zuzugreifen, wo wir jetzt nicht wissen was drin steht, weil das gar nicht zu unserem Programm gehört und wir haben nen schönen Seg-Fault...
Also müsste das ganze so aussehen, dann würde korrekterweise 0x01 übergeben:
Wie auch immer @Sector1379, weil dich ja nun noch von den anderen Threads in Erinnerung habe wo du die gleiche oder ähnliche Fehler gemacht hast, wenn du so nen Speicherbereich oder Vektoren übergeben willst, dann musst du nicht array[][] oder array[max] oder sowas schreiben, sondern einfach sicherstellen, dass in array die Addresse des Anfangs dieses Bereichs, bzw. Vektors liegt (und das tus üblicherweise, wenn es das ein Ergebnis eines erfolgreichen malloc()s o. Ä bzw. ein fix deklarierter Vektor ist und man es nicht verändert) und einfach diesen Pointer (array) übergeben. Wegen der Deklarationen ist klar was damit gemacht werden muss, also ob das nun ein Integer, ein Character oder ein anderer Typ ist oder ob es ein-, zwei- oder n-dimensional ist.
Also function(array) übergibt den geamten Vektor bzw. Speicherbereich, also eigentlich den Zeiger zum Anfang, aber wenn der Funktionsprototyp mit function(type** argument) dasteht ist bekannt, dass das zweidimensional ist.
function(array[n][m]) übergibt genau ein Element im Vektor bzw. Bereich. Wenn der Typ von array also beispielsweise mit int **array deklariert wurde halt einen Integer, keinen Zeiger!
Um einen Teilbereich bzw. -vektor zu übergeben kannst du function(array[n]) benutzen. Bei zwei Dimensionen würde dann eine Zeile übergeben werden, also beispielsweise wenn die Deklararion von array type **array lautet wäre dass dann ein Vektor bzw. Bereich des Typs type *.
Man möge mich korregieren, wenn ich da ne Lücke hab aber AFAIK ist alles andere, also function(array[]) und function(array[][m]) usf. Bullshit und bringt ausser Syntaxfehlern gar nichts hervor, sowas klappt vielleicht in Java (meine da mal sowas gesehen zu haben, kann mich aber auch täuschen), aber nicht in C...