
C言語基礎|size_t型とtypedef宣言
sizeof の正体、ちゃんと知ってる?―size_t と typedef を押さえると、型の不安がスッと消える。
size_t型とtypedef宣言って何のためにあるの?
C言語でサイズを調べるとき、みんな大好き sizeof が登場しますよね。
ところがここに、初学者がよくハマる“地味だけど重要”なポイントがあります。
- sizeof が返す値は 符号無し整数
- でも、その「具体的な型」が unsigned なのか unsigned long なのかなどは 処理系(環境)次第
つまり、A環境では unsigned、B環境では unsigned long…みたいに変わり得るんです。
これだと「sizeof の結果を受け取る変数は何型にすべき?」がブレますよね。
そこで登場するのが size_t です。
size_t は <stddef.h> などで、だいたい次のように typedef 宣言されています(例)
typedef unsigned long size_t; /* 例:実際は環境によって変わる */これにより、どの環境でも
- sizeof が返す型は size_t
と言い切れるようになります。
この「環境依存の差を吸収して、共通の名前で呼べるようにする」役が typedef の大事なお仕事です。

まず押さえる:typedef は“新しい型”を作らない
typedef はよく「型を作る」と誤解されますが、やっているのは 別名(あだ名)を付けることだけです。
typedef の基本ルール
既存の型 A に、別名 B を付ける
typedef A B;
この結果、B は 型名として使えるようになります。
でも中身はあくまで A のままです。新種の型が増えたわけではありません。
size_t と typedef の役割
| 項目 | 何をするもの? | うれしいこと |
|---|---|---|
| sizeof | 型や変数の大きさ(バイト数)を得る | 何バイトかを安全に調べられる。 |
| size_t | sizeof の結果を表すための型名 | 環境差を吸収して共通の書き方にできる。 |
| typedef | 既存の型に別名を付ける宣言 | 読みやすさUP/環境依存を隠せる。 |
この表のポイントはここです。
size_t は typedef で作られた“別名”で、sizeof の結果を受け取るための共通の呼び名。
size_t が必要になる理由を、もう一段わかりやすく
ありがちな悩み
「sizeof の結果って、unsigned で受け取ればよくない?」
→ それが よくない場合があるんです。
環境によって sizeof の型が違うので、受け取り側の型を固定するとズレる可能性があります。
例:環境が違うとこうなり得る
環境A:sizeof の型 = unsigned
環境B:sizeof の型 = unsigned long
環境C:sizeof の型 = unsigned long long
でも全部まとめて size_t という名前で呼べるようにする
つまり size_t は“橋渡し役”です。
「sizeof の型は環境によって違うけど、size_t って呼べばOK」にしてくれます。
書式(命令の書式)をきっちり:typedef の書き方
typedef 宣言の書式
- 基本形:
typedef 既存の型名 新しい別名;
例:
typedef unsigned long size_t;
typedef int Score;
typedef unsigned char u8;
何をする命令なの?
- typedef は 型に別名を付ける宣言
- 変数を作ったり、メモリ確保をしたりはしません
- “読みやすさ”と“移植性(環境差への強さ)”を上げます
printf で size_t を出すときのルール(ここ大事)
size_t は unsigned 系のどれか、という立ち位置なので、printf で出すときは 専用の書式指定を使います。
- size_t を表示する書式指定:%zu
(z は size_t 用の修飾子、u は unsigned 系、というイメージです)
サンプルプログラム
配列の要素数と全体サイズを確認するプログラムです。
プロジェクト名:chap7-9-1 ソースファイル名:chap7-9-1.c
#include <stdio.h>
#include <stddef.h>
int main(void)
{
int numbers[] = {10, 20, 30, 40, 50};
size_t total_bytes = sizeof(numbers);
size_t one_bytes = sizeof(numbers[0]);
size_t count = total_bytes / one_bytes;
puts("配列のサイズを確認してみよう!");
printf("配列全体のバイト数 = %zu\n", total_bytes);
printf("要素1個のバイト数 = %zu\n", one_bytes);
printf("要素数(計算結果) = %zu\n", count);
return 0;
}このプログラムで使っている要素の説明
| 書き方 | 意味 | 結果の型 |
|---|---|---|
| sizeof(numbers) | 配列全体のバイト数 | size_t |
| sizeof(numbers[0]) | 要素1個のバイト数 | size_t |
| total_bytes / one_bytes | 要素数(割り算で求める) | size_t(計算結果として) |
図のイメージ

この図が言っているのは、
- 配列は「同じ型の要素が並ぶ箱の列」
- 全体サイズを1要素サイズで割ると要素数が出る
という超定番テクです。
まとめ:今日のゴール
- sizeof の結果は size_t 型
- size_t は 環境依存の unsigned 系型に typedef で別名を付けたもの
- typedef は 新しい型を作らず、別名を与える
- size_t を printf するなら %zu
