2

1次元配列を関数に渡すために使用する通常の方法は次のとおりです。

#include <stdio.h>
#define ARRAY_SIZE 5 

void function(int *ptr_array, int size) 
{
  int index;
  printf("Destination array contents: ");
  for(index=0;index<size;index++)
  {
     printf("%d ",ptr_array[index]);
  }
}

int main()
{
   int array[ARRAY_SIZE]={1,2,3,4,5};
   function(array,ARRAY_SIZE);
   printf("\n");
   return 0;
}

void function(int ptr_array[],int size)引数を受け入れる関数は(または)としても続くことができることに気づきvoid function(int ptr_array[5],int size)ました。このシナリオでは、渡された引数はですが、int *で受信されint []ます。だから質問は

  • コンパイラは関数で受け入れられた引数のキャストを実行する必要があるように見えます。配列インデックスはキャストにどのように影響しますか?
  • 関数に渡されるのが2D配列のベースアドレスである場合、int[][]フォーム で引数を受け入れるための正しいタイプは何ですか
4

3 に答える 3

2

関数パラメーター宣言のコンテキストでは、は;T a[]T a[N]同義です。は、またはを使用するかどうかに関係なく、配列型ではなくポインタ型です。 T *aa[][N]*

章と詩:

6.7.6.3関数宣言子(プロトタイプを含む)

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

なぜそうなるのでしょうか?これが理由です:

6.3.2.1左辺値、配列、および関数指定子

... 3演算子、演算子、または単項演算子
のオペランドである場合、または配列を初期化するために使用される文字列リテラルである場合を除き、 ''の配列''型の式は式に変換されます配列オブジェクトの初期要素を指し、左辺値ではないタイプ''ポインタからタイプ''を使用します。配列オブジェクトに ストレージクラスがある場合、動作は定義されていません。 sizeof_Alignof&register

の呼び出しでfunctionは、 arrayのタイプは「5要素配列のint」です。6.3.2.1 / 3の規則により、「decays」型の式に変換(「decays」)され、intその値は最初の要素(&array[0])のアドレスになります。このポインタ値は、に渡されるものfunctionです。

arrayとして宣言されていた場合int array[5][5]、式arrayは「5要素配列の5要素配列int」から「ポインタから5要素配列のint」またはint (*)[5]に変換され、関数宣言は次のようになります。

void function(int (*array)[5], int size)

これは次のように書くこともできます

void function(int array[][5], int size)

また

void function(int array[5][5], int size)

この場合、外寸のサイズはオプションではないことに注意してください。コンパイラがポイントされている型のサイズを認識できるように指定する必要があります。

于 2012-10-17T16:17:16.690 に答える
1

すべての配列は、配列と同じタイプのポインターに暗黙的にキャストできますが、その逆はできません。そのため、ポインターを受け入れる関数またはポインターに配列を割り当てる関数に配列を渡すことはできますが、配列にポインターを割り当てることはできません。

2番目の質問については、引数をdouble配列(つまりtype array[][])または配列へのポインター(つまり)として持つ必要がありますtype (*array)[]。この場合、ポインタへのポインタは別のものであるため機能しません

于 2012-10-17T16:00:01.440 に答える
1

コンパイラは関数で受け入れられた引数のキャストを実行する必要があるように見えますが、配列インデックスはキャストにどのように影響しますか?

一部の状況(C11標準によるとsizeof_Alignofおよび単項演算子のオペランドとしての使用)を除いて、配列は最初の要素へのポインターとして評価されます。&さらに、次の形式は同等です(関数パラメーターの場合)。

void function(int ptr_array[], int size);
void function(int *ptr_array, int size);

したがって、議論の実際の「キャスト」はありません。配列は暗黙的にポインタに変換され、引数の型と一致します。

関数に渡されるのが2D配列のベースアドレスである場合、int [] []形式の引数を受け入れるための正しいタイプは何ですか?

次の形式は、他にも正しいものです。

void f(int t[][SIZE]);
void f(int (*t)[SIZE]);
于 2012-10-17T16:01:56.610 に答える