可能性のある複製:
sizeof(配列を指すポインタ)を見つける方法)
Sizeof演算子が評価され、コンパイル時に定数に置き換えられることを理解しています。それでは、プログラムのさまざまなポイントでさまざまな配列を渡された関数のサイズをどのように計算できますか?関数にパラメーターとして渡すことはできますが、絶対に必要がない場合は、パラメーターを追加する必要はありません。
これが私が求めていることを説明するための例です:
#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;
}
魔法の解決策はありません。 Cは反映言語ではありません。オブジェクトは、それらが何であるかを自動的に認識しません。
しかし、あなたには多くの選択肢があります:
関数パラメーターが実際に配列型になることはありません。コンパイラが見たとき
_void printarray( double p[], int s )
_
あるいは
_void printarray( double p[100], int s )
_
いずれかに変換します
_void printarray( double* p, int s )
_
したがって、sizeof(p)
はsizeof(double*)
です。はい、サイズをパラメーターとして渡す必要があります。
問題は、関数が配列値を受信しないことです。ポインタ値を受け取ります。
sizeof
演算子または単項&
演算子のオペランドである場合、または宣言内の別の配列を初期化するために使用される文字列リテラルである場合を除き、型「array of T
"は" pointer to T
"型に変換され、その値は配列の最初の要素のアドレスになります。
したがって、printarray
を呼び出すと、array1
の型は「double
の100要素配列」から「double
へのポインター」に暗黙的に変換されます。したがって、パラメータp
のタイプはdouble *
であり、double [100]
ではありません。
関数パラメーター宣言のコンテキストでは、T a[]
はT *a
と同じです。
これが、配列のサイズを個別に渡す必要がある理由です。
あなた自身の質問に答えました。それはコンパイル時に計算されるので、実行時に「sizeof p」はどのようにして複数の値を持つことができますか?
長さをパラメーターとして渡すことは良い解決策です。そうでない場合は、配列が常に特別な値(文字列やnullバイトなど)で終わるようにすることができます。
文字列の処理方法であるセンチネル値を使用できます。欠点は、配列のサイズを見つけるために配列全体を反復処理する必要があることです。
たとえば、次のような文字列があるとします。
char s1[] = "foobar";
実際に持っているのは長さ7の配列で、7番目のスポットは配列/文字列の終わりを示すのに役立つヌル終了文字 '\ 0'です。
あなたがそれを行うことができる別の方法は、配列とそれに続くサイズで構成される構造体を作成することです。
あなたはどちらかでなければなりません
配列がnullで終了している場合は、配列を反復処理して最後の値を見つけることができます。 Cの多くの文字列演算子はそのように機能します
そうでなければ、あなたはあまり選択肢がありません。
sizeofはpのサイズを返します。これはポインターであり、intサイズと等しくなります。