要約
ここまで、このコースのデータはどれも自分の変数に、自分の名前で住んできた。しかし同じ型の多くのデータ、たとえば一週間の気温は、一つひとつが別の名前をもっていてはループで走査できない。このレッスンでは、コースで最初のデータ構造である添字付きの列を紹介する。同じ型の要素がメモリ上の隣り合う位置に並び、零から番号が振られたものである。現代の C++ では std::array で書き、その大きさはコンパイル時に固定される。その宣言、添字の型 std::size_t、そして二つの走査、すなわち添字による走査と範囲 for 文による走査を学ぶ。単元全体を支配する規則も定める。添字は 0 から大きさ引く一までの間にあれば有効であり、ループ内の各アクセスでは、その有効性を不変条件で正当化する。規則が守られないと何が起こるか、すなわち未定義動作を示し、[] と範囲チェック付きアクセス .at() を比べる。最後に、他人のコードを読むために C 言語の配列を紹介する。
学習目標
std::arrayを宣言し、初期化し、添字と範囲for文で走査できる。- ループの不変条件によって、各アクセスで添字が範囲内にあることを正当化できる。
- 規格が検査しない
[]によるアクセスと、つねに検査される.at()によるアクセスを区別し、それぞれがどんなときに適切かを説明できる。 - C 言語の配列を使ったコードを読み、
std::arrayと比べたときの欠点を説明できる。
添字付きの列
多くのデータに一つの名前
ここまでに学んだことで一週間の気温の平均を計算するなら、monday、tuesday、と続けて sunday までの七つの変数と、七項の和が必要になる。一年分の気温なら変数は 365 個になり、どんなループもそれらを走査できない。ループの本体では変数の名前はつねに同じだからである。足りないのは、全体に対する一つの名前と、各要素に対する一つの番号であり、その番号をループが進める変数にできればよい。
添字付きの列とは、まさにそれである。同じ型の 個の要素の集まりで、メモリの隣り合う区画に次々と格納され、その位置によって指定される。この位置を添字という。数学はこの対象を知っている。有限数列 であり、そこで は位置 にある要素を表す。あるいはベクトルであり、コース「代数と幾何 I」のベクトルがそれにあたる。C++ では a[i] と書き、添字には任意の整数式を使える。2、i、i + 1 などである。
なぜ零からなのか
C++ では、現在の大多数の言語と同じく、最初の要素の添字は 0、最後の要素の添字は である。理由は気まぐれな取り決めではなく、要素を見つける方法にある。列がメモリのある番地から始まり、各要素が バイトを占めるなら、添字 の要素は、先頭の番地に を足した番地にある。したがって添字はオフセット、つまり最初の要素から数えて飛び越すべき要素の個数である。最初の要素は自分自身から飛び越し零回の位置にある。
ここから、この単元全体を支配する定義が導かれる。 個の要素の列において、添字 が有効であるのは のとき、かつそのときに限る。右側の不等式は狭義であり、列を扱うときに最も多い誤り、すなわち1 ずれのエラーの源になる。 と書いてしまうこと(正しくは )、あるいは 1 から始めてしまうこと(正しくは 0 から)である。 に等しい添字は最後の要素を指すのではなく、列の直後にあって列に属さない区画を指す。
コンテンツを読み込んでいます…