0

私はCの初心者で、配列を関数に渡して要素にアクセスする方法を探しています。

それには3つの方法があることがわかりました。

  1. 配列を渡し、関数はパラメーターを配列の型として特定します
  2. 配列を渡し、関数はパラメーターをポインターの型として特定します
  3. 最初の要素のアドレスを渡します(実際、このアドレスは配列アドレスと同じです。これは方法2と同じだと思います)

私が理解していないのは、方法1を使用することです。渡される配列のアドレスは、関数内の配列パラメーターのアドレスとは異なります。方法 1 と方法 2 の使用の違いは何ですか。

コード:

#include <stdio.h>

void pass_by_array(int x[]);
void pass_by_pointer(int *x);
int main(void){
    int i;
    int base[5] = {3, 7, 2, 4, 5};
    printf("address of first element in main %p\n", &base[0]);
    printf("address of array in main %p \n\n", &base);
    pass_by_array(base);
    pass_by_pointer(base);
}

/* Pass in the array as type of int x [] */
void pass_by_array(int x[]){
    printf("address of first element passed in: %p \n", &x[0]);
    printf("address of array passed in: %p \n\n", &x);
}

/* Pass in the array as type of int pointer*/
void pass_by_pointer(int *x){
    printf("passing in array by pointer, address: %p",x);
}

出力:

address of first element in main 0xbfcea3ac
address of array in main 0xbfcea3ac 

address of first element passed in: 0xbfcea3ac 
address of array passed in: 0xbfcea390 

passing in array by pointer, address: 0xbfcea3ac%   
4

2 に答える 2

2

この行:

printf("address of array passed in: %p \n\n", &x);

間違っている。配列のアドレスを出力するのではなく、配列ポインターが格納されているローカル変数のアドレスを出力します (はい、x実際にはポインターです)。出力するだけxです:

printf("address of array passed in: %p \n\n", x);

答えは、この場合、どちらの方法で宣言してもあまり問題にならないということです。 int[]int*C では、互換性がある場合があり、これは互換性のあるケースの 1 つです。

参考文献:

于 2013-06-13T18:53:04.830 に答える
2

[]コンパイラのセマンティクスは同じですが、フォームを使用することには十分な理由があります。具体的には、引数が特定の次元(静的または渡された別の引数で指定されたもの)の配列を表すと予想される場合、*構文を使用するよりも意図を明確にすることができます。

あれは

int arraySum(int n, int ary[n]);

引数の意味を文書化しますがn

int arraySum(int n, int *ary);

ではない。

同様に

void crossProduct(double result[3], double v1[3], double v2[3]);

引数が 3 次元ベクトルであることが期待されることを明確にします。

void crossProduct(double *result, double *v1, double *v2);

読者に推測を任せます。

繰り返しになりますが、コンパイラはこれらを同じものとして扱いますが、人間の読者は、一方のフォームから他方のフォームよりも多くの情報を取得できます。

于 2013-06-13T19:05:43.737 に答える