Unterschied bei Zugriff auf C-Array
-
Ich habe gerade eine Funktion vor mir die absichtlich auf ein 2D Array anstatt mit
A[x][y] mit A[x*N+y] zugreift.Hat das in irgendeiner Hinsicht Vorteile, z.B. bzgl der Geschwindigkeit ?
Matthias
-
Der Vorteil liegt vor allem in der Dynamik - Wenn du das 2D-Array als eindimensionales Array modellierst und die Indizes selber umrechnest, kannst du die Breite (N) zur Laufzeit bestimmen. Bei "echten" 2D-Arrays muß sie bereits zur Compilezeit feststehen (oder du benutzt Doppelzeiger, aber damit benötigst du eine zusätzliche Indirektionsebene).
-
CStoll schrieb:
Der Vorteil liegt vor allem in der Dynamik - Wenn du das 2D-Array als eindimensionales Array modellierst und die Indizes selber umrechnest, kannst du die Breite (N) zur Laufzeit bestimmen.
Das war nicht ganz meine Frage. Die Arrays sind entweder als 1D oder 2D definiert worden und werden an die Funktion als Pointer übergeben. Wie sie definiert sind spielt daher keine Rolle.
Ich habe mich nur gefragt ob es z.B. von der Geschwindigkeit her Sinn macht auf ein 2D Array wie auf ein 1D Array zuzugreifen über A[x*N+y].
Ich habe nämlich eine Funktion die das tut und dadurch schlecht zu lesen ist.Matthias
-
pospiech schrieb:
Ich habe mich nur gefragt ob es z.B. von der Geschwindigkeit her Sinn macht auf ein 2D Array wie auf ein 1D Array zuzugreifen über A[x*N+y].
ich glaube nicht. auch wenn du A[x][y] schreibst, wird's intern als A[x*N+y] behandelt. im normalfall ist der speicher ja sowieso eindimensional...

-
Doch, es kommt darauf an, wie das Array definiert ist.
Wenn es ein echt zweidimensionales Array ist, ist der Aufruf A[x*N+y] illegal (bzw. ergibt einen Zeiger, der vermutlich außerhalb der Array-Grenzen liegt) - der kann höchstens noch mit geeigneten Casts erträglich gemacht werden (aber sowas liegt dann an der Grenze des portierbaren).
Wenn du ein 1D-Feld umdeutest als 2D-Array, funktioniert der Aufruf A[x][y] nicht (es sei denn, du hast irgendwelche Proxie-Objekte dazwischengeschoben, die den Aufruf möglich machen).
-
CStoll schrieb:
Doch, es kommt darauf an, wie das Array definiert ist.
Wenn es ein echt zweidimensionales Array ist, ist der Aufruf A[x*N+y] illegal (bzw. ergibt einen Zeiger, der vermutlich außerhalb der Array-Grenzen liegt) - der kann höchstens noch mit geeigneten Casts erträglich gemacht werden (aber sowas liegt dann an der Grenze des portierbaren).
Also eine der Funktionen von denen ich rede sieht wie folgt aus (nicht von mir):
void Shift2D(double *A,long N) // A muss als double A[N][N] deklariert worden sein!!! // A[x][y] = A[x*N+y] A[0][0] ... A[N][0] // ... ... // A[0][N] ... A[N][N] { double swap; long ix,iy; for (ix=0;ix<N;ix++) Cycle(A+ix*N,N); // Spalten shiften for (iy=0;iy<N;iy++) // Zeilen einzeln shiften for (ix=0;ix<N/2;ix++) { swap=A[(ix+N/2)*N+iy]; A[(ix+N/2)*N+iy]=A[ix*N+iy]; A[ix*N+iy]=swap; } }und dort wird auf ein 2D Array nur mit A[ix*N+iy] zugegriffen.
Matthias
-
CStoll schrieb:
Wenn es ein echt zweidimensionales Array ist, ist der Aufruf A[x*N+y] illegal...
seltsam, das hier scheint zu klappen:
int main() { int a[2][2]; int *p = (int*)a; a[0][0] = 1; a[0][1] = 2; a[1][0] = 3; a[1][1] = 4; printf ("%d %d %d %d\n", p[2*0+0], p[2*1+0], p[2*0+1], p[2*1+1]); printf ("%d %d %d %d\n", *p, *p+1, *p+2, *p+3); }oder ist das 'undefined behaviour'?
-
@pospiech: Die Funktion nutzt ein lineares Array, das es zweidimensional betrachtet. Das heißt, da ist diese Koordinatenumstellung notwendig.
@pale dog: Ja, das ist undefiniertes Verhalten (und funktioniert auch nur, weil printf() keine Typkontrolle für seine Parameter durchführt).
-
CStoll schrieb:
@pale dog: Ja, das ist undefiniertes Verhalten (und funktioniert auch nur, weil printf() keine Typkontrolle für seine Parameter durchführt).
wieso printf

oben wird die adresse des 2d-arrays einem einfachen int* übergeben damit man's linear auslesen kann.
ich wollte eigentlich wissen ob man auf 2d-arrays immer eindimensional zugreifen kann, oder ob jeder compiler die arrayelemente anordnen kann wie er will (so dass es nicht mehr funktioniert).

-
CStoll schrieb:
@pospiech: Die Funktion nutzt ein lineares Array, das es zweidimensional betrachtet. Das heißt, da ist diese Koordinatenumstellung notwendig.
Das heißt ich übergebe ein 2D Array an eine Funktion die ein 1D Array erwartet, was offensichtlich funktioniert, und dann arbeite ich mit dem 1D Array als wäre es 2-dimensional ?
-
Also wenn der Compiler es tatsächlich schluckt, daß du der Funktion ein 'double A[N][N]' übergibst, würde ich mich schon sehr wundern. Meiner wirft mir da einen C2664 entgegen.