1

以下のように書いたら結果が1になってしまいます。予想される答えは 5 です。

    int main()
    {
      const char* list_of_filename[] = {"One","Two","Three","Four","Five"};

      printf("%d", countFiles(list_of_filename));

      return 0;
    }

    int countFiles(const char* list_of_filename[])
    {
      return sizeof(list_of_filename) / sizeof(list_of_filename[0]);
    }
4

4 に答える 4

4

sizeof配列は、配列を宣言するスコープでのみ機能します。

  const char* list_of_filename[] = {"One","Two","Three","Four","Five"};
  printf("%d", sizeof(list_of_filenames) / sizeof(list_of_filenames[0]));

C では、配列を渡すことはできません。そう:

int countFiles(const char* list_of_filename[])

は次とまったく同じです:

int countFiles(const char **list_of_filename)

つまり、2 つのポインターのサイズを比較しています。とのサイズはconst char *const char **システム上で同じです。

この回答(Michael Burrによるものですが、元々はChromiumから)は、配列サイズの計算を行うマクロと、このような無効な構造のエラーを提供します(ただし、これはそうではありません)

于 2012-04-05T03:45:17.483 に答える
2

関数の引数として、

const char* list_of_filename[]

実際には:

const char** list_of_filename.

したがって、実際に計算しているのは次のとおりです。

sizeof(char**) / sizeof(char*)

char**char*は両方とも単なるポインタであり、すべてのポインタは一般に同じサイズであるため(少なくともこの場合、これら2つは同じです):

x / x
= 1


編集:配列をCの関数に渡すときは、通常、配列のサイズを渡すか、配列の長さを決定できるように特定の値で配列を終了する必要があります。

于 2012-04-05T03:47:43.253 に答える
1

C標準から(C11 6.3.2.1 Lvalues, arrays, and function designators, para 3):

sizeof演算子、_Alignof演算子、またはunary&演算子のオペランドである場合、または配列を初期化するために使用される文字列リテラルである場合を除き、「型の配列」型の式は、次の式に変換されます。配列オブジェクトの初期要素を指し、左辺値ではない「typeへのポインター」と入力します。

つまり、その配列を関数に渡すと、配列の最初の要素へのポインターになるため、そのサイズはポインターのサイズになります。

関数内で配列として扱いたい場合は、次のようなサイズ情報を明示的に渡す必要があります。

void printArray (int *arr, size_t sz) {
    for (size_t i = 0; i < sz; i++)
        print ("%d ", arr[i]);
    puts ("");
}
:
int xyzzy[] = {3,1,3,1,5,9,2,6,5,3,5,8,9};
printArray (xyzzy, sizeof (xyzzy) / sizeof (*xyzzy));
于 2012-04-05T03:52:44.710 に答える
0

C 配列とポインタは同じではありません!

初心者の C プログラマーがよく耳にする最初のことの 1 つは、「配列はポインターと同じです」というものです。残念ながら、これは危険な半分の真実です。ANSI C 規格のパラグラフ 6.5.4.2 では、次のことを推奨しています。

宣言の違いに注意してください。

extern int *x;
extern int y[];

1 つ目は、x が int へのポインターであることを宣言します。2 番目は、y を、サイズが指定されていない (不完全な型の) int の配列であると宣言します。そのストレージは別の場所で定義されています。

規格は、それ以上の詳細については触れていません。

したがって、配列から取得しようとするとsizeof、配列全体のサイズ (オブジェクトのサイズの合計) がバイトsizeof単位で返され、ポインターを取得しようとすると、ポインターのサイズがバイト単位で返されます。ポインタのサイズは、1 つのプラットフォームでは常に一定の値です。通常は 4 または 8 バイトです。

これを覚えて :)

于 2012-04-05T04:47:50.380 に答える