C言語の配列における主な制限とは?特徴と注意点を解説
配列(Array)とは、同じ型の要素を固定サイズで連続的に格納できるデータ構造の一種です。配列はデータの集合を扱うために使われますが、実用上は「同じ型を持つ変数の集合」として考えると理解しやすくなります。
配列の主な制限
C言語の配列には、以下のような制限があります。
同種のデータしか格納できない: 配列は均質(homogeneous)な構造です。int型の配列には整数値のみ、float型の配列には浮動小数点数のみ、char型の配列には文字のみを格納できます。1つの配列に異なるデータ型の値を混在させることはできません。
宣言時にサイズ指定が必須かつ定数であること: 配列を宣言するときはサイズの指定が必須で、そのサイズは定数でなければなりません。このため、実際に必要なデータ量とのずれにより、メモリ不足やメモリの無駄遣いが発生します。
要素の挿入・削除にシフト処理が必要: 配列内の要素を挿入または削除する際は、後続の要素を移動(シフト)させる必要があります。
境界チェックが行われない: C言語では、配列に入力された値が配列のサイズを超えているかどうかを自動的に検査できません。
範囲外へのデータ書き込み: 添字(インデックス)を指定して入力されたデータが配列のサイズを超えると、そのデータは配列の外側、つまり他のデータ領域やプログラム本体の領域に書き込まれてしまいます。
予測不能な結果とエラー通知の欠如: 範囲外への書き込みは、少なくとも予測できない結果を招きます。さらに、配列サイズを超えたことを知らせるエラーメッセージも一切表示されません。最悪の場合、プログラムがハングアップ(停止状態)することもあります。
そのため、次のようなプログラムは意図しない結果を生む可能性があります。
int a[10],i; for(i=0;i<=20;i++) a[i]=i;
このコードでは、10個分の領域しか持たない配列 a に対して21回の代入(i = 0〜20)を行っているため、配列の境界を超える書き込み(バッファオーバーラン)が発生してしまいます。
サンプルプログラム
以下は、2つの配列の対応する要素同士を加算し、その合計を表示するC言語のプログラムです。
#include<stdio.h>
void main(){
// コンパイル時初期化による配列の宣言 //
int array1[5],array2[5],sum[5];
// 変数の宣言 //
int i;
// forループを使って入力と出力を処理 //
printf("Enter the values of array1 :\n");
for(i=0;i<5;i++){
printf("array1[%d] : \n",i);
scanf("%d",&array1[i]);
}
printf("Enter the values of array2 :\n");
for(i=0;i<5;i++){
printf("array2[%d] :\n",i);
scanf("%d",&array2[i]);
}
printf("Elements in the sum of array1 and array2 are:\n ");
for(i=0;i<5;i++){
sum[i]=array1[i]+array2[i];
printf("%d ",sum[i]);
}
}
なお、現代のC標準(C99以降)では、main関数は int main(void) として宣言し、末尾で return 0; を返すことが推奨されています。
実行結果
上記のプログラムを実行すると、次のような出力が得られます。
Enter the values of array1 : array1[0] :2 array1[1] :3 array1[2] :1 array1[3] :2 array1[4] :3 Enter the values of array2 : array2[0] :4 array2[1] :5 array2[2] :3 array2[3] :2 array2[4] :1 Elements in the sum of array1 and array2 are: 6 8 4 4 4
このように配列は非常に便利なデータ構造である一方、サイズが固定であることや境界チェックが行われないといった制限を持つため、使用時には添字の範囲に十分注意する必要があります。
-
C言語のシフト演算とは?左シフト・右シフト・補数の基本をわかりやすく解説
問題 C言語を使用して、ある数値に対する左シフト・右シフト・補数(ビット反転)を求める簡単なプログラムを作成するには、どのようにすればよいのでしょうか。 解決方法 左シフト(<<) 変数の値を1ビットだけ左へシフトすると、その値は2倍になります。「a × 2」を計算したのと同じ結果です。 例:a = 10 の場合、a << 1 = 20 右シフト(>>) 変数の値を1ビットだけ右へシフトすると、その値は元の半分になります。「a ÷ 2」の整数除算と同じ結果です。 例:a = 10 の場合、a >> 1 = 5 サンプルプログラム 以下は、シ
-
C言語の探索アルゴリズム解説|線形探索と二分探索の違いと実装例
探索(サーチ)とは、複数の要素で構成されるリストの中から、目的の「キー」となる要素を見つけ出す処理のことです。 リストの中に指定した要素が存在すれば、その探索は「成功」とみなされます。 指定した要素がリストに存在しなければ、その探索は「失敗(不成功)」となります。 C言語で広く使われている代表的な探索手法は、主に次の2つです。 線形探索(Linear Search/リニアサーチ) 二分探索(Binary Search/バイナリサーチ) 線形探索(Linear Search)とは 線形探索は、リストの先頭から順に要素を1つずつ取り出し、キーと一致するかどうかを確認していく、最も基本的な探