配列がデータ型であると言うとき、これは正確にはどういう意味ですか?
データ型は、定義済みの特性を持つ値を持つデータのセットです。データ型の例: 整数、浮動小数点数、文字、文字列、ポインター
配列は、すべて同じ名前と同じ型を持つという事実によって関連付けられたメモリ位置のグループです。
なぜ配列が変更できないのか疑問に思っているなら、私が今まで読んだ中で最も良い説明は次のとおりです。
Cは、デニス・リッチーの心から完全に形成されたわけではありません。これは、B (BCPL から派生した) として知られる初期の言語から派生したものです。1 B は「型のない」言語でした。整数、浮動小数点数、テキスト、レコードなどの異なる型はありませんでした。代わりに、すべてが固定長の単語または「セル」(本質的には符号なし整数) でした。メモリは、セルの線形配列として扱われました。次のように、B で配列を割り当てた場合
auto V[10];
コンパイラは 11 個のセルを割り当てました。配列自体の 10 個の連続したセルに加えて、最初のセルの位置を含む V にバインドされたセル:
+----+
V: | | -----+
+----+ |
... |
+----+ |
| | <----+
+----+
| |
+----+
| |
+----+
| |
+----+
...
Ritchie がstruct
C に型を追加していたとき、彼はこの配置が彼にいくつかの問題を引き起こしていることに気付きました。たとえば、ファイルまたはディレクトリ テーブルのエントリを表す構造体型を作成したいと考えていました。
struct {
int inumber;
char name[14];
};
彼は、この構造がエントリを抽象的な方法で記述するだけでなく、実際のファイル テーブル エントリのビットを表すことも望んでいました。これには、配列内の最初の要素の位置を格納するための余分なセルや単語がありませんでした。そこで彼はそれを取り除きました - 最初の要素のアドレスを格納する別の場所を確保する代わりに、配列式が評価されるときに最初の要素のアドレスが計算されるように C を書きました。
これが、次のようなことができない理由です
int a[N], b[N];
a = b;
と の両方がそのコンテキストのポインター値a
に評価されるためです。と同等です。配列の最初の要素のアドレスを実際に格納するメモリはありません。コンパイラは、変換フェーズで単純に計算します。 b
3 = 4
1. これはすべてThe Development of the C Languageという論文からの抜粋です。
詳細については、この回答をお読みください。
編集:より明確にするために; 変更可能な左辺値、変更不可能な左辺値、および右辺値 (要するに) の違い。
これらの種類の式の違いは次のとおりです。
- 変更可能な左辺値は、アドレス指定可能 (単項 & のオペランドにすることができます) および代入可能 (= の左オペランドにすることができます) です。
- 変更不可能な左辺値はアドレス可能ですが、割り当て可能ではありません。
- r値は、アドレス可能でも代入可能でもありません。