2016-08-04 11 views
0

Ich habe Code so etwas wie diesesDie Ausgänge meines Programms sind verwirrend

int main() 
{ 
    unsigned int x [4] [3] = 
    {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}}; 
    printf("%u, %u, %u", x + 3, * (x + 3), * (x + 2) + 3); 
} 

Die Ausgabe für alle 3 Werte sind gleiche kann mir jemand sagen, warum.?

+0

Die Verwendung des falschen Formatspezifizierers ist ein undefiniertes Verhalten. – mch

+0

Wie kommt es falsch Formatbezeichner% u ist für unsigned int. –

+0

'x + 3' hat den Typ' unsigned int (*) [3] '(ein Zeiger),' * (x + 3) 'und' * (x + 2) + 3' haben den Typ 'unsigned int *'. Alle 3 sind keine »unsigned int«, sondern Zeiger, also sollten Sie '% p' verwenden und nach' (void *) 'umwandeln. – mch

Antwort

2

Zunächst müssen Sie - wie andere darauf hingewiesen haben - die richtigen Formatbezeichner verwenden und diese Werte in Pointer umwandeln.


Nun, warum alle von ihnen denselben Wert geben.

Hier ist x ein Array. Und die Art seiner Elemente sind unsigned int[3]. d.h. x ist ein Array von unsigned int[3] Arrays.

Zuerst gibt x + 3 die Adresse des vierten Elements in Ihrem Array. Das ist die Adresse von {10, 11, 12}. Die Adresse dieses Arrays im Speicher ist die Adresse seines ersten Elements im Speicher. Das ist die Adresse 10 im Speicher. Beachten Sie, dass dieser Wert int (*) [3] ist, d. H. address of an unsigned int[3] array.

Zweitens ist * (x + 3) äquivalent zu x [3], das ist das vierte Element, das unsigned int[3] ist. Es ist das Array {10, 11, 12}. Dieser Wert zeigt auf das erste Element von Array {10, 11, 12}. Das heißt, dieser Wert zeigt auf 10. Beachten Sie, dass dieser Wert unsigned int[3] ist.

Third *(x+2) + 3: Hier *(x + 2) entspricht x[2] was ein unsigned int[3], die {7, 8, 9} Array ist, und wenn Sie eine + 3 tun Sie wieder bekommen die Adresse 10.Beachten Sie, dass dieser Wert unsigned int[3] ist.

So sehen Sie in allen drei Fällen Ihr Ergebnis ist die gleiche Adresse im Speicher, d. H. Die Adresse, wo 10 gespeichert ist - auch wenn Sie verschiedene Dinge zu unterschiedlichen Zeiten darstellen; unsigned int (*)[3] zuerst, und unsigned int[3] an zweiter und dritter Stelle.

0

Destilliertes undefinierten Verhalten:

printf("%u, %u, %u", x + 3, * (x + 3), * (x + 2) + 3); 

Alle zusätzlichen Argumente müssen unsigned int sein, aber der 2d ist unsigned int (*)[3], die 3D-unsigned int * ist, ist die 4. unsigned int * auch.

1

Sie erhalten falsche Werte, weil Sie die Zeigerarithmetik falsch machen.
x vom Typ unsigned int[4][3], ein Array mit einer Länge von 4, von denen jedes Mitglied selbst ein Array mit der Länge 3.

Was ist also x+3? Es ist die Adresse des letzten Mitglieds in x (denken Sie daran, dass die Mitglieder von x sind Arrays).
Und daher ist *(x+3) selbst ein Array. Aber was passiert mit Arrays, wenn Sie sie als Funktionsparameter übergeben? Sie zerfallen in Zeiger. So sehen Sie die Adresse des ersten Elements in , die Array, durch den falschen Typ-Spezifizierer in printf gemangelt.

Okay, kommen wir zum Beispiel zum Element x[2][3]. Es wird ein Ausdruck dieser Art *(*(x+2)+3) sein, der insgesamt *(&x[0][0] + 2*3 + 3) entspricht.

Verwandte Themen