C Größe eines übergebenen Arrays [duplicate]

Lesezeit: 4 Minuten

Benutzeravatar von Untamed
Ungezähmt

Mögliches Duplikat:

So finden Sie die Größe von (ein Zeiger, der auf ein Array zeigt)

Ich verstehe, dass der sizeof-Operator zur Kompilierzeit ausgewertet und durch eine Konstante ersetzt wird. Angesichts dessen, wie kann eine Funktion, der an verschiedenen Stellen in einem Programm verschiedene Arrays übergeben werden, ihre Größe berechnen lassen? Ich kann es als Parameter an die Funktion übergeben, aber ich möchte lieber keinen weiteren Parameter hinzufügen, wenn ich es nicht unbedingt muss.

Hier ist ein Beispiel, um zu veranschaulichen, was ich frage:

#include <stdio.h>
#include <stdlib.h>

#define SIZEOF(a) ( sizeof a / sizeof a[0] )


void printarray( double x[], int );

int main()
{
        double array1[ 100 ];


        printf( "The size of array1 = %ld.\n", SIZEOF( array1 ));
        printf( "The size of array1 = %ld.\n", sizeof array1 );
        printf( "The size of array1[0] = %ld.\n\n", sizeof array1[0] );

        printarray( array1, SIZEOF( array1 ) );

        return EXIT_SUCCESS;
}


void printarray( double p[], int s )
{
        int i;


        // THIS IS WHAT DOESN"T WORK, SO AS A CONSEQUENCE, I PASS THE 
        // SIZE IN AS A SECOND PARAMETER, WHICH I'D RATHER NOT DO.
        printf( "The size of p calculated = %ld.\n", SIZEOF( p ));
        printf( "The size of p = %ld.\n", sizeof p );
        printf( "The size of p[0] = %ld.\n", sizeof p[0] );

        for( i = 0; i < s; i++ )
                printf( "Eelement %d = %lf.\n", i, p[i] );

        return;
}

  • Standard C Gotcha – siehe die verknüpfte Frage.

    – Jon

    30. März 2011 um 22:37 Uhr

  • sizeof muss nicht zur Kompilierzeit in C99 ausgewertet werden – VLAs funktionieren ordnungsgemäß mit sizeofund ihre Größe kann nur zur Laufzeit bekannt sein.

    – Karl Norum

    30. März 2011 um 22:45 Uhr

Benutzeravatar von DigitalRoss
DigitalRoss

Es gibt keine magische Lösung. C ist keine reflektierende Sprache. Objekte wissen nicht automatisch, was sie sind.

Aber Sie haben viele Möglichkeiten:

  1. Fügen Sie natürlich einen Parameter hinzu
  2. Verpacken Sie den Aufruf in ein Makro und fügen Sie automatisch einen Parameter hinzu
  3. Verwenden Sie ein komplexeres Objekt. Definieren Sie eine Struktur, die das dynamische Array und auch die Größe des Arrays enthält. Übergeben Sie dann die Adresse der Struktur.

  • Sie können einen Zeiger auf das Array übergeben printarray( double (*p)[100])anrufen printarray(&array1) Sie können also auf Ihr Array verweisen *p und verwenden sizeof *p

    – Andrea993

    10. Mai 2018 um 21:49 Uhr

Funktionsparameter haben eigentlich nie einen Array-Typ. Wenn der Compiler sieht

void printarray( double p[], int s )

oder auch

void printarray( double p[100], int s )

es konvertiert entweder eins zu

void printarray( double* p, int s )

So sizeof(p) ist sizeof(double*). Und ja, Sie müssen die Größe als Parameter übergeben.

Das Problem ist, dass Ihre Funktion keinen Array-Wert erhält; es erhält einen Zeigerwert.

Außer wenn es der Operand von ist sizeof oder unär & Operatoren, oder es handelt sich um ein Zeichenfolgenliteral, das verwendet wird, um ein anderes Array in einer Deklaration zu initialisieren, einen Ausdruck vom Typ “array of T” wird in den Typ “Zeiger auf T” und sein Wert ist die Adresse des ersten Elements des Arrays.

Also, wenn Sie anrufen printarraydie Art von array1 wird implizit von “100-element array of double” bis “Zeiger auf double.” Also der Typ des Parameters p ist double *nicht double [100].

Im Kontext einer Funktionsparameterdeklaration T a[] ist identisch mit T *a.

Aus diesem Grund müssen Sie die Array-Größe separat übergeben;

  • Klar und prägnant, danke.

    – AlexSp3

    7. Oktober 2021 um 23:02 Uhr

Sie haben Ihre eigene Frage beantwortet. Es wird zur Kompilierzeit berechnet, also wie kann ‘sizeof p’ während der Laufzeit möglicherweise mehr als einen Wert haben?

Das Übergeben der Länge als Parameter ist eine gute Lösung, ansonsten können Sie sicherstellen, dass Ihre Arrays immer mit einem speziellen Wert enden (wie Zeichenfolgen und das Nullbyte).

Sie können einen Sentinel-Wert verwenden, der die Art und Weise darstellt, wie Zeichenfolgen behandelt werden. Der Nachteil ist, dass Sie über das gesamte Array iterieren müssen, um seine Größe zu finden.

Wenn Sie beispielsweise eine Zeichenfolge wie die folgende haben:

char s1[] = "foobar";

Was Sie tatsächlich haben, ist ein Array der Länge 7, wobei die siebte Stelle ein Null-Endzeichen ‘\0’ ist, das dazu dient, das Ende des Arrays / Strings anzuzeigen.

Eine andere Möglichkeit besteht darin, eine Struktur zu erstellen, die aus einer Größe gefolgt vom Array besteht.

Benutzeravatar von Scott Duckworth
Scott Duckworth

Sie müssen entweder

  1. Übergeben Sie die Größe des Arrays als Parameter an die Funktion
  2. Stellen Sie sicher, dass das Array mit einem bekannten Wert endet, und stoppen Sie, wenn Sie diesen Wert erreichen.

Benutzeravatar von Eric
Erich

Wenn Ihr Array nullterminiert ist, können Sie das Array durchlaufen und den letzten Wert finden. Viele String-Operatoren in C funktionieren auf diese Weise

Sonst hat man keine große Wahl.

sizeof gibt die Größe von p zurück, das ein Zeiger ist und gleich Ihrer int-Größe ist

1391110cookie-checkC Größe eines übergebenen Arrays [duplicate]

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

Privacy policy