Zugriff auf 2d-Array nur mit einer Dimension?
-
Hallo Forum!
In einem Quelltext, den ich versucht habe zu analysieren, ist mir folgende Stelle aufgefallen:INTEGER(A)[2] = ...
Nur irgendwie bekomme ich bei folgendem Programm nicht den Wert 1, sondern irgendetwas anderes ausgegeben:int main() { short table[2][2]; for(i = 0; i < 2; i++) { for(j = 0; j < 2; j++) { table[i][j] = 1; } } printf("Table element[0] is %d", table[0]); return 0; }
//Ausgabe... Table element[0] is 1245028
Ich kann mir aber auch nicht herleiten, wie diese Zahl zu stande kommt, auch wenn ich mir vorstelle wie das Feld im Speicher angelegt ist...
Kann mit da jemand weiterführende Infos über solche besonderen Zugriffe auf 2dimensionale Arrays geben?
-
table[0][0] verwenden
-
Hallo Bebbo,
Dein Fehler liegt hier:
printf("Table element[0] is %d", table[0]);
du definierst table als ein zwei dimensionales Array von Typ short:
short table[2][2];
welches 2 Zeilen mit jeweils 2 Einträgen besitzt.
Du kannst dieses Array auch als short **table auffassen.
In der print-Anweisung schreibst du table[0] und hättest gerne
das erste Element. Aber was ist nun table[0]?!table[0] ist ein Pointer auf die erste Zeile, welche zwei Einträge
vom Typ short enthaelt. Folglich bekommst du die auf int gecastete
Adresse des Pointers angezeigt.Richtig wäre:
printf("Table element[0] is %d", table[0][0]);
Gruss mcr
-
mcr schrieb:
table[0] ist ein Pointer auf die erste Zeile, welche zwei Einträge
vom Typ short enthaelt. Folglich bekommst du die auf int gecastete
Adresse des Pointers angezeigt.Vielen Dank für die gute Erklärung, genau das wollte ich wissen!!
Es handelt sich also bei table[0] um keinen Wert, der sich aus den Einträgen aus der 1. Zeile ergibt, sondern um einen Pointer...Ich hatte in einem Buch den nachfolgenden Quellcode gefunden, in dem eine Funktion average ist, die dieses table-Feld tatsächlich als Vektor behandelt. Daher meine Verwirrung bezüglich des Zugriffs.
#include <stdio.h> #include <stdlib.h> int main() { int average(int[], int); int values[10]; short table[3][3]; int i, j; for(i = 0; i < 10; ++i) { values[i] = rand(); } for(i = 0; i < 3; i++) { for(j = 0; j < 3; j++) { table[i][j] = rand(); } } printf("Average value in first array is %d\n", average(values, 10)); printf("Average value in TABLE is %d", average(table, 9)); return 0; } int average(int a[], int size) { int i; long int sum = 0; for(i = 0; i < size; ++i) { sum += a[i]; } return (sum/size); }
-
Dein Beispiel aus dem Buch ist nicht korrekt. Es liefert Warnings
beim Kompilieren mit gcc und auch falsche Ergebnisse.Hier erst mal das ein wenig abgeänderte Programm. Habe nur rand durch
Zahlen ersetzt, damit man nachrechnen kann, was passiert und ein wenig
zusammengefaßt. Sonst ist nichts verändert:#include <stdio.h> #include <stdlib.h> int main() { int average(int[], int); int values[10]; short table[3][3]; int i, j; for(i = 0; i < 10; ++i) values[i] = i; for(i = 0; i < 3; i++) { for(j = 0; j < 3; j++) table[i][j] = 3*i+j; } printf("Average value in first array is %d\n", average(values, 10)); printf("Average value in TABLE is %d\n", average(table, 9)); return 0; } int average(int a[], int size) { int i; long int sum = 0; for(i = 0; i < size; ++i) { printf("a[%i] = %i\n", i, a[i]); sum += a[i]; } return (sum/size); }
Ach ja, ich habe noch eine Print-Anweisung eingefügt.
Und hier die Meldung vom Compiler:gcc -o a -W -Wall -pedantic a.c && ./a a.c: In Funktion »main«: a.c:18: Warnung: Übergabe des Arguments 1 von »average« von inkompatiblem Zeigertyp
Und nun die Ausgabe des Programms:
a[0] = 0 a[1] = 1 a[2] = 2 a[3] = 3 a[4] = 4 a[5] = 5 a[6] = 6 a[7] = 7 a[8] = 8 a[9] = 9 Average value in first array is 4 a[0] = 65536 a[1] = 196610 a[2] = 327684 a[3] = 458758 a[4] = 8 a[5] = 65536 a[6] = 131072 a[7] = 196608 a[8] = 262144 Average value in TABLE is 189328
Ändert man den Typ von table von short auf int erhält man folgenden Output:
gcc -o a -W -Wall -pedantic a.c && ./a a.c: In Funktion »main«: a.c:18: Warnung: Übergabe des Arguments 1 von »average« von inkompatiblem Zeigertyp a[0] = 0 a[1] = 1 a[2] = 2 a[3] = 3 a[4] = 4 a[5] = 5 a[6] = 6 a[7] = 7 a[8] = 8 a[9] = 9 Average value in first array is 4 a[0] = 0 a[1] = 1 a[2] = 2 a[3] = 3 a[4] = 4 a[5] = 5 a[6] = 6 a[7] = 7 a[8] = 8 Average value in TABLE is 4
Schon besser, aber immer noch nicht so wirklich richtig. Man kann nun hingehen
und noch einen Cast einführen:printf("Average value in TABLE is %d\n", average((int*)table, 9));
Dann ist auch die Warning weg, aber ob das auf allen Plattformen ohne Fehler
funktioniert weiß ich so nicht.Aus welchem Buch hast du das denn?
Gruss
mcr
-
Danke, dass du dir die Arbeit gemacht hast.
Das mit dem short[][] table war mein Fehler, im Buch steht int[][] table. Ich hatte das nur vergessen abzuändern, weil ich probiert hatte, ob die Ergebnisse vom reservierten Speicherplatz abhängen...Der Titel des Buches lautet Microsoft C - Programmierhandbuch (Untertitel: Eine vollständige Anleitung mit Tips und Tricks und effizienten Programmen), 2. Auflage, Microsoft C, Version 6. von Kris Jamsa.
Das Buch ist sehr alt, es wurde 1991 herausgegeben...