元の質問:私が定義すると:
const int z[5] = {10, 11, 12, 13, 14};
それはどういう意味ですか?
OR
編集:
より詳しい情報:
別の変数があります:
const int *y = z;
func((int *) y);
ここで、funcは次のように定義されています。
void func(int y[]) {
int i;
for(i = 0; i < 5; i++) {
y[i] = i; //y[i] can be set to any integer; used i as example
}
}
funcでは、yを使用して配列が走査され、各要素が変更されます。 zのすべての要素がconstであっても、これは有効ですか?
これは、z
の各要素が読み取り専用であることを意味します。
オブジェクトz
は、ポインターオブジェクトではなく配列オブジェクトです。それは何も指し示していない。他のオブジェクトと同様に、z
のアドレスはその存続期間中は変化しません。
objectz
は配列なので、expressionz
は、すべてではないがほとんどのコンテキストで、z[0]
を指すポインター式に暗黙的に変換されます。配列オブジェクトz
全体のアドレスと同様に、そのアドレスはオブジェクトの存続期間中は変化しません。この「変換」は、式の意味に対するコンパイル時の調整であり、実行時の型変換ではありません。
配列とポインターの(しばしば混乱する)関係を理解するには、 comp.lang.c FAQ のセクション6を読んでください。
「定数」とconst
は2つの異なるものであることを理解することが重要です。何かがconstantの場合、コンパイル時に評価されます。たとえば、42
および(2+2)
は定数式です。
オブジェクトがconst
キーワードで定義されている場合、それは読み取り専用であり、定数である必要はありません。これは、オブジェクトを名前で変更することはできず、他の方法で(たとえば、アドレスを取得して非constポインターにキャストすることによって)変更しようとすると、未定義の動作が発生することを意味します。たとえば、次のことに注意してください。
const int r = Rand();
有効です。 r
は読み取り専用ですが、その値は実行時まで判別できません。
- Zの各要素は定数です。つまり、それらの値は変更できません。
配列はオブジェクトであり、実行時にのみ作成でき、const
エンティティはコンパイル時に解決されるため、const
配列を作成することはできません。
したがって、const
は、以下の最初の例のように解釈されます。つまり、配列の要素に適用されます。つまり、以下は同等です。 あなたの例の配列は初期化する必要があります。
int const z[5] = { /*initial (and only) values*/};
const int z[5] = { /*-//-*/ };
const
の例では、int
指定子と型指定子の型 可換プロパティ です。
以下は、定数の使用法を明確にするためのいくつかの例です。
1.定数整数の定義:(再割り当てできません)。以下の2つの式では、const
の使用は同等です。
int const a = 3; // after type identifier
const int b = 4; // equivalent to before type qualifier
2.定数ポインターの定義(ポインター演算や再割り当てはできません):
int * const p = &anInteger; // non-constant data, constant pointer
定数int
へのポインター定義(ポイントされた整数の値は変更できませんが、ポインターは変更できます):
const int *p = &anInteger; // constant data, non-constant pointer