C言語でプログラムを書く上で、最初に必ず理解しておきたいのが変数です。
値を一時的に保存したり、計算の結果を扱ったりするために欠かせない存在であり、変数を正しく使えるかどうかでプログラムの質が大きく変わります。
本記事では、C言語の変数について、型・宣言・初期化という3つの基本から、初心者がつまずきやすいポイントまで、図解を交えながら丁寧に解説していきます。
C言語の変数とは何か
変数の基本概念と役割

C言語における変数(variable)とは、メモリ上に確保された値を入れるための「名前付きの箱」のことです。
プログラムは処理の途中で、計算結果や入力された値を一時的に保存したり、何度も参照したりする必要があります。
そのときに使われるのが変数です。
例えば、次のようなC言語のコードを考えます。
#include <stdio.h>
int main(void) {
int x; // 整数を入れる箱(変数x)を用意
x = 10; // 箱xに10を代入
printf("%d\n", x); // 箱xの中身を表示
return 0;
}
このプログラムでは、xという名前の箱を用意し、その中に10という値を入れています。
printfは、その箱の中身を取り出して表示しているだけです。
ここで重要なのは、変数は「名前」と「値」と「型」をセットで考えるという点です。
- 名前 … 人間が識別するためのラベル(例:
x,score) - 値 … 実際にメモリに保存されるデータ(例: 10, 3.14, ‘A’)
- 型 … どのようなデータかを示す情報(例:
int,double,char)
C言語では、型を必ず指定して変数を宣言するというルールがあります。
これが、後で扱う「変数宣言」の基本です。
変数名のルールと注意点

変数には必ず変数名が必要です。
C言語では、変数名の付け方にいくつかルールがあります。
変数名の基本ルール
C言語の変数名は、次のルールを満たす必要があります。
- 英文字(A~Z、a~z)、数字(0~9)、アンダースコア(_)のみ使用できる
- 最初の文字に数字は使えない
- 大文字と小文字は区別される(例:
valueとValueは別の変数) - 予約語(キーワード)は使えない(例:
int,for,ifなど)
具体例を表にまとめます。
| 種類 | 例 | 説明 |
|---|---|---|
| 使用できる | score | 英文字だけのシンプルな名前 |
| 使用できる | user_age | アンダースコアで単語を区切った名前 |
| 使用できる | total3 | 最初が英字で途中に数字を含む |
| 使用できない | 1abc | 最初の文字が数字 |
| 使用できない | int | C言語のキーワード(予約語) |
| 使用できない | a-b | マイナス記号(-)は使用できない |
読みやすい変数名の付け方
文法的に正しければ何でもよいわけではなく、意味がわかりやすい変数名を付けることが大切です。
例えば、テストの点数ならscoreやtest_score、商品の合計金額ならtotal_priceのように、「中身が何か」を名前から想像できるようにします。
また、C言語ではuserAgeのように途中を大文字で区切る(camelCase)か、user_ageのようにアンダースコアで区切る(snake_case)ことがよくあります。
プロジェクト内でどちらかに統一すると、コードが読みやすくなります。
C言語の基本的なデータ型
整数型(int・short・long)の特徴

C言語では、整数を扱うための基本的な型としてshort、int、longなどがあります。
これらは整数型と呼ばれ、小数点を含まない値だけを表現します。
整数型の主な違いは、メモリ上で使用するバイト数と、表現できる値の範囲です。
一般的な32ビット環境では、次のようになっていることが多いです(実際の値は環境やコンパイラで異なる可能性があります)。
| 型 | よくあるサイズ | おおよその範囲(符号付き) |
|---|---|---|
short | 2バイト | 約 -32,768 ~ 32,767 |
int | 4バイト | 約 -2,147,483,648 ~ 2,147,483,647 |
long | 4または8バイト | 環境に依存 |
また、整数型にはsigned(符号付き)とunsigned(符号なし)のバリエーションがあります。
signed int… マイナスもプラスも扱える(通常のintと同じ)unsigned int… 0以上の値だけを扱う代わりに、上限が2倍近くまで増える
例えば、個数や人数のように絶対にマイナスにならない値を扱う場合は、unsigned intを使うと意図が明確になります。
実数型(float・double)の特徴

実数型は、小数点を含む数値(例えば3.14や0.001など)を扱うための型です。
C言語では、主にfloatとdoubleが使われます。
| 型 | よくあるサイズ | 特徴 |
|---|---|---|
float | 4バイト | 単精度浮動小数点数。メモリ使用量が少ないが、精度はやや低い |
double | 8バイト | 倍精度浮動小数点数。より高精度で、多くの計算に推奨される |
実数型は浮動小数点数と呼ばれ、内部的には指数表現(例: 1.23 × 10^4)のような形式で扱われます。
そのため、ごく一部の小数は正確に表現できず、わずかな誤差が生じることがあります。
例えば、次のようなコードを考えます。
#include <stdio.h>
int main(void) {
double a = 0.1;
double b = 0.2;
double c = a + b;
printf("a + b = %.20f\n", c); // 小数点以下20桁まで表示
return 0;
}
a + b = 0.30000000000000004441
見た目には0.3のはずですが、内部表現の関係で正確な0.3にならない場合があります。
このような性質があるため、金額計算などで厳密な精度が必要な場合は整数型で扱うなどの工夫が必要になります。
文字型(char)と文字コードの基本

char型は、1文字を扱うための型です。
ただし、内部的には整数として文字コードを保存しているという点が重要です。
典型的な環境では、1バイト(8ビット)のcharに0~255の数値(または-128~127)が格納され、その数値が文字コードと解釈されます。
ASCIIコードでは、例えば次のような対応があります。
| 文字 | ASCIIコード(10進) |
|---|---|
'A' | 65 |
'B' | 66 |
'a' | 97 |
'0' | 48 |
文字リテラルは'A'のようにシングルクォートで囲みます。
一方、文字列リテラル(複数文字)は"ABC"のようにダブルクォートで囲みます。
ここは初心者が混同しやすいので注意が必要です。
#include <stdio.h>
int main(void) {
char c = 'A'; // 文字'A'を表すchar
int code = c; // charをintに代入(文字コードになる)
printf("c = %c\n", c); // 文字として表示
printf("code = %d\n", code); // 整数(文字コード)として表示
return 0;
}
c = A
code = 65
このように、charは小さな整数型でもあり、同時に文字を表す型でもあると理解しておくと、C言語の文字処理がわかりやすくなります。
型のサイズと範囲の確認方法

C言語の型は、プラットフォームやコンパイラによってサイズが異なる場合があります。
そのため、正確なサイズや範囲を知りたいときは、sizeof演算子やlimits.hなどのヘッダを使って確認する方法が有効です。
sizeof演算子でサイズを確認する
sizeofは、型や変数が何バイトの大きさかを返す演算子です。
返り値の型はsize_tという無符号整数型です。
#include <stdio.h>
int main(void) {
printf("sizeof(char) = %zu\n", sizeof(char));
printf("sizeof(short) = %zu\n", sizeof(short));
printf("sizeof(int) = %zu\n", sizeof(int));
printf("sizeof(long) = %zu\n", sizeof(long));
printf("sizeof(float) = %zu\n", sizeof(float));
printf("sizeof(double)= %zu\n", sizeof(double));
return 0;
}
sizeof(char) = 1
sizeof(short) = 2
sizeof(int) = 4
sizeof(long) = 8
sizeof(float) = 4
sizeof(double)= 8
環境が変わるとlongのサイズなどが異なることがあります。
このように、自分の環境で一度確認しておくとよいです。
limits.hとfloat.hで範囲を確認する
整数型の最小値・最大値はlimits.h、浮動小数点型の情報はfloat.hで定義されています。
例えばINT_MIN、INT_MAXなどの定数を使うことができます。
#include <stdio.h>
#include <limits.h>
#include <float.h>
int main(void) {
printf("INT_MIN = %d\n", INT_MIN);
printf("INT_MAX = %d\n", INT_MAX);
printf("FLT_MIN = %e\n", FLT_MIN); // floatの最小正値
printf("FLT_MAX = %e\n", FLT_MAX); // floatの最大値
return 0;
}
INT_MIN = -2147483648
INT_MAX = 2147483647
FLT_MIN = 1.175494e-38
FLT_MAX = 3.402823e+38
このように、型のサイズや範囲は「推測」ではなく「実測」することが大切です。
C言語の変数宣言と初期化の基本
変数宣言の書き方と文法

C言語で変数を使うには、まず宣言が必要です。
宣言では、「この名前の変数を、どの型として使うか」をコンパイラに伝えます。
基本的な書き方は次の通りです。
型名 変数名;
例えば、整数型の変数scoreを宣言するなら次のように書きます。
int score;
複数の変数を同じ型で宣言する場合は、カンマで区切ります。
int a, b, c; // 3つのint型変数を宣言
注意すべき点として、変数は使う前に必ず宣言しなければならないというルールがあります。
C99以降では、ブロック内の任意の場所で宣言できますが、「使う直前で宣言する」と覚えておくとよいです。
変数の初期化

初期化(initialization)とは、変数を宣言すると同時に初期の値を与えることです。
C言語では、次のように書きます。
int x = 10; // 宣言と同時に10を代入(初期化)
double pi = 3.14; // 実数型の初期化
char c = 'A'; // 文字型の初期化
初期化を行わないと、ローカル変数の中身は「不定値」(何が入っているかわからない状態)になり、後から使用したときに予測不能な動作を引き起こします。
この点は後ほど詳しく扱いますが、可能な限り宣言と同時に初期化する習慣を付けることがとても重要です。
同時宣言・同時初期化のパターン

C言語では、1つの型に対して複数の変数を同時に宣言・初期化できます。
int a = 1, b = 2, c = 3; // 3つを同時に宣言・初期化
double x = 1.0, y, z = 2.5; // yだけ初期化なし
ここで注意したいのは、型名は最初の1回しか書かれていないという点です。
つまりint a = 1, b = 2;は、int a = 1; int b = 2;と等価です。
逆にint a = 1, double b = 2.0;のように、intとdoubleを同じ行に混ぜて書くことはできません。
型が違う場合は、行を分けるなどして宣言します。
const変数(定数)の宣言と使いどころ

constは、一度値を設定したら変更しないという約束事をコンパイラに伝えるためのキーワードです。
いわゆる定数として使います。
書き方は次の通りです。
const int TAX_RATE = 10; // 消費税率(%)を表す定数
const double PI = 3.14159; // 円周率
constを付けた変数に、後から代入しようとするとコンパイルエラーになります。
#include <stdio.h>
int main(void) {
const int TAX_RATE = 10;
// TAX_RATE = 8; // これはコンパイルエラーになる
printf("税率は%d%%です\n", TAX_RATE);
return 0;
}
税率は10%です
constを使う主なメリットは次の通りです。
- ミスによる書き換えを防げる
- 意味のある名前を付けられるので、コードが読みやすくなる
- 「この値は変わらない」という意図を明確に伝えられる
例えば3.14159や10といった数字を直接コードに書くのではなく、PIやTAX_RATEのような名前を付けたconst変数を使うことで、「マジックナンバー」を避けることができます。
初心者がつまずきやすいポイントと対策
未初期化変数の危険性と防ぎ方

ローカル変数(関数の中で宣言した変数)は、初期化をしない限り中身が不定です。
これは、「たまたまメモリに残っていた適当な値をそのまま使ってしまう」ことを意味します。
#include <stdio.h>
int main(void) {
int x; // 初期化していない
printf("%d\n", x); // 何が表示されるかわからない
return 0;
}
このプログラムはコンパイル自体は通りますが、実行すると毎回違う値が表示されたり、予測不能な挙動になったりします。
これは典型的なバグの原因です。
対策はシンプルで、必ず初期値を与えることです。
#include <stdio.h>
int main(void) {
int x = 0; // 0で初期化
printf("%d\n", x); // 毎回0が表示される
return 0;
}
特に、forループのカウンタや合計値を入れる変数などは、初期化忘れによるバグが非常に多いので、「宣言と同時に初期化するクセを付ける」ことが大切です。
型変換(暗黙の型変換・キャスト)の基本

C言語では、異なる型同士の値を計算・代入するときに、型変換(type conversion)が行われます。
型変換には大きく2種類あります。
- 暗黙の型変換 … プログラマが明示しなくても自動で行われる変換
- 明示的な型変換(キャスト) … プログラマが
(int)などと書いて指定する変換
暗黙の型変換の例
#include <stdio.h>
int main(void) {
int a = 3;
double b = 2.5;
double c = a + b; // aが自動的にdoubleに変換されてから計算される
printf("c = %f\n", c);
return 0;
}
ここではaがint、bがdoubleですが、計算時には「より表現力の高い型(double)に合わせる」というルールに従って、自動的にaがdoubleに変換されます。
キャスト(明示的な型変換)の例
込み入った計算では、意図的に型変換を行いたい場面があります。
そのときに使うのがキャストです。
#include <stdio.h>
int main(void) {
int a = 5;
int b = 2;
double c1 = a / b; // int同士の割り算 → 結果もint(2) → doubleに変換されて2.0
double c2 = (double)a / b; // aだけdoubleにキャスト → doubleとintの計算 → 2.5
printf("c1 = %f\n", c1);
printf("c2 = %f\n", c2);
return 0;
}
c1 = 2.000000
c2 = 2.500000
この例では、c1はa / bがint同士で計算されるため、結果が2になってからdoubleに変換されています。
一方、c2では(double)aとbの計算になるため、2.5という期待通りの結果になります。
このように、どのタイミングでどの型に変換されるかを意識することが、C言語の数値計算では非常に重要です。
スコープ(有効範囲)とローカル変数・グローバル変数

変数にはスコープ(scope)と呼ばれる有効範囲があります。
どこからその変数が使えるか、という概念です。
C言語では主にローカル変数とグローバル変数の2種類を理解しておく必要があります。
ローカル変数
ローカル変数は、関数の中やブロックの中で宣言された変数です。
その変数は、宣言されたブロックの中でしか使えません。
#include <stdio.h>
int main(void) {
int a = 10; // main関数のローカル変数
{
int b = 20; // ブロック内のローカル変数
printf("a = %d, b = %d\n", a, b);
}
// printf("%d\n", b); // エラー: bはこの位置からは見えない
return 0;
}
bは内側の{ }の中で宣言されているため、そのブロックの外では存在しないことになります。
グローバル変数
グローバル変数は、どの関数の外でも宣言されている変数です。
ファイル全体(さらには他のファイルからも)から参照できるようになります。
#include <stdio.h>
int global_var = 100; // グローバル変数
void func(void) {
printf("global_var in func = %d\n", global_var);
}
int main(void) {
printf("global_var in main = %d\n", global_var);
func(); // 別の関数からも同じ変数にアクセスできる
return 0;
}
global_var in main = 100
global_var in func = 100
グローバル変数はどこからでも参照できて便利に見えますが、どこからでも書き換えられてしまうため、プログラムが複雑になるほどバグの原因になります。
そのため、基本的にはローカル変数を使い、グローバル変数は最小限に抑えることが推奨されます。
まとめ
C言語における変数は、型・宣言・初期化という3つの要素を理解することで、ぐっと扱いやすくなります。
整数型・実数型・文字型といった基本的なデータ型の特徴を把握し、自分の環境でsizeofやlimits.hを使ってサイズや範囲を確認しておくことも大切です。
また、未初期化変数を避ける、型変換の仕組みを意識する、スコープを踏まえてローカル変数を中心に設計する、といったポイントを押さえれば、安定したCプログラムを書けるようになります。
まずは本記事の内容を参考に、実際に小さなプログラムで変数を試しながら学習を進めてみてください。
