変数とデータ型
変数はラベルの付いた箱のようなものです——箱には名前と型があり、正しい種類のものしか入れられません。違うものを入れるとトラブルになります。
変数とは
変数はプログラム内でデータを格納するための名前付きメモリ位置です。箱に例えると:
- 変数名:箱のラベル、見つけるためのもの
- データ型:箱に入れられるものの種類
- 変数の値:箱の中身
- メモリアドレス:倉庫の中での箱の位置
変数の宣言と初期化
変数の宣言
変数を宣言するとコンパイラに「箱が必要です。名前と型はこれです」と伝えます:
int age;
float weight;
char blood_type;
宣言直後、変数の値は未定義(ゴミ値)です——そのメモリ位置に残っていたランダムなデータが入っています。未初期化の変数は絶対に使わないでください!
変数の初期化
初期化とは、宣言と同時に変数に初期値を与えることです:
int age = 20;
float weight = 65.5f;
char blood_type = 'A';
先に宣言、後で代入
宣言してから後で代入することもできます:
int age;
age = 20;
結果は同じですが、2 段階に分けると宣言と代入の間で未初期化のまま変数を誤って使ってしまうリスクが高まります。
同じ型の変数をまとめて宣言
int a = 1, b = 2, c = 3;
変数の命名規則
C言語には変数名に関する厳格な規則があります:
守らなければならないこと:
- 英字(a-z、A-Z)、数字(0-9)、アンダースコア(_)のみ使用可能
- 英字またはアンダースコアで始める必要がある——数字で始められない
- C言語のキーワード(
int、return、ifなど)は使用不可 - 大文字と小文字は区別される(
Ageとageは別の変数)
守るべきこと:
- 名前に意味を持たせる:
scではなくstudent_countを使う - snake_case スタイル(小文字 + アンダースコア)を使う
- 二重アンダースコアで始まる名前(
__countなど)は避ける——コンパイラが内部で使用 - 長すぎる名前は避ける(31 文字を超えるとコンパイラがサポートしない場合がある)
| 名前 | 有効? | 備考 |
|---|---|---|
age |
有効 | 短くて意味が明確 |
_count |
有効 | アンダースコアで始まる |
student_name |
有効 | snake_case スタイル |
2nd_place |
無効 | 数字で始まる |
my-score |
無効 | ハイフンを含む(減算と解釈される) |
int |
無効 | キーワード |
Age |
有効だが非推奨 | 先頭大文字は通常型名に予約 |
基本データ型
C言語のデータ型は、変数が占めるメモリ量、値の範囲、データの解釈方法を決定します。C99 の基本データ型は次の通りです:
整数型
| 型 | サイズ(バイト) | 代表的な範囲 | フォーマット指定子 |
|---|---|---|---|
char |
1 | -128 ~ 127 | %c または %d |
unsigned char |
1 | 0 ~ 255 | %u |
short |
2 | -32768 ~ 32767 | %hd |
unsigned short |
2 | 0 ~ 65535 | %hu |
int |
4 | -2147483648 ~ 2147483647 | %d |
unsigned int |
4 | 0 ~ 4294967295 | %u |
long |
4 または 8 | プラットフォーム依存 | %ld |
unsigned long |
4 または 8 | プラットフォーム依存 | %lu |
long long |
8 | -9223372036854775808 ~ 9223372036854775807 | %lld |
int で十分です。より大きな範囲が必要なときは long long を、文字には char を使いましょう。最近のプラットフォームでは int が short と同じくらい効率的なため、short はあまり使われません。
int が 4 バイトとしていますが、これは最近のプラットフォームでの話です。C言語の規格は int を最低 2 バイトとしか要求していません。実際のサイズはプラットフォームに依存します——sizeof で確認してください。
浮動小数点型
| 型 | サイズ(バイト) | 有効桁数 | 絶対値の範囲 | フォーマット指定子 |
|---|---|---|---|---|
float |
4 | 6-7 | 1.2e-38 ~ 3.4e38 | %f |
double |
8 | 15-16 | 2.2e-308 ~ 1.8e308 | %lf |
long double |
8 以上 | 18+ | プラットフォーム依存 | %Lf |
浮動小数点数は精度が限られており、すべての小数を正確に表せるわけではありません。例えば:
float f = 0.1f;
printf("%.20f\n", f);
0.10000000149011611938
0.1 は 2 進数で無限に循環する小数のため、float では正確に格納できません。これは浮動小数点表現の本質的な特性であり、バグではありません。
double を使いましょう。精度が高く、最近の CPU では float と同じ速度です。メモリに制約がある組み込みシステムでのみ float を優先してください。
文字型
char 型は本質的に 1 バイトの整数で、通常は文字の格納に使います。文字はメモリ上では ASCII コードとして格納されます:
char ch = 'A';
printf("%c\n", ch);
printf("%d\n", ch);
A
65
'A' の ASCII コードは 65 です。%c で文字として出力し、%d で整数値として出力します。これは C言語では文字と整数が相互に変換可能であることを示しています。
'A' は文字(単一引用符)、"A" は文字列(二重引用符、末尾に \0 が付く)です。これらは全く異なるもの——絶対に混同しないでください。
_Bool型
C99 では _Bool 型が導入され、0 と 1 のみ格納できます。<stdbool.h> をインクルードすると bool、true、false が使えます:
#include <stdbool.h>
bool is_valid = true;
bool is_empty = false;
sizeof演算子
sizeof は C言語のキーワード(関数ではない)で、データ型や変数が占めるバイト数を返します:
例
#include <stdio.h>
int main(void) {
printf("char: %zu bytes\n", sizeof(char));
printf("short: %zu bytes\n", sizeof(short));
printf("int: %zu bytes\n", sizeof(int));
printf("long: %zu bytes\n", sizeof(long));
printf("long long: %zu bytes\n", sizeof(long long));
printf("float: %zu bytes\n", sizeof(float));
printf("double: %zu bytes\n", sizeof(double));
return 0;
}
char: 1 bytes
short: 2 bytes
int: 4 bytes
long: 4 bytes
long long: 8 bytes
float: 4 bytes
double: 8 bytes
sizeof は size_t 型を返し、そのフォーマット指定子は %zu です。コンパイラが %zu をサポートしていない場合(古いバージョンなど)は、代わりに %lu を使ってください。
sizeof は変数にも使えます:
int age = 20;
printf("%zu\n", sizeof(age));
フォーマット出力の詳細
整数のフォーマット
int n = 42;
printf("10 進数: %d\n", n);
printf("8 進数: %o\n", n);
printf("16 進数(小文字): %x\n", n);
printf("16 進数(大文字): %X\n", n);
printf("8 進数(プレフィクス付き): %#o\n", n);
printf("16 進数(プレフィクス付き): %#x\n", n);
10 進数: 42
8 進数: 52
16 進数(小文字): 2a
16 進数(大文字): 2A
8 進数(プレフィクス付き): 052
16 進数(プレフィクス付き): 0x2a
浮動小数点のフォーマット
double pi = 3.141592653589793;
printf("デフォルト: %f\n", pi);
printf("小数点以下 2 桁: %.2f\n", pi);
printf("小数点以下 8 桁: %.8f\n", pi);
printf("科学的記数法: %e\n", pi);
printf("幅 12.2f: [%12.2f]\n", pi);
デフォルト: 3.141593
小数点以下 2 桁: 3.14
小数点以下 8 桁: 3.14159265
科学的記数法: 3.141593e+00
幅 12.2f: [ 3.14]
型の値の範囲
C言語の標準ライブラリには、各型の範囲を問い合わせるためのヘッダファイルが用意されています:
limits.h(整数型)
#include <limits.h>
printf("int の最小値: %d\n", INT_MIN);
printf("int の最大値: %d\n", INT_MAX);
printf("char の最大値: %d\n", CHAR_MAX);
よく使うマクロ:
| マクロ | 意味 |
|---|---|
INT_MIN |
int の最小値 |
INT_MAX |
int の最大値 |
CHAR_MIN |
char の最小値 |
CHAR_MAX |
char の最大値 |
LONG_MAX |
long の最大値 |
LLONG_MAX |
long long の最大値 |
float.h(浮動小数点型)
#include <float.h>
printf("float の有効桁数: %d\n", FLT_DIG);
printf("double の有効桁数: %d\n", DBL_DIG);
printf("float の最大値: %e\n", FLT_MAX);
例
#include <stdio.h>
#include <limits.h>
#include <float.h>
int main(void) {
char ch = 'Z';
int num = 100;
float f = 3.14f;
double d = 2.718281828;
printf("char '%c' = ASCII %d, サイズ = %zu\n", ch, ch, sizeof(ch));
printf("int %d, サイズ = %zu, 範囲 = [%d, %d]\n", num, sizeof(num), INT_MIN, INT_MAX);
printf("float %.6f, サイズ = %zu, 桁数 = %d\n", f, sizeof(f), FLT_DIG);
printf("double %.9f, サイズ = %zu, 桁数 = %d\n", d, sizeof(d), DBL_DIG);
return 0;
}
char 'Z' = ASCII 90, サイズ = 1
int 100, サイズ = 4, 範囲 = [-2147483648, 2147483647]
float 3.140000, サイズ = 4, 桁数 = 6
double 2.718281828, サイズ = 8, 桁数 = 15
例
#include <stdio.h>
int main(void) {
char lower = 'a';
char upper = lower - 32;
printf("小文字: %c(ASCII %d)\n", lower, lower);
printf("大文字: %c(ASCII %d)\n", upper, upper);
printf("\n数字文字:\n");
char digit = '0';
printf("文字 '%c' の ASCII コード = %d\n", digit, digit);
printf("文字 '%c' の数値 = %d\n", digit, digit - '0');
return 0;
}
小文字: a(ASCII 97)
大文字: A(ASCII 65)
数字文字:
文字 '0' の ASCII コード = 48
文字 '0' の数値 = 0
'0' を引けばその数値が得られます——これが文字を数値に変換する基礎です。
❓ よくある質問
📖 まとめ
- 変数は名前付きメモリ位置です。宣言時に型と名前を指定し、必ず初期化しましょう
- 名前は英字またはアンダースコアで始め、大文字小文字は区別され、キーワードは使えません
- 整数型:char(1 バイト)、short(2)、int(4)、long(4 または 8)、long long(8)
- 浮動小数点型:float(4 バイト、有効桁 6-7)、double(8 バイト、有効桁 15-16)
- sizeof は型や変数のバイトサイズを返します。limits.h と float.h が値の範囲を提供します
📝 練習問題
- sizeof を使って、自分のパソコンですべての整数型と浮動小数点型のバイトサイズを出力するプログラムを書いてください。同級生の結果と比較して一致するか確認しましょう
- 文字 'a' ~ 'z' の ASCII コードを出力するプログラムを書いてください。1 行に 5 つずつ、%-5d で整列させること
- INT_MAX + 1 の結果(整数オーバーフロー)を計算して出力し、INT_MIN と比較してなぜそうなるか考察してください



