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
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:
Fügen Sie natürlich einen Parameter hinzu
Verpacken Sie den Aufruf in ein Makro und fügen Sie automatisch einen Parameter hinzu
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.
Scott Duckworth
Sie müssen entweder
Übergeben Sie die Größe des Arrays als Parameter an die Funktion
Stellen Sie sicher, dass das Array mit einem bekannten Wert endet, und stoppen Sie, wenn Sie diesen Wert erreichen.
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
13911100cookie-checkC Größe eines übergebenen Arrays [duplicate]yes
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äß mitsizeof
und ihre Größe kann nur zur Laufzeit bekannt sein.– Karl Norum
30. März 2011 um 22:45 Uhr