C言語基礎|sizeof演算子の使い方

sizeof は「何バイト?」を聞く最強の物差し。―でも、書き方を間違えると“別のもの”を測っちゃう!

C言語で型や変数の大きさ(バイト数)を知りたいとき、登場するのが sizeof 演算子です。
配列の要素数を求めたり、構造体(12章で解説)のサイズを確認したり、メモリ確保の計算をしたり…使い道がめちゃくちゃ多い、超重要パーツですね。

ただ、sizeof は 書き方が2種類あって、さらに 括弧の有無や演算子の優先順位で意味が変わることがあります。
ここを最初にスッキリ整理しておくと、後の学習がかなりラクになります。

sizeof の2つの書き方

sizeof には次の2形式があります。

A:sizeof(型名)

  • 括弧は必須(型名を直接書くときは必ず必要)

B:sizeof 式

  • 式(変数、定数、計算式など)を対象にする
  • 括弧は不要(ただし付けた方が安全で読みやすい)

表で整理

形式書き方対象括弧
Asizeof(型名)型そのもの必須sizeof(int)
Bsizeof 式変数・定数・計算結果など任意(推奨)sizeof(x), sizeof(x + 1)

何をする演算子?(一言でいうと)

sizeof は、指定した対象が 何バイトの大きさかを調べる演算子です。
結果はバイト数で、型は size_t になります(表示は printf で %zu が定番です)。

重要:sizeof(式) は「式の型」を見ている

sizeof(式) は、式を実行して値を計算しているわけではなく、基本的に その式の型が何になるかを見て、その型のサイズを返します。

たとえば…

  • int + int は int
  • int + double は double
  • char + 1 は(整数拡張で)int になりやすい。

という「型の昇格・変換」に引っ張られて、sizeof の結果も変わります。

図でイメージ:sizeof が見ているもの

(あくまでイメージ図です)

注意:演算子の優先順位で意味が変わる(超重要)

例:sizeof n+2 はどう解釈される?

sizeof n+2 は、たいてい次のように解釈されます。

  • sizeof n が先に評価されて、その結果に + 2 する
    つまり (sizeof n) + 2 になる

一方、sizeof(n+2) は、

  • n+2 という式の型(たいてい int)を見て、そのサイズを返す

表で比較

書き方意味(読み方)何を測ってる?
sizeof n + 2(sizeof n) + 2n のサイズに 2 を足す
sizeof(n + 2)sizeof( n+2 の結果の型 )n+2 の結果(型)のサイズ
sizeof(n) + 2sizeof(n) に 2 を足す上と同じで明確

結論:sizeof と + や - を混ぜるときは、括弧で意図を固定するのが安全です。

サンプルプログラム

「いろんな型・変数・式の sizeof をまとめて観察する」プログラムを例に解説をします。

プロジェクト名:chap7-10-1 ソースファイル名:chap7-10-1.c

// sizeof の基本をまとめて確認する
#include <stdio.h>

int main(void)
{
    char        c = 1;
    int         n = 10;
    long long   big = 1000;
    double      d = 0.5;

    puts("sizeofの結果をまとめて確認しよう!");

    // A: sizeof(型名)
    printf("sizeof(char)      = %zu\n", sizeof(char));
    printf("sizeof(int)       = %zu\n", sizeof(int));
    printf("sizeof(long long) = %zu\n", sizeof(long long));
    printf("sizeof(double)    = %zu\n", sizeof(double));

    puts("---- 変数(B: sizeof 式) ----");
    printf("sizeof(c)   = %zu\n", sizeof(c));
    printf("sizeof(n)   = %zu\n", sizeof(n));
    printf("sizeof(big) = %zu\n", sizeof(big));
    printf("sizeof(d)   = %zu\n", sizeof(d));

    puts("---- 式(結果の型に注目) ----");
    printf("sizeof(c + 1)     = %zu\n", sizeof(c + 1));
    printf("sizeof(n + 1)     = %zu\n", sizeof(n + 1));
    printf("sizeof(n + d)     = %zu\n", sizeof(n + d));
    printf("sizeof(big + n)   = %zu\n", sizeof(big + n));

    puts("---- 優先順位の例(括弧で差が出る) ----");
    printf("sizeof n + 2      = %zu\n", sizeof n + 2);
    printf("sizeof(n + 2)     = %zu\n", sizeof(n + 2));

    return 0;
}

このプログラムの見どころ

注目点期待できる学び
sizeof(char) など型名形式(A)型そのもののサイズを測る
sizeof(c), sizeof(n)変数は式(B)変数の型のサイズを測る
sizeof(c + 1)整数拡張c が char でも式は int になりやすい
sizeof(n + d)通常の算術変換int + double は double になりやすい
sizeof n + 2 と sizeof(n + 2)優先順位括弧の有無で意味が変わる
c は char だけど、c + 1 は int になりやすい
  → sizeof(c) と sizeof(c + 1) が違うことがある

n + d は double になりやすい
  → sizeof(n + d) は sizeof(double) と同じになりやすい

sizeof n + 2 は (sizeof n) + 2
sizeof(n + 2) は (n + 2) の結果の型のサイズ

使った命令(演算子・関数)の書式と役割

sizeof(演算子)

  • 書式
    sizeof(型名)
    sizeof 式
  • 役割
    対象のバイト数を返す(結果の型は size_t)

printf(関数)

  • 書式(よく使う形)
    printf(書式文字列, 値1, 値2, ...);
  • 役割
    画面に整形して表示する
  • size_t を表示する書式指定
    %zu

puts(関数)

  • 書式
    puts(文字列);
  • 役割
    文字列を表示し、最後に改行も付けてくれる

演習問題

演習7-1:括弧で意味が変わる sizeof

次の式のうち、同じ値になりやすい組と、意味が変わって値が変わりやすい組を答え、理由を説明せよ。
ここで n は int 型の変数とする。

  1. sizeof(n)
  2. sizeof n
  3. sizeof n + 2
  4. sizeof(n + 2)
  5. sizeof((double)-1)

解答例・解説

まず、同じになりやすい組

1.sizeof(n) と 2) sizeof n
 どちらも n の型(int)のサイズを測る

2.は括弧省略形(読みやすさのため 1) 推奨)

意味が変わって値が変わりやすい組

3.sizeof n + 2
 (sizeof n) + 2 と解釈されやすい
 n のサイズに 2 を足しているだけ(測る対象は n)

4.sizeof(n + 2)
 n + 2 という式の結果の型(たいてい int)のサイズ

とは別物になりやすい

型変換が絡む例

5.sizeof((double)-1)
 (double)-1 は double 型の式
 つまり sizeof(double) と同じになりやすい

ポイントまとめ

  • sizeof と + や - を混ぜるときは、括弧で意図を固定する。
  • sizeof(式) は式の結果の型に注目する。