15

私の質問は次のコードに基づいています:

int myfunct(int ary[], int arysize)   
int myfunct2(int *ary, int arysize)

 int main(void){
   int numary[10];
   myfunct(numary, 10)
   myfunct2(numary, 10)
   return;
 }

int myfunct(int ary[], int arysize) {   
      //Whatever work is done

  }

int myfunct2(int *ary, int arysize) {
     // Whatever work is done

  }

これらのいずれかを他のものよりも使用する理由はありますか?詳述すると、数値配列に関係する場合、配列表記よりもポインター表記を使用したい理由がありますか。ポインタ表記を使用する場合は、関数ポインタ内で算術演算などが使用されます。また、[]配列表記を使用する場合は、通常どおり配列を操作できます。私はプログラミングに不慣れで、現在、ポインター表記を使用するメリットはありません。

私の正確な質問は、ポインター表記を使用して、したがって関数内でポインター操作を使用して、数値配列を関数に渡す理由があります。

4

6 に答える 6

11

関数パラメーターを配列として宣言すると、コンパイラーは配列サイズ(存在する場合)を自動的に無視し、それをポインターに変換します。つまり、この宣言は次のとおりです。

int foo(char p[123]);

100%同等です:

int foo(char *p);

実際、これは表記ではなく、実際のタイプに関するものです。

typedef char array_t[42];
int foo(array_t p);  // still the same function

pこれは、関数内でのアクセス方法とは関係ありません。さらに、[]演算子は「配列表記」ではありません。[]ポインタ演算子です:

a[b]

100%同等です:

*(a + b)
于 2013-01-12T23:22:30.677 に答える
9

2つの表記法の間に実際の機能上の違いはありません。Cでは、配列変数を関数に渡すと、表記に関係なく、ポインターに減衰します。しかし、私の意見では、ポインタ表記が望ましいです。関数定義の表記法の問題[]は、私の意見では、それがいくぶん誤解を招くことです。

void foo(int array[])
{

}

初心者のCプログラマーの間でよくある間違いは、スタックで宣言された配列変数の場合と同様に、配列内の要素の数にを掛けたものにsizeof(array)なると想定することです。しかし、現実には、誤解を招く表記にもかかわらず、ポインターに減衰しているので、そうなるでしょう。実際には、最初の要素への単なるポインタ、またはおそらくどこかに割り当てられた単一の整数へのポインタです。sizeof(int)arrayarray[]sizeof(array)sizeof(int*)array

たとえば、次のfooように呼び出すことができます。

int x = 10;
foo(&x);

その場合、[]の定義の表記fooは誤解を招くようなものです。

于 2013-01-12T23:21:13.783 に答える
3

これらの宣言は完全に同一です。標準を引用するには:

「型の配列」としてのパラメータの宣言は、「型への修飾ポインタ」に調整されるものとします。

C99標準セクション6.7.5.3パラグラフ7

于 2013-01-13T07:04:49.323 に答える
0

C99以降可変長配列を持つ最新のCでは、が配列の場合は配列表記が望ましいと思います。1次元配列の場合、次のようなことができます。

int myfunct(size_t size, int array[size]) {
  ... array[i] ..
}

そして二次元のために

int myfunct(size_t size, int array[size][size]) {
  ... array[i][j] ..
}

したがって、配列表記は全体像にはるかによく適合します。洗練されたコンパイラーは境界チェックを行うことさえできますが、これを行うものはまだありません。

于 2013-01-13T08:31:07.107 に答える
0

私の意見では、関数プロトタイプで空の配列表記よりもポインター表記を好む主な理由は、後者が構造体の定義と一致していないことです。

struct person {
   char *firstname;
   char *lastname;
};

void setperson(struct person *p, char firstname[], char lastname[])
{
    p->firstname = firstname;
    p->lastname = lastname;
}

構造体では、とにかくポインタ表記を使用する必要があります。これは、空の配列表記は、少なくともC99以降、最後のメンバーを柔軟な配列メンバーにしたい場合にのみ有効であるためです。

于 2019-09-27T08:04:21.077 に答える
-1

多次元配列には、配列表記を使用するだけで済みます。(最初の次元のサイズを指定する必要はありません)。

于 2013-01-12T23:32:31.883 に答える