
C言語基礎|ビットとCHAR_BIT
C言語で変数を「箱」だとすると、その箱の中身は 0 と 1 の並び(ビット)です。
つまり、数値も文字も、最終的にはビット列として保存されています。
ここで最初に押さえたいのはこの2つ。
- ビット(bit):0 か 1 のどちらかを表す最小単位
- char は “最低でも” 8ビット(でも 何ビットかは処理系依存)
そこで登場するのが CHAR_BIT です。
これは「この環境の char は何ビットでできてる?」を教えてくれる定数(マクロ)になります。

ビットって何?(C的なイメージ)
Cの世界では、ビットはざっくりこう捉えると分かりやすいです。
- 2種類の状態(0/1)を区別できる最小単位
- ビット1個ずつにアドレスが付いていなくてもOK(ビット単位で直接参照できなくてもOK)
- 0 以外にすることを **セット(set)**と呼ぶ
図:箱の中はビット列

この図は「中身は0/1の並び」というイメージを作るためのものです。
次に、この“並びの本数”が重要になります。
CHAR_BIT:char の箱は何ビット?
CHAR_BIT は <limits.h> に定義されていて、意味はこれです。
1バイト(= char 1個)が何ビットか
CHAR_BIT の意味
| 名前 | 意味 | どこで定義される |
|---|---|---|
| CHAR_BIT | 1バイトに含まれるビット数 | <limits.h> |
例として、もし CHAR_BIT が 8 なら、
- char の箱は 8ビット
- 0/1 の組み合わせは 2^8 = 256通り
となり、unsigned char なら 0~255 が表せる、という話につながります。
図:CHAR_BIT = 8 のときの char

この図は「CHAR_BIT 個のビットの束が char 1個」という関係を示しています。
値の範囲と CHAR_BIT の関係(なぜ重要?)
char のビット数が増えれば、表現できる値の種類も増えます。
ビット数と表現できる値の数
| ビット数 | 表現できるパターン数 | unsigned の範囲(例) |
|---|---|---|
| 8 | 2^8 = 256 | 0 ~ 255 |
| 9 | 2^9 = 512 | 0 ~ 511 |
| 16 | 2^16 = 65536 | 0 ~ 65535 |
この表が言いたいのは、char の範囲が処理系依存なのは、そもそも char のビット数が処理系依存だからってことです。
sizeof 演算子:箱の大きさを調べる
Cでは sizeof(char) は必ず 1 と決め打ちされています。
ただしこの 1 は「1バイト」であって、「8ビット」とは限りません。
(8ビットが多いけど、規格上は CHAR_BIT で決まる)
sizeof の役割
| 書式 | 意味 |
|---|---|
| sizeof(型名) | その型が何バイトか |
| sizeof 変数名 | その変数が何バイトか |
そして int 系のサイズは環境依存です。ただし順序関係は決まっています。
int系のサイズ関係
| 関係 | 意味 |
|---|---|
| sizeof(short) ≤ sizeof(int) ≤ sizeof(long) ≤ sizeof(long long) | 右側ほど同じか大きい |
さらに、符号付きと符号無しでサイズは同じです。
signed/unsigned でサイズは同じ
| 例 | 成立する関係 |
|---|---|
| short と unsigned short | sizeof(short) = sizeof(unsigned short) |
| int と unsigned | sizeof(int) = sizeof(unsigned) |
サンプルプログラム
CHAR_BIT と “ビット換算したサイズ”まで一気に見えるプログラムです。
プロジェクト名:chap7-8-1 ソースファイル名:chap7-8-1.c
// この環境の 1バイトが何ビットか、各整数型が何ビットかを表示する
#include <stdio.h>
#include <limits.h>
int main(void)
{
puts("=== ビット数チェック ===");
printf("1バイトのビット数 (CHAR_BIT) = %d\n", CHAR_BIT);
printf("char : %zu バイト = %zu ビット\n", sizeof(char), sizeof(char) * CHAR_BIT);
printf("short : %zu バイト = %zu ビット\n", sizeof(short), sizeof(short) * CHAR_BIT);
printf("int : %zu バイト = %zu ビット\n", sizeof(int), sizeof(int) * CHAR_BIT);
printf("long : %zu バイト = %zu ビット\n", sizeof(long), sizeof(long) * CHAR_BIT);
printf("long long : %zu バイト = %zu ビット\n", sizeof(long long), sizeof(long long) * CHAR_BIT);
return 0;
}このプログラムは、
- CHAR_BIT で「1バイト=何ビット?」を確認し
- sizeof で「何バイト?」を確認し
- 掛け算して「何ビット?」まで見える
という流れをまとめて確認できます。
登場する命令の書式と「何をするか」
#include
- 書式:#include <ヘッダ名>
- 何をする:ライブラリ関数やマクロ定義を取り込む
<stdio.h>:puts / printf を使う
<limits.h>:CHAR_BIT を使う
puts
- 書式:puts(文字列);
- 何をする:文字列を表示して改行する(見出し向き)
printf
- 書式:printf(書式文字列, 値, ...);
- 何をする:値を指定した形式で表示する
sizeof(演算子)
- 書式:sizeof(型名) / sizeof 変数名
- 何をする:型や変数の大きさ(バイト数)を得る
- ポイント:sizeof(char) は必ず 1
%zu(printf の書式指定)
- 何をする:sizeof の結果(size_t 型)を表示するための指定
- つまり %d ではなく %zu を使うのが安全、という話につながります
図でまとめ:バイトとビットの関係
図:1バイトは CHAR_BIT 個のビット

この図は「バイトはビットの束」であることを示しています。
だから、型のビット数は「sizeof(型) * CHAR_BIT」で求められます。
