C言語で配列を使う際、「あらかじめ要素数を決めて int arr[10]; のように宣言しなければならない」というルールに不便さを感じることはありませんか?
「実行するまでデータの個数がわからない」
こういった状況は、プログラミングにおいて頻繁に発生します。
実は、C言語でも特定の条件下であれば、要素数を指定せずに配列を宣言することが可能です。
また、ポインタとメモリ確保を組み合わせることで、実行時にサイズを自由に変えられる「動的配列」を作ることもできます。
この記事では、初期化リストを使って要素数を省略する基本的な書き方から、関数での受け渡し、さらには malloc や realloc を使って要素数を可変にする応用テクニックまで、サンプルコード付きで徹底解説します。
![]() 執筆者:マヒロ |
|
- OS:Windows 11 / macOS Sequoia
- IDE:Visual Studio / VS Code / IntelliJ IDEA
- その他:Chrome DevTools / 各言語最新安定版
※本メディアでは、上記環境にてコードの動作と情報の正確性を検証済みです。
配列の要素数を省略して宣言する(初期化時)
C言語の配列は、宣言と同時に「初期化」を行う場合に限り、角括弧 [] の中の数字(要素数)を省略することができます。
コンパイラが右辺のデータの個数を自動的に数え、その数に合わせてメモリを確保してくれるためです。
初期化子リストを使った省略記法
具体的な書き方を見てみましょう。
データの個数を数えて arr[5] と書く必要はなく、単に arr[] と記述するだけで済みます。
#include <stdio.h>
int main(void) {
// 要素数を省略して宣言(右辺の個数に合わせて自動設定される)
int numbers[] = {10, 20, 30, 40, 50};
// 配列全体のサイズ / 1つの要素のサイズ = 要素数
int count = sizeof(numbers) / sizeof(numbers[0]);
printf("要素数: %d\n", count);
for (int i = 0; i < count; i++) {
printf("numbers[%d] = %d\n", i, numbers[i]);
}
return 0;
}
実行結果
要素数: 5
numbers[0] = 10
numbers[1] = 20
numbers[2] = 30
numbers[3] = 40
numbers[4] = 50
int numbers[] = {10, 20, 30, 40, 50}; と記述することで、コンパイラは自動的に「要素数5の配列」として処理します。
この方法の最大のメリットは、初期データの個数が増減しても、宣言部分の数字を書き直す必要がない点です。
メンテナンス性が向上し、数え間違いによるバグも防ぐことができます。
要素数は sizeof(numbers) / sizeof(numbers[0]) という計算式で取得するのが定石です。
文字列(char配列)の場合
文字列を扱う場合も同様に、要素数を省略できます。文字列の場合は、末尾のヌル文字 \0 も自動的にカウントに含まれます。
char str[] = "Hello";
// char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'}; と同じ意味になる
関数の引数で要素数を指定しない書き方
関数に配列を渡す場合、受け取る側の仮引数では要素数を指定する必要がありません。
これは、C言語において関数の引数として渡される配列は、実質的に「先頭要素へのポインタ」として扱われるためです。
配列を受け取る関数の定義
#include <stdio.h>
// 要素数を指定せずに配列を受け取る
// int func(int *arr, int size) と書いても同じ
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main(void) {
int data1[] = {1, 2, 3};
int data2[] = {10, 20, 30, 40, 50};
// どちらの配列も同じ関数に渡せる
printArray(data1, 3);
printArray(data2, 5);
return 0;
}
実行結果
1 2 3
10 20 30 40 50
関数定義 void printArray(int arr[], int size) において、arr[] は要素数を持たない配列の型として記述されています。
重要なのは、この関数内では sizeof(arr) を使っても配列全体のサイズは取得できないという点です(ポインタのサイズが返ってきてしまいます)。
そのため、別途 size 引数として要素数を渡してあげる必要があります。
実行時に要素数を決める「可変長配列(VLA)」
C99規格以降(現在の主要なコンパイラでサポート)では、変数をサイズ指定に使う「可変長配列(Variable Length Array: VLA)」が利用できます。
これにより、プログラムを実行してからユーザーに入力してもらった数だけ配列を用意する、といったことが可能です。
#include <stdio.h>
int main(void) {
int n;
printf("配列のサイズを入力してください: ");
scanf("%d", &n);
// 変数 n を使って配列を宣言(VLA)
int dynamicArr[n];
// データの入力
for (int i = 0; i < n; i++) {
dynamicArr[i] = i * 10;
}
// 表示
for (int i = 0; i < n; i++) {
printf("%d ", dynamicArr[i]);
}
return 0;
}
int dynamicArr[n]; のように、コンパイル時定数ではない変数 n をサイズに指定しています。
非常に便利ですが、この配列は「スタック領域」に確保されるため、あまりに巨大なサイズ(数メガバイト以上など)を指定すると「スタックオーバーフロー」を起こしてプログラムが強制終了する危険性があります。
数万個を超えるようなデータを扱う場合は、次の malloc を使う方法が推奨されます。
自由に要素数を増減させる「動的メモリ確保(malloc/realloc)」
「最初は10個でいいけど、足りなくなったら増やしたい」といった柔軟な配列が必要な場合は、ポインタとメモリ操作関数(malloc, realloc, free)を使用します。
これこそが、C言語における真の「要素数を指定しない(可変にする)」テクニックです。
mallocとreallocを使った動的配列の実装
#include <stdio.h>
#include <stdlib.h> // malloc, realloc, free に必要
int main(void) {
int count = 0;
int capacity = 3; // 最初の容量
int input;
// 最初に3個分のメモリを確保
int *arr = (int *)malloc(sizeof(int) * capacity);
if (arr == NULL) return 1; // エラー処理
printf("数値を入力(-1で終了):\n");
while (1) {
scanf("%d", &input);
if (input == -1) break;
// 容量がいっぱいになったら拡張する
if (count >= capacity) {
capacity *= 2; // 容量を2倍にする
// メモリを再確保(拡張)してデータを移行
int *temp = (int *)realloc(arr, sizeof(int) * capacity);
if (temp == NULL) {
free(arr);
return 1;
}
arr = temp;
printf("--- 容量を %d に拡張しました ---\n", capacity);
}
arr[count] = input;
count++;
}
// 結果表示
printf("入力されたデータ: ");
for (int i = 0; i < count; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// メモリの解放(必須)
free(arr);
return 0;
}
実行結果
数値を入力(-1で終了):
10
20
30
40
--- 容量を 6 に拡張しました ---
50
-1
入力されたデータ: 10 20 30 40 50
最初は malloc で小さな領域を確保し、データが入りきらなくなったら realloc 関数を使ってメモリ領域を拡張しています。
realloc は「現在のデータを保持したまま、サイズを変更した新しい領域を確保し直す」という強力な関数です。
これにより、PythonのリストやC++のvectorのような「可変長配列」をC言語で実現できます。
使い終わった後は必ず free(arr) でメモリを解放することを忘れないでください。
C言語のスキルを活かして年収を上げる方法
以上、C言語で配列の要素数を指定しないで宣言する方法について解説してきました。
C言語を扱えるエンジニアは比較的希少価値が高く、転職によって数十万円の年収アップはザラで、100万円以上年収が上がることも珍しくありません。
なお、転職によって年収を上げたい場合は、エンジニア専門の転職エージェントサービスを利用するのが最適です。
転職エージェントも副業エージェントも、登録・利用は完全無料なので、どんな求人や副業案件があるのか気になる方は、気軽に利用してみるとよいでしょう。
| 年収アップにこだわりたい方 (平均アップ額138万円の実績) | テックゴー |
| 未経験・経験者問わず幅広く探したい方 | ユニゾンキャリア |
| 業界に精通した担当者に相談したい方 | キッカケエージェント |
| ゲーム業界への転職を志望する方 | ファミキャリ |
| エンジニア未経験からキャリアを築く方 | イーチキャリア |



