2014-11-13 2 views
5

Angesichts der Definition eines Arrays in C: int a [2] [3] [4] [5], und die Adresse eines [0] [0] [ 0] [0] ist 1000 was ist die Adresse von a [1] [1] [1] [1], vorausgesetzt, ein int belegt 4 Bytes.Finden Sie die Adresse eines Index in einem Array in C

Ich habe:

(3 * 4 * 5 * 4 Bytes) + (4 * 5 * 4 Bytes) + (5 * 4 Bytes) + 4 Bytes = 344

344 + 1000 = 1344 Ort von einem [1] [1] [1] [1]

aber ich habe keine Ahnung, ob ich recht habe. Aber meine Mathematik schien mir gut zu sein.

+0

Hört sich gut an. – JS1

Antwort

3

einfach die Adresse der Variablen drucken Sie es, Sie werden es sehen !:

#include <stdio.h> 

int main() { 

    int a[2][3][4][5]; 

    printf ("Size of int %d\n", sizeof(int)); 

    printf("Adress of the frist element \t%p\n", &a[0][0][0][0]); 
    printf("Adress of x element \t\t%p\n", &a[1][1][1][1]); 

    printf ("In decimal: \t\t\t%d\n", &(a[0][0][0][0])); 
    printf ("In decimal: \t\t\t%d\n", &(a[1][1][1][1])); 

    printf("Difference between the adresses %d", (char *)&a[1][1][1][1] - (char *)&a[0][0][0][0]); 




    return 0; 

} 

Danach können Sie, wenn Sie überprüfen können, wo richtig!

Und wie Sie Ihr Recht sehen! es ist 334

+0

Ihre zweite 'printf' gibt die Adresse von' a [1] [1] [1] [0] ', nicht 'a [1] [1] [1] [1]'. Warum nicht einfach über das, was Sie versuchen zu tun und schreiben '& a [0] [0] [0] [0]'? –

+0

@RedAlert Wups hat 1 Dimension vergessen! Danke – Rizier123

+0

'% d' mit einem Zeiger ist problematisch (vor allem, wenn int 32bit und Zeiger ist 64bit), in Betracht ziehen, [Uintptr_t] (http://stackoverflow.com/questions/5795978/string-format-for-intptr-t -und-uintptr-t) –

0

So etwas ist ziemlich einfach zu überprüfen (a):

#include <stdio.h> 

int main (void) { 
    int a[2][3][4][5]; 

    // Ignore incorrect format specifiers for now. 

    printf ("%d\n", sizeof(int)); 
    printf ("%d\n", &(a[0][0][0][0])); 
    printf ("%d\n", &(a[1][1][1][1])); 
    printf ("%d\n", (int)&(a[1][1][1][1]) 
        - (int)&(a[0][0][0][0]) 
        + 1000); 

    return 0; 
} 

und der Ausgang davon ist:

4 
2665056 
2665400 
1344 

Beachten Sie die Umwandlungen der Zeiger auf int Werte in diesem letzten printf. Ohne diese würde die 1000 als int * skaliert werden, was den falschen Wert ergibt.

Also, ja, unterm Strich, Ihre Argumentation ist richtig.


(a) Das ist nicht immer der Fall, da einige Aspekte der Sprache C über Implementierungen unterscheiden können (umsetzungs spezifizierte Verhalten) oder in irgendeiner Weise sie (nicht definiertes Verhalten) wollen.

Erfreulicherweise Layout von Arrays spezifisch durch die Norm in C11 6.5.2.1 Array subscripting angegeben ist:

2/A Postfix Ausdruck durch einen Ausdruck in eckigen Klammern [] ist eine indizierte Bezeichnung eines Elements eines Arrays Objekt. Die Definition des tiefgestellten Operators [] ist, dass E1[E2] identisch mit (*((E1)+(E2))) ist. Aufgrund der Konvertierungsregeln, die auf den binären + Operator anzuwenden, wenn E1 ist ein Array-Objekt (äquivalent, ein Zeiger auf das Anfangs-Element eines Arrays Objekts) und E2 eine ganze Zahl ist, E1[E2] bezeichnet das E2-th Element E1 (Zählung von Null).

3/Aufeinanderfolgende Subskriptoperatoren bezeichnen ein Element eines mehrdimensionalen Array-Objekts. Wenn E ein n-dimensionales Array (n> = 2) mit den Dimensionen i * j * ... * k ist, wird E (anders als ein lvalue verwendet) in einen Zeiger auf ein (n - 1) -dimensionales Array mit den Dimensionen j * ... * k konvertiert.Wenn der unäre Operator * auf diesen Zeiger explizit oder implizit als Ergebnis von Subskriptionen angewendet wird, ist das Ergebnis das referenzierte (n - 1) -dimensionale Array, das selbst in einen Zeiger konvertiert wird, wenn es anders als ein Lvalue verwendet wird. Daraus folgt, dass Arrays in Reihe-Haupt-Reihenfolge gespeichert werden (letzter Index variiert am schnellsten).

+1

dieser Ausgang scheint seltsam, '2665400 - 2665056 + 1000' ist nicht' 1086'. Ich stelle mir vor, der Compiler denkt, dass Sie versuchen, Zeigerarithmetik zu tun. –

+1

@RedAlert, ja, habe das gerade gemerkt, und du würdest denken, dass jemand mit so viel C unter dem Gürtel wie ich das vorne wissen würde :-) Modified to fix. – paxdiablo

3

Ihre Mathematik ist korrekt. Sie können durch Subtraktion der beiden Adressen überprüfen, aber vergessen Sie nicht, dass die arithmetische Zeiger wird die Schriftgröße erkennen, so müssen Sie die Adressen zu gieße char, die eine Größe von einem Byte hat:

(char*)&a[1][1][1][1] - (char*)&a[0][0][0][0] 

, die das gibt Differenz in Bytes. Dann füge einfach die Startadresse hinzu und du hast deine Antwort.

Verwandte Themen