Zeiger auf ein doppeltes Array
-
darthdespotism schrieb:
Nope.
2D Felder haben immer noch in der 1. Dimension einen Zeiger auf die Zweite Version.
int feld[10][10]; int** a = feld; int* b = feld[0]; int c = feld[0][0];=>
void foo(int**, size_t x, size_t y);Bei 1000+ Beiträgen erwarte ich eigentlich, dass du gelegentlich auch mal andere Beiträge liest - dieser Unfug ist einigermaßen regelmäßig Thema in diesem Forum.
umfg schrieb:
Hallo,
ich ein zweidimensionales Array (9 auf 9), und möchte in einer Funktion deren
Werte ändern, d.h. ich brauche als Parameter einen Zeiger auf das
zweidimensionale Array. Ohne Zeiger habe ich es schon geschaft:void fill(int iFeld[][9]); int main() { int feld[9][9]; fill(feld); // ... }Aber wie geht das jetzt mit Zeiger?

Das ist bereits eine Variante mit Zeiger, auch wenn es vielleicht nicht so aussieht.
void fill(int iFeld[][9]); // ist äquivalent zu void fill(int (*iFeld)[9]);Es wird also bereits hier ein Zeiger auf ein Element von feld (welches zufällig selbst ein Array ist) übergeben. Es ist schlicht nicht möglich, Arrays als Kopie an Funktionen zu übergeben. Es gibt noch zwei weitere Möglichkeiten, bei denen dann keine Informationen über die Dimensionen verloren gehen (oder anders gesagt: du kannst den Funktionen keine Arrays mit anderen Dimensionen übergeben):
void fill(int (*iFeld)[9][9]); // Aufruf: fill(&feld);oder
void fill(int (&iFeld)[9][9]); // Aufruf: fill(feld);Wobei die zweite Variante offensichtlich syntaktisch bequemer ist.
-
hmmm, aber da gibt es doch diesen char** pointer in main...
Dabei handelt es sich um ein Array aus Char-Arrays, also wo liegt da denn dann der Unterschied?
-
void fill(int (&iFeld)[9][9]);
// Aufruf:
fill(feld);Das geht doch auch so:
void fill(int iFeld[9][9]); // Aufruf: fill(feld);@**argv
Ich denke, dass das dort ein Array von Zeigern auf char* ist. Also:
char *argv[]; char** parg = (char**) &argv; std::cout << pargv[0][0]; //Gibt dir den 1. Buchstaben des 1. Strings aus
-
camper schrieb:
... Es gibt noch zwei weitere Möglichkeiten, bei denen dann keine Informationen über die Dimensionen verloren gehen (oder anders gesagt: du kannst den Funktionen keine Arrays mit anderen Dimensionen übergeben):
void fill(int (*iFeld)[9][9]); // Aufruf: fill(&feld);Das, *int(iFeld)[9][9] ist ein Zeiger namens iFeld auf ein dreidimensionales int-Array(feld[][9][9])

-
drakon schrieb:
Das geht doch auch so:
void fill(int iFeld[9][9]); // Aufruf: fill(feld);Es geht auch. Ist aber nicht das. Bei dir ist iFeld ein Zeiger auf int[9], die Deklaration ist 100% gleichwertig zu der, die die erste Dimension auslässt, oder der, in welcher gleich ein Zeiger auftritt. In einer Funktionsdeklaration wird der Typ eines Arguments, welches formal ein Array ist (mit bekannter oder unspezifizierter Größe), in den eines Zeiger auf den Elementtyp angepasst.
-
willy schrieb:
camper schrieb:
... Es gibt noch zwei weitere Möglichkeiten, bei denen dann keine Informationen über die Dimensionen verloren gehen (oder anders gesagt: du kannst den Funktionen keine Arrays mit anderen Dimensionen übergeben):
void fill(int (*iFeld)[9][9]); // Aufruf: fill(&feld);Das, *int(iFeld)[9][9] ist ein Zeiger namens iFeld auf ein dreidimensionales int-Array(feld[][9][9])

Unsinn.
-
camper schrieb:
Unsinn.
Sachlich bleiben!
-
camper schrieb:
drakon schrieb:
Das geht doch auch so:
void fill(int iFeld[9][9]); // Aufruf: fill(feld);Es geht auch. Ist aber nicht das. Bei dir ist iFeld ein Zeiger auf int[9], die Deklaration ist 100% gleichwertig zu der, die die erste Dimension auslässt, oder der, in welcher gleich ein Zeiger auftritt. In einer Funktionsdeklaration wird der Typ eines Arguments, welches formal ein Array ist (mit bekannter oder unspezifizierter Größe), in den eines Zeiger auf den Elementtyp angepasst.
Ahh, wenn ich das jetzt richtig verstehe, wird der Zeiger einfach implizit konvertiert.
-
drakon schrieb:
camper schrieb:
drakon schrieb:
Das geht doch auch so:
void fill(int iFeld[9][9]); // Aufruf: fill(feld);Es geht auch. Ist aber nicht das. Bei dir ist iFeld ein Zeiger auf int[9], die Deklaration ist 100% gleichwertig zu der, die die erste Dimension auslässt, oder der, in welcher gleich ein Zeiger auftritt. In einer Funktionsdeklaration wird der Typ eines Arguments, welches formal ein Array ist (mit bekannter oder unspezifizierter Größe), in den eines Zeiger auf den Elementtyp angepasst.
Ahh, wenn ich das jetzt richtig verstehe, wird der Zeiger einfach implizit konvertiert.
Welcher Zeiger? Womit wir es hier zu tun haben, sind Funktionsdeklarationen, die alle äquivalent sind - also ein und dieselbe Funktion deklarieren:
void fill(int (*iFeld)[9]); void fill(int iFeld[][9]); void fill(int iFeld[9][9]); void fill(int iFeld[42][9]);Der Parametertyp dieser einen Funktion ist int(*)[9] - also ein Zeiger auf ein Array aus 9 int.
P.S.
- Arrays sind keine Zeiger.
- Funktionsparameter sind niemals Arrays oder Funktionen.
- Es ist möglich, bei der Deklaration von Funktionen für die Parameterdeklaration die Syntax von Array- bzw. Funktionsdeklarationen zu benutzen, dabei werden aber jeweils Zeigerparameter deklariert.
-
Ich glaube wir haben aneinander vorbeigeredet.
Mit Zeiger meinte ich den Typfehler, der konvertiert wurde bei der Übergabe von
fill(feld);Aber ist ja jetzt egal.

-
drakon schrieb:
Ich glaube wir haben aneinander vorbeigeredet.
Mit Zeiger meinte ich den Typfehler, der konvertiert wurde bei der Übergabe von
fill(feld);Aber ist ja jetzt egal.

Grammatik ist auch in der natürlichen Sprache wichtig - hier wird kein Zeiger konvertiert, sondern in einen Zeiger konvertiert.