Woher kennt sizeof die Größe des Arrays? [duplicate]

Lesezeit: 5 Minuten

Ich habe folgende Codes:

main() {
    int array[5] = {3,6,9,-8,1};
    printf("the size of the array is %d\n", sizeof(array));
    printf("the address of array is %p\n", array);
    printf("the address of array is %p\n", &array);
    int * x = array;
    printf("the address of x is %p\n", x);
    printf("the size of x is %d\n", sizeof(x));
}

Die Ausgabe ist

the size of the array is 20
the address of array is 0x7fff02309560
the address of array is 0x7fff02309560
the address of x is 0x7fff02309560
the size of x is 8

Ich kenne die Variable array wird als Zeiger auf das erste Element des Arrays gesehen, also verstehe ich, dass die Größe von x 8 ist. Aber ich weiß nicht, warum die Größe des Arrays 20 ist. Sollte es nicht 8 sein (in a 64-Bit-Maschine)?

Außerdem, woher weiß das Programm, dass es 20 ist? Soweit ich weiß, speichert es in C nicht die Anzahl der Elemente. Wie kommt das sizeof(array) und sizeof(x) ist anders? Ich habe mehrere Posts verfolgt, die sich auf das Verfallen von Arrays beziehen, aber keine Ahnung von diesem Problem.

  • Der Compiler weiß, wie groß die Array-Elemente sind und wie viele Elemente sich im Array befinden, sodass er die beiden multiplizieren kann, um das Ergebnis zu erhalten sizeof. Es ist die Aufgabe des Compilers, dies zu wissen.

    – Jonathan Leffler

    17. Dezember 2014 um 4:20 Uhr


  • Verwandte: Wie verwende ich Arrays in C++? Die ersten 3 Themen der akzeptierten Antwort erklären den Unterschied zwischen Zeigern und Arrays ziemlich ausführlich.

    – AliciaBytes

    17. Dezember 2014 um 4:27 Uhr


  • Überprüfen Sie diese Frage stackoverflow.com/questions/17752978/…

    – nj-ath

    17. Dezember 2014 um 4:36 Uhr

  • Ein Array ist nicht ein Zeiger auf sein erstes Element – es wird nur manchmal automatisch in eins umgewandelt.

    – Benutzer253751

    17. Dezember 2014 um 8:33 Uhr


  • Schlüsselpunkt, den Sie vielleicht übersehen haben: Trotz seines Aussehens, sizeof ist keine Funktion, sondern ein Kompilierungsoperator. Nur der Compiler muss die Antwort wissen, es spielt also keine Rolle, dass die Informationen nicht im Programm “gespeichert” werden.

    – Euro Mizellen

    17. Dezember 2014 um 11:27 Uhr

Benutzer-Avatar
Jerry Sarg

Der Name eines Arrays zerfällt zu einem Zeiger auf das erste Element des Arrays in die meisten Situationen. Es gibt jedoch ein paar Ausnahmen von dieser Regel. Die beiden wichtigsten sind, wenn der Array-Name als Operand von entweder verwendet wird sizeof Betreiber oder die address-of Operator (&). In diesen Fällen bleibt der Name des Arrays ein Bezeichner für das Array als Ganzes.

Für ein Nicht-VLA-Array bedeutet dies, dass die Größe des Arrays statisch (zur Kompilierzeit) bestimmt werden kann und das Ergebnis des Ausdrucks die Größe des Arrays (in Byte) und nicht die Größe eines Zeigers ist.

Wenn Sie die Adresse des Arrays nehmen, erhalten Sie denselben Wert (dh dieselbe Adresse), als ob Sie nur den Namen des Arrays ohne die Adresse verwendet hätten. Der Typ ist jedoch unterschiedlich – wenn Sie explizit die Adresse nehmen, erhalten Sie einen Zeiger vom Typ „Zeiger auf Array von N Elementen vom Typ T“. Das bedeutet (für ein Beispiel) dass während array+1 zeigt auf das zweite Element des Arrays, &array+1 zeigt auf ein anderes Array direkt hinter dem Ende des gesamten Arrays.

Unter der Annahme eines Arrays von mindestens zwei Elementen, *(array+1) bezieht sich auf das zweite Element des Arrays. Unabhängig von der Array-Größe &array+1 ergibt eine Adresse nach dem Ende des Arrays, sodass der Versuch, diese Adresse zu dereferenzieren, zu einem undefinierten Verhalten führt.

In Ihrem Fall ist die Größe des Arrays 20 und die Größe eines Elements des Arrays 4, wenn array war dann beispielsweise 0x1000 array+1 wäre 0x1004 und &array+1 wäre 0x1014 (0x14 = 20).

Benutzer-Avatar
Raipe

Ihr Array hat eine statische Länge, sodass es zur Kompilierzeit bestimmt werden kann. Ihr Compiler kennt die sizeof(int) = 4 und Ihre statische Array-Länge [5]. 4 * 5 = 20

Bearbeiten: Ihr Compiler ist wahrscheinlich int 32-Bitaber 64-Bit-Adressierung. Deswegen sizeof(pointer) zurück 8.

Beachten Sie, dass sizeof ist nicht eine Bibliotheksfunktion. sizeof ist

ein unärer Kompilierzeit-Operator […] die verwendet werden können, um die Größe eines beliebigen Objekts zu berechnen
K&R

So sizeof nicht weiß, wie groß das Array ist, weiß der Compiler, wie groß das Array ist, und per Definition

Bei Anwendung auf ein Array ist das Ergebnis die Gesamtzahl der Bytes im Array.
K&R

Ein Zeiger und ein Array sind 2 verschiedene Datentypen.

Array kann Elemente ähnlichen Datentyps enthalten. Der Speicher für das Array ist zusammenhängend.

Zeiger wird verwendet, um auf einen gültigen Speicherort zu zeigen.

sizeof(type) gibt Ihnen die Anzahl der Bytes des Typs, den Sie übergeben.

Wenn Sie nun ein Array übergeben, weiß der Compiler, dass dies ein Array und eine Anzahl von Elementen darin ist, und er multipliziert einfach so viele Elemente mit dem entsprechenden Datentyp-Größenwert.

In diesem Fall:

5*4 = 20

Wieder die sizeof(int) oder sizeof(pointer) ist plattformabhängig. In diesem Fall sehen Sie sizeof(pointer) als 8.

Nein, Arrays zerfallen nicht als Operanden von sizeof Operator. Dies ist einer der wenigen Orte, an denen Arrays nicht zerfallen. Wenn ein int auf Ihrem Rechner 4 Bytes beträgt, dann sollte die Gesamtzahl der Bytes des Arrays 20 (4 * 5) betragen. Wir brauchen nicht einmal ein Objekt, um dies zu testen.

sizeof(int[5]) // 20
sizeof(int*)   // 8 on a 64-bit machine

Benutzer-Avatar
hackt

C11: 6.5.3.4 (p2)

Das sizeof Operator liefert die Größe (in Bytes) seines Operanden, der ein Ausdruck oder der Name eines Typs in Klammern sein kann. Die Größe wird durch den Typ des Operanden bestimmt. […]

In der Deklaration

int array[5]  

die Art von array ist ein Reihe von 5 ints. Der Compiler bestimmt die Größe von array von diesem Typ.

Benutzer-Avatar
lappen

Versuche dies

int x = sizeof(array)/sizeof(int);
printf("the size of the array is %d\n", x);

1143020cookie-checkWoher kennt sizeof die Größe des Arrays? [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy