【2026年8月最新】C言語の配列完全ガイド|宣言・初期化・ポインタ・多次元配列・Claude Code活用法
C言語を学び始めると、早い段階で「配列」に出会います。配列は同じ型の複数の値を一つの変数名でまとめて管理できるデータ構造です。C言語の配列を理解することは、ポインタ・文字列・動的メモリ確保を学ぶための基礎にもなります。
しかしC言語の配列にはいくつかの落とし穴があります。境界外アクセスによるメモリ破壊、配列のコピー時の注意点(=演算子では値がコピーされない)、ポインタとの密接な関係など、初心者が躓きやすいポイントが多くあります。
この記事ではC言語の配列に関する全知識を体系的に解説します。さらにClaude Codeを使ってC言語の配列処理コードを自動生成する方法も紹介します。
01 C ARRAY BASICS C言語の配列とは?変数との違いとメモリの仕組み 配列はメモリ上の連続した領域に値を並べたデータ構造
C言語の配列は、同じ型のデータが連続したメモリ領域に並んで格納されるデータ構造です。例えば「int arr[5]」と宣言すると、メモリ上に int型(4バイト)×5個 = 20バイトの連続した領域が確保されます。
📚 用語解説
配列(Array):C言語で同じ型の複数の値をメモリ上の連続した領域に格納するデータ構造。「arr[0]」「arr[1]」のように添字(インデックス)で各要素にアクセスする。添字は0から始まる(0始まり)。C言語の配列はポインタと密接に関係しており、配列名はその配列の先頭要素のアドレスを表すポインタとして機能する。
| 比較項目 | 通常の変数(int a;) | 配列(int arr[5];) |
|---|---|---|
| 格納できる値の数 | 1つだけ | 宣言した要素数(5つ) |
| アクセス方法 | 変数名(a) | 変数名+インデックス(arr[0]〜arr[4]) |
| メモリ上の配置 | 任意の場所 | 連続したアドレスに配置 |
| インデックス | なし | 0から始まる整数 |
| ループとの相性 | 毎回変数名を変える必要あり | インデックス変数をループで変化させて処理 |
配列のメモリ上の配置を理解することは、ポインタ演算を学ぶ準備にもなります。int型配列 arr[5] の場合、arr[0]のアドレスを仮に0x1000とすると、arr[1]は0x1004、arr[2]は0x1008…と4バイトずつ増加して連続します。
02 DECLARE INIT 配列の宣言・初期化・代入の方法 3つのパターンを使い分けてC言語の配列を正しく初期化する
2-1. 宣言と要素ごとの代入
最も基本的な方法です。まず配列を宣言し、後から各要素に個別に値を代入します。
#include <stdio.h>
int main() {
int arr[5]; /* 5要素のint型配列を宣言 */
/* 各要素に値を代入 */
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr[3] = 40;
arr[4] = 50;
printf("arr[0] = %d\n", arr[0]); /* 10 */
printf("arr[4] = %d\n", arr[4]); /* 50 */
return 0;
}
2-2. 宣言と同時に初期化(初期化子リスト)
宣言と同時に中括弧{}で値を与える方法(初期化子リスト)です。要素数を省略すると、与えた値の数が自動的に要素数になります。
#include <stdio.h>
int main() {
/* 方法1: 要素数を指定して初期化 */
int arr1[5] = {10, 20, 30, 40, 50};
/* 方法2: 要素数を省略(自動で5要素になる) */
int arr2[] = {10, 20, 30, 40, 50};
/* 方法3: 一部だけ初期化(残りは0になる) */
int arr3[5] = {10, 20}; /* arr3[2]〜arr3[4]は0 */
/* 方法4: 全要素を0で初期化 */
int arr4[5] = {0};
printf("%d\n", arr1[2]); /* 30 */
printf("%d\n", arr3[2]); /* 0 */
printf("%d\n", arr4[4]); /* 0 */
return 0;
}
初期化子リストで要素数を省略する(int arr[] = {10, 20, 30};)と、値の個数が自動的に要素数になります。後から要素を追加しても要素数を手動で変更しなくて済むため、保守しやすいコードになります。ただし、宣言後に追加代入する場合は要素数を明示する必要があります。
int arr[5];と宣言だけして値を代入せずにアクセスすると、そのメモリ領域にある不定の値(ゴミ値)が返されます。これは重大なバグの原因になります。配列を宣言したら必ず初期化するか、使う前に必ず値を代入してください。全要素を0にしたい場合は「int arr[5] = {0};」が最も安全です。
03 POINTER ARRAY ポインタと配列の関係:アドレスアクセス 配列名はポインタとして機能する——C言語の核心的な概念を解説
C言語で配列を理解するうえで欠かせない知識が「配列名はその先頭要素のアドレスを表すポインタとして機能する」という事実です。
📚 用語解説
ポインタ(Pointer):C言語でメモリのアドレス(番地)を格納する変数。「int *p;」で整数型を指すポインタpを宣言する。配列名はポインタとして機能するため、「int arr[5]」の場合、arrとだけ書くと配列の先頭要素(arr[0])のアドレスを指すポインタになる。*(arr+1)はarr[1]と同じ意味になる(ポインタ演算)。
#include <stdio.h>
int main() {
int arr[5] = {10, 20, 30, 40, 50};
/* 配列名はポインタ(先頭要素のアドレス)として機能 */
printf("arr = %p\n", arr); /* 先頭アドレス */
printf("&arr[0] = %p\n", &arr[0]); /* 同じアドレス */
/* ポインタ演算でのアクセス(arr[1]と*(arr+1)は同じ) */
printf("arr[1] = %d\n", arr[1]); /* 20 */
printf("*(arr+1) = %d\n", *(arr+1)); /* 20(同じ) */
/* ポインタ変数に配列を代入 */
int *p = arr;
printf("p[2] = %d\n", p[2]); /* 30 */
printf("*(p+2) = %d\n", *(p+2)); /* 30(同じ) */
return 0;
}
配列名とポインタの関係を整理します。
| アクセス方法 | 意味 | 使う場面 |
|---|---|---|
| arr[i] | 添字を使った標準的な配列アクセス | 通常の配列操作(読みやすい) |
| *(arr + i) | ポインタ演算(arr[i]と同義) | ポインタ操作を意識する場面 |
| int *p = arr; p[i] | ポインタ変数経由のアクセス | 関数引数で配列を受け取る場合 |
| &arr[i] | 配列のi番目要素のアドレスを取得 | 要素のアドレスを別の関数に渡す場合 |
04 ARRAY COPY 配列のコピー:浅いコピーと深いコピー(memcpy) =演算子では配列はコピーされない——memcpyとstrncpyを使う理由
C言語で配列をコピーしたい場面はよくありますが、=演算子では配列の内容はコピーできません。これはC言語を学ぶ人が必ず躓くポイントです。
📚 用語解説
memcpy(メモリコピー関数):C言語の標準ライブラリ(string.h)の関数。「memcpy(コピー先, コピー元, バイト数)」の形で使い、指定したバイト数分のメモリを丸ごとコピーする。配列のコピーに使う場合、バイト数は「sizeof(型) * 要素数」で計算する。文字列(char配列)のコピーにはstrncpy関数が安全。
#include <stdio.h>
#include <string.h>
int main() {
int src[5] = {10, 20, 30, 40, 50};
int dst[5];
/* NG: =演算子では配列の値はコピーされない */
/* dst = src; コンパイルエラーになる */
/* OK: memcpyを使った正しいコピー */
memcpy(dst, src, sizeof(int) * 5);
/* コピーされているか確認 */
for (int i = 0; i < 5; i++) {
printf("dst[%d] = %d\n", i, dst[i]);
}
/* 出力: 10 20 30 40 50 */
/* srcを変更してもdstは変わらない(独立したコピー) */
src[0] = 999;
printf("dst[0]はそのまま: %d\n", dst[0]); /* 10 */
return 0;
}
浅いコピーと深いコピーの違いも整理しておきましょう。
| コピーの種類 | 説明 | C言語での実現 | 注意点 |
|---|---|---|---|
| 浅いコピー(Shallow Copy) | ポインタ変数のみコピー(同じメモリを参照) | int *p = arr; (ポインタのコピー) | 片方を変更するともう片方も変わる |
| 深いコピー(Deep Copy) | メモリ上の値を新たな領域にコピー | memcpy(dst, src, サイズ) | 独立したコピーが作られる |
05 CHAR ARRAY 文字列を配列で扱う方法(char配列) NULL終端文字の仕組みとprintf・scanf・strncpyの正しい使い方
C言語では文字列を扱うための専用の型がなく、char型の配列(char配列)を使って文字列を表現します。C言語の文字列処理を理解するには「NULL終端文字」の概念が不可欠です。
📚 用語解説
NULL終端文字(\0):C言語の文字列が終わりを示す特別な文字。文字コードが0(ゼロ)の文字で、「\0」と書く。char型の配列で文字列を扱う場合、文字の後に必ず\0が付く。例:「Hello」を格納するには char str[6] = "Hello"; が必要(5文字 + \0 = 6バイト)。\0のぶんを忘れると文字列操作関数がメモリ境界を越えてしまう危険がある。
#include <stdio.h>
#include <string.h>
int main() {
/* 文字列の初期化方法1: 文字列リテラルで初期化 */
char str1[10] = "Hello"; /* H-e-l-l-o-\0 で6バイト使用 */
/* 文字列の初期化方法2: 文字配列で個別に指定 */
char str2[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
/* 表示 */
printf("str1 = %s\n", str1); /* Hello */
printf("str2 = %s\n", str2); /* Hello */
/* 文字列の長さ(\0を除いた文字数) */
printf("長さ: %zu\n", strlen(str1)); /* 5 */
/* 文字列のコピー(strcpyではなくstrncpyが安全) */
char dst[10];
strncpy(dst, str1, sizeof(dst) - 1);
dst[sizeof(dst) - 1] = '\0'; /* 安全のため末尾にNULLを明示 */
printf("コピー: %s\n", dst); /* Hello */
return 0;
}
"Hello"という5文字の文字列を格納するには、char str[6](5文字 + \0終端文字)が必要です。char str[5]と宣言してしまうと\0が入らず、printf等の文字列関数が正しく動作しない危険があります。また、strcpy関数ではバッファオーバーフローの危険があるため、セキュリティ観点からstrncpy(コピーする最大バイト数を指定できる)を使うことが推奨されます。
06 SIZEOF ELEMENT 配列の要素数をsizeofで取得する方法 sizeof(配列名) / sizeof(配列名[0])で要素数を動的に計算する
C言語では配列の要素数を動的に取得するための関数はなく、sizeof演算子を使って計算します。「sizeof(配列名) / sizeof(配列名[0])」が定番のパターンです。
📚 用語解説
sizeof演算子:C言語で変数や型のバイトサイズを返す演算子。sizeof(int)は環境によって4、sizeof(char)は1、sizeof(double)は8など。配列全体に対して使うとバイト総量が返るため、「配列の要素数 = sizeof(arr) / sizeof(arr[0])」で計算できる。ただし、関数に配列をポインタとして渡した後でsizeofを使っても要素数は得られない(ポインタのサイズが返るため)。
#include <stdio.h>
int main() {
int arr[] = {10, 20, 30, 40, 50};
/* sizeof(配列全体)でバイト総量を取得 */
printf("配列全体のバイト数: %zu\n", sizeof(arr)); /* 20(int 4バイト × 5要素)*/
/* sizeof(要素1つ)で1要素のバイト数を取得 */
printf("1要素のバイト数: %zu\n", sizeof(arr[0])); /* 4 */
/* 要素数の計算 */
int count = sizeof(arr) / sizeof(arr[0]);
printf("要素数: %d\n", count); /* 5 */
/* 要素数を使ったループ(ハードコードを避ける) */
for (int i = 0; i < count; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
return 0;
}
実際のC言語のコードでは「#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))」というマクロを定義して使うことが多いです。ARRAY_SIZE(arr)と書くだけで要素数が取得でき、コードの可読性が上がります。
07 ARRAY FUNCTION 関数の引数に配列を渡す方法 配列はポインタとして渡される——要素数を別に渡す必要がある理由
C言語で配列を関数の引数に渡すと、配列の値がコピーされるのではなく、先頭要素のポインタ(アドレス)が渡されます。これは重要な仕様で、関数内で配列の要素を変更すると、呼び出し元の配列も変更されます。
#include <stdio.h>
/* 配列を受け取る関数(int *arr または int arr[]と書く) */
void printArray(int arr[], int size) {
/* 注意: ここでsizeof(arr)を使うとポインタのサイズ(8バイト)が返る */
/* 要素数は引数のsizeを使う必要がある */
for (int i = 0; i < size; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
}
/* 配列の全要素を合計する関数 */
int sumArray(int arr[], int size) {
int total = 0;
for (int i = 0; i < size; i++) {
total += arr[i];
}
return total;
}
int main() {
int data[] = {10, 20, 30, 40, 50};
int size = sizeof(data) / sizeof(data[0]);
/* 配列と要素数を一緒に渡す(サイズを別引数で渡すのが慣習)*/
printArray(data, size);
printf("合計: %d\n", sumArray(data, size)); /* 150 */
return 0;
}
配列を関数の引数に渡した後、関数内でsizeof(arr)を使っても配列全体のサイズは得られません。ポインタのサイズ(64bit環境では8バイト)が返るだけです。関数内で要素数が必要な場合は、必ず要素数を別の引数(int size)として渡す必要があります。これはC言語を学ぶ人が最もよく誤解するポイントの一つです。
int arr[5] = {10,...}
呼び出し元で初期化
sizeof(arr)/sizeof(arr[0])
呼び出し元でカウント
printArray(arr, size)
配列名+要素数を渡す
arr[]をポインタとして受け取り
sizeでループ範囲を制御
08 MULTIDIM ARRAY 多次元配列の宣言と使い方 行×列の2次元配列を使った行列・表形式データの処理を解説
C言語では2次元・3次元など多次元の配列を扱えます。2次元配列は行と列を持つ表形式のデータに対応し、数学の行列や画像データの処理にも使われます。
#include <stdio.h>
int main() {
/* 2次元配列の宣言: [行数][列数] */
int matrix[3][4] = {
{1, 2, 3, 4}, /* 0行目 */
{5, 6, 7, 8}, /* 1行目 */
{9, 10, 11, 12} /* 2行目 */
};
/* 2重ループで全要素を処理 */
int rows = 3;
int cols = 4;
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
printf("%3d", matrix[r][c]);
}
printf("\n");
}
/* 特定の要素にアクセス */
printf("matrix[1][2] = %d\n", matrix[1][2]); /* 7 */
return 0;
}
| 次元数 | 宣言方法 | 使用シーン | 注意点 |
|---|---|---|---|
| 1次元配列 | int arr[5] | リスト・数列 | 最もよく使う |
| 2次元配列 | int arr[3][4] | 行列・表・画像ピクセル | メモリは行優先で連続配置 |
| 3次元配列 | int arr[2][3][4] | 立体データ・RGB画像 | ネストが深くなり複雑 |
09 CLAUDE CODE C Claude CodeでC言語の配列コードを自動生成する C言語の複雑な配列処理もAIに依頼すれば数分で完成
C言語の配列はポインタ・メモリ管理・NULL終端など、覚えることが多く、コードを書き慣れるまで時間がかかります。2026年現在、Claude Codeを使えばC言語の配列処理コードを自然言語で指示して自動生成できます。
| あなたの指示 | Claude Codeが生成するもの |
|---|---|
| 「5つのintを格納する配列を宣言して全要素を合計するC言語コード」 | 宣言・初期化・ループ・合計処理のCコード(コンパイル可能) |
| 「整数配列を引数で受け取り最大値と最小値を返すC言語関数」 | ポインタ引数で複数値を返す関数のコード |
| 「このCコードのsegmentation faultの原因を教えて(コードを貼り付け)」 | バッファオーバーフローやNULL参照などのバグ原因の説明と修正 |
| 「3×4の2次元配列を引数に受け取って各行の合計を表示するC言語コード」 | 2次元配列・関数引数・ループ処理のCコード |
C言語の配列もClaude Codeで効率的に学べます
「C言語の配列でエラーが出て解決できない」「ポインタと配列の関係が理解できない」——こうしたC言語の課題はClaude Codeで解決できます。コードを見せるだけでエラーの原因と修正方法を説明してくれます。
まずは無料相談で、プログラミング学習・業務自動化の課題をヒアリングさせてください。
NEXT STEP
この記事の内容を、あなたのビジネスで
実践してみませんか?
よくある質問
Q. C言語で配列を宣言・初期化する方法を教えてください。
A. C言語の配列宣言は「int arr[5];」(5要素のint型配列)です。初期化は宣言と同時に「int arr[5] = {10, 20, 30, 40, 50};」と書きます。要素数を省略して「int arr[] = {10, 20, 30};」と書くと自動で3要素の配列になります。全要素を0にしたい場合は「int arr[5] = {0};」が最も簡単です。宣言後に個別に代入する場合は「arr[0] = 10; arr[1] = 20;」のように書きます。
Q. C言語で配列をコピーする方法は?=演算子では駄目なのですか?
A. はい、C言語では「dst = src;」のように=演算子で配列をコピーすることはできません(コンパイルエラーになります)。配列のコピーにはmemcpy関数(string.hをinclude)を使います。「memcpy(dst, src, sizeof(int) * 要素数)」の形で書きます。文字列(char配列)のコピーにはstrncpy関数が安全です。
Q. C言語で配列の要素数を取得するには?
A. C言語には配列の要素数を返す組み込み関数がないため、sizeof演算子で計算します。「sizeof(arr) / sizeof(arr[0])」で要素数を取得できます。ただし、この方法は配列変数に対してのみ有効です。関数の引数として受け取った配列(ポインタとして渡される)に対してsizeofを使っても正しい要素数は返りません。関数に配列を渡す場合は、要素数を別の引数として渡す必要があります。
Q. C言語の配列とポインタの関係を教えてください。
A. C言語では配列名はその先頭要素のアドレスを表すポインタとして機能します。「int arr[5]」の場合、arrと書くだけでarr[0]のアドレスを指すポインタになります。そのため「int *p = arr;」と書いてポインタ変数pに配列を代入できます。また「arr[i]」と「*(arr+i)」は同じ意味です。関数に配列を渡すときもポインタとして渡されるため、関数内で配列の要素を変更すると呼び出し元の配列も変更されます。
Q. C言語のchar配列で文字列を扱う方法を教えてください。
A. C言語には文字列専用の型がなく、char型の配列で文字列を表現します。「char str[10] = "Hello";」と書くと、文字列Helloの後にNULL終端文字(\0)が自動で付いた配列が作られます。配列のサイズはNULL終端文字分+1バイト以上が必要です。文字列のコピーにはstrncpy(dst, src, sizeof(dst)-1)を使い、末尾に手動でNULLを付けると安全です。
Q. C言語の2次元配列の使い方を教えてください。
A. 2次元配列は「int arr[行数][列数]」で宣言します。例えば「int matrix[3][4]」は3行4列のint型配列です。初期化は「{{1,2,3,4},{5,6,7,8},{9,10,11,12}}」のように行ごとに中括弧で区切ります。アクセスは「matrix[行][列]」の形で行います。全要素を処理するには2重forループを使います。関数に2次元配列を渡す場合は「void func(int arr[][4], int rows)」のように列数を明示する必要があります。
Q. C言語の配列コードをClaude Codeで生成できますか?
A. できます。「5要素のint配列を宣言して全要素の合計を出力するC言語コード」のように日本語で説明するだけで、コンパイル可能なCコードが生成されます。segmentation fault等のエラーメッセージと問題のコードを貼り付けて「原因と修正方法を教えて」と依頼する使い方も効果的です。
Claude Codeで業務自動化を90日で叩き込む
経営者向けの伴走型パーソナルトレーニング
AI鬼管理/AI社員AIKATAへのお問い合わせ
この記事を読んで気になった方へ。
専門スタッフが、御社に最適な
業務自動化・業務代行プランを無料でご提案します。




