配列の可変長さについてのC言語:初心者向けガイド

こんにちは、未来のプログラマーたち!今日は、C言語における可変長配列(Variable Length Arrays、以下VLA)の世界に楽しく飛び込みます。プログラミングが初めてであっても心配しないでください。私はあなたの親切なガイドとして、すべてをステップバイステップで説明します。それでは、始めましょう!

C - Variable Length Arrays

可変長配列とは?

まず、可変長配列とは何かを理解しましょう。パーティを計画しているとしますが、どれくらいのゲストが来るか分かりません。ゲストの人数に応じて魔法のようにサイズを調整できるテーブルがあれば素晴らしいでしょう。プログラミングにおけるVLAはまさにそのようなものです!

可変長配列は、そのサイズが実行時(プログラムが動作している時)で決定される配列で、コンパイル時(プログラムが実行準備される時)では決定されません。この機能はC99標準で導入され、配列の作成に柔軟性をもたらします。

可変長配列の作成

簡単な例でVLAを作成してみましょう:

#include <stdio.h>

int main() {
int n;
printf("どれだけの数を保存したいですか? ");
scanf("%d", &n);

int numbers[n];  // これは私たちの可変長配列です

printf("%d個の数を入力してください:\n", n);
for (int i = 0; i < n; i++) {
scanf("%d", &numbers[i]);
}

printf("あなたが入力したのは: ");
for (int i = 0; i < n; i++) {
printf("%d ", numbers[i]);
}

return 0;
}

これを分解すると:

  1. ユーザーに保存したい数の個数を尋ねます。
  2. ユーザーの入力したサイズ n の配列 numbers を作成します。
  3. ループを使用して n 個の数をユーザーから入力します。
  4. 最後に、ユーザーが入力したすべての数を表示します。

これがVLAの美しいところです。コードを書いている際に配列のサイズを知る必要はありません。サイズはプログラムが実行されたときに決定されます!

二次元可変長配列

次に、レベルアップして二次元VLAを見てみましょう。ウェディングの席の配置を考えているとしますが、どれくらいのテーブルがあって、各テーブルにどれくらいの席があるか分かりません。二次元VLAが役立ちます!

以下はその例です:

#include <stdio.h>

int main() {
int tables, seats;

printf("どれだけのテーブルがありますか? ");
scanf("%d", &tables);

printf("各テーブルにどれだけの席がありますか? ");
scanf("%d", &seats);

int seating[tables][seats];  // 私たちの2D可変長配列

// 席の番号を割り当てる
for (int i = 0; i < tables; i++) {
for (int j = 0; j < seats; j++) {
seating[i][j] = i * seats + j + 1;
}
}

// 席の配置を表示する
printf("\n席の配置:\n");
for (int i = 0; i < tables; i++) {
printf("テーブル %d: ", i + 1);
for (int j = 0; j < seats; j++) {
printf("%3d ", seating[i][j]);
}
printf("\n");
}

return 0;
}

この例では:

  1. ユーザーにテーブルの数と各テーブルの席の数を尋ねます。
  2. サイズが [tables][seats] の2D VLA seating を作成します。
  3. 席の番号を各位置に割り当てます。
  4. 最後に、席の配置を表示します。

この柔軟性により、実行時に決定される任意のサイズの席の配置を作成できます!

ジャグジー配列

さて、もっと面白いところに進みましょう。ウェディングの各テーブルが異なる数の席を持っている場合を考えます。そこで登場するのがジャグジー配列です。各サブ配列が異なる長さを持つ配列です。

C言語はジャグジー配列を直接サポートしていませんが、VLAとポインタを使用してシミュレートできます。以下はその方法です:

#include <stdio.h>
#include <stdlib.h>

int main() {
int tables;
printf("どれだけのテーブルがありますか? ");
scanf("%d", &tables);

int *seats = malloc(tables * sizeof(int));
int **seating = malloc(tables * sizeof(int*));

// 各テーブルの席の数を入力する
for (int i = 0; i < tables; i++) {
printf("テーブル %d にどれだけの席がありますか? ", i + 1);
scanf("%d", &seats[i]);
seating[i] = malloc(seats[i] * sizeof(int));
}

// 席の番号を割り当てる
for (int i = 0; i < tables; i++) {
for (int j = 0; j < seats[i]; j++) {
seating[i][j] = j + 1;
}
}

// 席の配置を表示する
printf("\n席の配置:\n");
for (int i = 0; i < tables; i++) {
printf("テーブル %d: ", i + 1);
for (int j = 0; j < seats[i]; j++) {
printf("%3d ", seating[i][j]);
}
printf("\n");
}

// 配割り当てたメモリを解放する
for (int i = 0; i < tables; i++) {
free(seating[i]);
}
free(seating);
free(seats);

return 0;
}

この例は少し複雑ですが、以下を分解すると:

  1. テーブルの数の配列 seats を作成し、各テーブルの席の数を格納します。
  2. ポインタの配列 seating を作成してジャグジー配列をシミュレートします。
  3. 各テーブルに応じてメモリを動的に割り当てます。
  4. 席の番号を割り当て、配置を表示します。
  5. 最後に、割り当てたメモリを解放します。

このアプローチにより、各テーブルが異なる数の席を持つことができます。非常に柔軟です!

メソッドの表

ここで使用したメソッドの簡単な参照表を示します:

メソッド 説明
scanf() ユーザーからの形式された入力を読み取る scanf("%d", &n);
printf() コンソールに形式された出力を表示する printf("Hello, %s!", name);
malloc() 動的にメモリを割り当てる int *arr = malloc(n * sizeof(int));
free() 動的に割り当てたメモリを解放する free(arr);

力には責任が伴います。VLAと動的メモリ割り当ては強力なツールですが、スタックオーバーフローやメモリリークを避けるために注意深く使用する必要があります。

そして、ここまででC言語の可変長配列についての初めてのステップを踏み出しました。実践が大事ですので、これらの概念を試してみてください。ハッピーコーディング!

Credits: Image by storyset