0

Cの関数の仮パラメータでの多次元配列のこれら2つの異なるタイプの宣言を読みました.

int c[][10];

int (*c)[10];

これら2つはどのように同じですか? 私はそれを感じていません。2番目の例が何をしようとしているのか、誰かがこれをいくつかの例で説明できますか? これが以前に尋ねられた場合は申し訳ありません..もしあれば重複に私をリダイレクトしてください.

4

3 に答える 3

8

関数の引数として、int* cおよびint c[]またはさらにint c[7]は同一です。C FAQを参照してください。

この[10]部分は、配列内の要素にアクセスするための算術演算の方法をコンパイラに伝えるだけc[3][5]です。これらの宣言は両方とも、2 番目の次元 (コンパイラに関する限り、この関数内) のサイズが 10 の多次元配列用です。

例:

#include <stdio.h>

int sum_all(int c[][2], int len) {
    int res = 0, i ,j;
    for (i=0; i < len; i++)
        for (j=0; j < 2; j++)
            res += c[i][j];
    return res;
}

int main() {
    int a[3][2] = { { 1, 2}, {3, 4}, {5, 6} };
    printf("sum is %d\n", sum_all(a, 3));
    return 0;
}

この例では、配列がサイズ 2 であることがチェックされていないことに注意してください。1 次元配列を渡すこともできました。コンパイラは気にしません。この配列の要素にアクセスする方法だけを彼に伝えました。

于 2013-06-27T10:22:40.207 に答える
4

N1570:

6.7.6.3 関数宣言子 (プロトタイプを含む)
... 7 「
の配列」としてのパラメーターの宣言は、「への修飾ポインター」に調整されるものとします 。型修飾子 (存在する場合) は指定されたものです配列型派生のand内。キーワードが配列型派生のand内にも現れる場合、関数の呼び出しごとに、対応する実引数の値によって、少なくともサイズで指定された数の要素を持つ配列の最初の要素へのアクセスが提供されます。表現。 []static[]

したがって、関数パラメーター宣言のコンテキスト内では、T a[N]とはどちらも;T a[]と同等です。3 つすべてが へのポインタとしてT *a宣言します。この特定のケースでは、「の 10 要素配列」です。aTTint

これは、次のことと密接に関連しています。

6.3.2.1 左辺値、配列、および関数指定子
... 3演算子、演算子、または単項演算子
のオペランドである場合、または配列の初期化に使用される文字列リテラルである場合を除き、'' 型を持つ式'' の配列は、配列オブジェクトの最初の要素を指し、左辺値ではない''型へのポインター '' を持つ式に変換されます。配列オブジェクトにレジスタ ストレージ クラスがある場合、動作は未定義です。 sizeof_Alignof&

次のように宣言された配列があるとします。

int arr[5][10];

arr次のような関数に配列式を渡すと、

foo( arr );

配列式arrは、「の 10 要素配列の 5 要素配列」int型から「」の 10 要素配列へのポインター型に変換されint、そのポインター値が関数に渡されます。したがって、 の関数プロトタイプは次のようにfooなります

void foo( int (*c)[10] )

また

 void foo( int c[][10] )

あるいは

 void foo( int c[5][10] )

ただし、3 つの場合すべてにおいてc、2D 配列ではなく、配列へのポインターです。

于 2013-06-27T11:13:38.530 に答える