2012-05-11 1 views
9

は、ここでサンプルプログラムです:長さのデータを破棄した場合のCの配列構文のポイントは何ですか?

#include <stdio.h> 

void foo(int b[]){ 
    printf("sizeof in foo: %i\n", sizeof b); 
} 

int main(){ 
    int a[4]; 
    printf("sizeof in main: %i\n", sizeof a); 
    foo(a); 
} 

出力は次のとおりです。

sizeof in main: 16 
sizeof in foo: 8 

質問は、それが単なる関数境界での標準的なポインタに変換されます場合は、その構文のポイントは何でしょう、ですか?

+0

サイズがあらかじめわかっている場合は、 'void foo(int b [4])'を宣言できます。 – Kevin

+3

@Kevinそれでは違いはありませんが、4以外の長さの配列を 'foo'に引き渡すことができます。長さ4の配列だけを許可したいなら 'foo'は' void foo(int(* b)[4]) 'でなければなりません。 – Praetorian

答えて

12
  1. それはシンタックスシュガーです:void foo(int b[])はそれが本当にポインタであるにも関わらず、bが配列(というよりも、単一の外のパラメータ)として使用されようとしていることを示唆しています。

  2. 左端がearly versions of Cです。ここで、接頭辞[]はポインタ宣言の構文です。

+0

+1砂糖は常に良い – Mehrdad

+14

@Mehrdad:必ずしもそうではありません。 Syntactic sugarはセミコロンの癌を引き起こす。 –

+1

@larsmansあなたは合成構文的な砂糖を考えています。 http://en.wikipedia.org/wiki/Synthetic_programming –

0

質問は、それが単なる関数境界での標準的なポインタに変換されます場合は、その構文のポイントは何でしょう、ですか?

この場合、引数として配列を渡しているので、Cは与えられたアドレスへのポインタを作成していますが、本当に興味深いのは、スタックに配列を割り当てたときそこに使ってください。

このようにすると、コンパイラはその配列のロードステートメントをポインタとオフセットに変換せず、スタックベース+オフセットに直接アクセスできます。とにかくポインタを格納するのは意味がありません。

しかし、その配列を渡すと、コンパイラは配列の基底のアドレスを関数に渡します。ポインタとして渡します。

要するに、[]はポインタ演算をよりうまくやってくれます。配列を宣言する場合、配列を最適化することができます。なぜなら、配列はポインタではなく、特定の状況ではポインタを介してアクセスされます(他のポインタではありません)。

関連する問題