Anmelden

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C] Matrix als Pointer an eine Funktion übergeben



stefan-tiger
28-11-2004, 19:07
Hallo,

wie kann ich in C eine Matrix (2D array) als Pointer an eine Funktion übergeben?

Der Matrixname ist ja ein Pointer auf ein Array mit Pointern die wiederum auf ein Array zeigen in denen die Werte liegen. Richtig?

So will ichs machen:


void irgendwas(*matrix)
{
...
wert=*(*(matrix+a)+b)
...
}

int main(...)
{
int matrix[3][3];
...
*(*(matrix+a)+b)
...
irgendwas(matrix);
...
}


Leider bekomme ich immer die Meldung: "passing arg 1 of `irgendwas' from incompatible pointer type"

Ich will damit die "matrix" in der Unterfunktion genauso ansprechen wie in der main Funktion, z.b. *(*(matrix+a)+b)

wraith
28-11-2004, 19:27
Einfach


void irgendwas(int matrix[3][3]) {
....

Die erste Dimension kannst du auch weglassen, weil die für den Compiler bei der Adressberechnung unwichtig ist.


void irgendwas(int matrix[][3]) {
....



Der Matrixname ist ja ein Pointer auf ein Array mit Pointern die wiederum auf ein Array zeigen in denen die Werte liegen. Richtig?

Der Matrixname ist ein Zeiger auf ein Array von 3 int, daher ist diese Schreibweise auch möglich (äquivalent zur zweiten von oben)


void irgendwas(int (*matrix)[3]) {
...

panzi
28-11-2004, 19:28
void irgendwas( int matrix[][] )
/* oder: void irgendwas( int ** matrix ) */
{
...
wert = matrix[ a ][ b ];
...
}

int main()
{
int matrix[ 3 ][ 3 ];
...
matrix[ a ][ b ] = ...;
...
irgendwas( matrix );
...
}

stefan-tiger
28-11-2004, 19:37
Bei

void irgendwas( int **matrix )

kommt leider für die Zeile des: warning: passing arg 1 of `irgendwas' from incompatible pointer type.


D.h. "irgendwas( matrix );" passt nicht mit "void irgendwas( int **matrix )" zusammen.

Gruß und Danke für deine Hilfe

PS: Ich will soviel es geht die [][] Schreibweise vermeiden.

wraith
28-11-2004, 19:42
void irgendwas(int * matrix)
{

}
...
irgendwas(&matrix[0][0]);

Jetzt mußt du aber die Indexberechnung selber erledigen.


PS: Ich will soviel es geht die [][] Schreibweise vermeiden.

Warum?

stefan-tiger
28-11-2004, 19:54
Warum?

Die Funktion soll dynamisch sein. d.h. ich will nicht immer eine 3x3 Matrix übergeben (dies erfüllt die Lösung:void irgendwas( int *matrix ) mit dem Aufruf: irgendwas(&matrix[0][0]); ).

Das zweite was ich will, ist , daß ich die Schreibweise:

*(*(matrix+a)+b)

auch in der Unterfunktion nutzen will (dies erfüllt die Lösung:void irgendwas( int matrix[][] ) ).

Kann ich beides gleichzeitig haben?

wraith
28-11-2004, 20:21
(dies erfüllt die Lösung:void irgendwas( int matrix[][] ) ).

Das ist keine Lösung, weil es kein korrektes C ist, man kann höchstens die linkeste Grenze weglassen.


Kann ich beides gleichzeitig haben?
Nein, nicht mit exakt dieser Schreibweise.
Welchen Vorteil hat sie für dich?
Da du jetzt aber einen Zeiger auf int hast, kannst du da dein a und b draufaddieren.Zweimaliges Dereferenzieren geht natürlich nicht mehr.

stefan-tiger
28-11-2004, 20:38
Das ist keine Lösung, weil es kein korrektes C ist, man kann höchstens die linkeste Grenze weglassen.

Nein, nicht mit exakt dieser Schreibweise.
Welchen Vorteil hat sie für dich?
Da du jetzt aber einen Zeiger auf int hast, kannst du da dein a und b draufaddieren.Zweimaliges Dereferenzieren geht natürlich nicht mehr.

Ja, die Klammern leer lassen geht nicht.

Und ja, ich habs nun so gemacht: Ich sprech die Matrix in der Unterfunktion so an wie die Daten im Speicher liegen, also:

*(matrix+a+k*b)

wobei k dei maximale Anzahl an Spalten ist.

Bei ner 3x3 Matrix also:

1. Zeile, 2. Spalte: *(matrix+1+3*0)
2. Zeile, 1. Spalte: *(matrix+0+3*1)


So gehts.

Gruß

panzi
30-11-2004, 21:59
hmm, stimmt. das mit int ** matrix kann so net funktionieren.
Also dann das dereferenzieren matrix[a][b]. Woher soll der compiler wissen, wie groß die Matrix ist? Liegt ja so im Speicher:
3x3 Matrix:
{ a, b, c }{ d, e, f }{ g, h, i }
Also bei [ 1 ][ 2 ] rechnet der Kompiler *( matrix + 3 * 1 + 2 ) und bekommt somit f.
Aber wenn der Kompiler die Abmessungen nicht kennt, dann kann er auch nicht das * 3 einfügen.
Man kann das aber anders lösen:


int matrix_data[ 3 ][ 3 ] = { ... };
int * matrix[ 3 ]; // array von pointern

matrix[ 0 ] = & matrix_data[ 0 ];
matrix[ 1 ] = & matrix_data[ 1 ];
matrix[ 2 ] = & matrix_data[ 2 ];

irgendwas( matrix );

// hmm, vieleicht muss man casten, sollt aber so richtig funktionieren
irgendwas( (int**)matrix );

// Damit "irgendwas" jetzt aber weiß, um was für ne Matrix
// es sich handelt, mus man ihm das sagen, damit "irgendwas"
// auch die Grenzen der Matrix einhalten kann.
void irgendwas( int ** matrix, size_t sitze ) { ... }

irgendwas( matrix, 3 );

Jetzt kann man in "irgendwas" auch mit matrix[ a ][ b ] dereferenzieren, da matrix[ a ] ja schon den pointer auf die richtige stelle ("unterarray") in matrix_data holt.

wraith
30-11-2004, 22:16
matrix[ 0 ] = & matrix_data[ 0 ];
matrix[ 1 ] = & matrix_data[ 1 ];
matrix[ 2 ] = & matrix_data[ 2 ];

Ohne &.

Der spätere Cast auf int** hingegen ist unnötig, weil Array beim Funktionsaufruf in einen Zeiger auf das erste Element degeneriert, was hier int** ergibt.

panzi
01-12-2004, 11:54
Ohne &.

Der spätere Cast auf int** hingegen ist unnötig, weil Array beim Funktionsaufruf in einen Zeiger auf das erste Element degeneriert, was hier int** ergibt.
hups

(zehn zeichen)