トラック5・📦変数・型・演算子

2進数・16進数リテラル(0b / 0x / 桁区切り')

読む目安 約11分・ゴール:0b・0x・8進の書き方の違いを理解し、C23の桁区切りで読みやすく数値を書ける

アプリでこのトピックを学ぶ(無料・登録不要)

このトピックの要点

コードに直接書いた数値をリテラルと呼びます。同じ「10」でも書き方はいくつもあり、C23では表現が増えて、意図がより伝わりやすくなりました。

4つの書き方、同じ値

#include <stdio.h>

int main(void) {
    int juu_10 = 10;       // 10進数
    int juu_2  = 0b1010;   // 2進数(C23で標準)
    int juu_16 = 0xA;      // 16進数
    int juu_8  = 012;      // 8進数(先頭の0が目印)

    printf("%d %d %d %d\n", juu_10, juu_2, juu_16, juu_8);
    return 0;
}

出力は 10 10 10 10。4つとも同じ値です。書き方が違うだけで、メモリに入る中身は変わりません。人間にとって読みやすい形を選べばよい、ということです。

・0b … 2進数。ビットを1つずつ見せたいとき(トラック21で本領を発揮します)
・0x … 16進数。1桁で4ビットを表せるので、メモリやカラーコードの表現に便利
・先頭の 0 … 8進数。意図せず使ってしまう罠(後述)

桁区切り——C23の読みやすさ

#include <stdio.h>

int main(void) {
    int jinkou = 125'000'000;
    int yosan  = 1'200'000;
    int bits   = 0b1010'1100;

    printf("%d %d %d\n", jinkou, yosan, bits);
    return 0;
}

C23から、数値の途中に '(シングルクォート)を入れて桁を区切れます。125000000 と 125'000'000 では、読み間違えにくいのは明らかに後者です。3桁ずつでも4ビットずつでも、好きな位置に置けます。区切りは値に一切影響しません。

16進・8進で表示する

#include <stdio.h>

int main(void) {
    int n = 255;

    printf("10進 %d\n", n);
    printf("16進 %x\n", n);
    printf("16進 %X\n", n);
    printf("8進 %o\n", n);
    return 0;
}

出力は 255 / ff / FF / 377。C23では2進表示の %b も追加されましたが、コンパイラの対応にばらつきがあるため、当面は %x が無難です。

罠・注意

先頭の0は8進数。 int t = 012; は10です。int t = 09; に至ってはエラーになります(8進に9は無いため)。時刻や日付を 0930 のように0埋めで書くと、静かに別の値になります。数値の先頭に0を書かないが鉄則です。

0b と ' はC23の機能。 古いコンパイラでは通りません(gccなら -std=c23 または -std=c2x を付けます)。

桁区切りは表示には出ない。 125'000'000 を printf しても 125000000 と出ます。区切りはソースコードの中だけの話です。

ビット0x は「ビットを4つずつ見る眼鏡」。慣れるとメモリの中身が読めるようになるよ。

まとめ

10進・2進(0b)・16進(0x)・8進(先頭0)は、書き方が違うだけで同じ値です。C23では ' で桁を区切れて、長い数値が一気に読みやすくなります。先頭0の8進は事故のもと。表示は %x %o、C23なら %b もあります。

アプリでこのトピックを学ぶ(無料・登録不要)

確認問題

確認問題 1

10進数の 255 を2進数リテラルで書きます。空欄に入るものはどれですか。

int n = ____;
  1. 0b11111111
  2. 0b10101010
  3. 0b11110000
  4. 0b100000000
答えを見る

正解:A(0b11111111)

1が8個並んだ 0b11111111 が 255(128+64+32+16+8+4+2+1)です。0b10101010 は170、0b11110000 は240、0b100000000(1のあと0が8個)は256になります。0b の2進数リテラルはC23で標準になった書き方で、0b1111'1111 のように桁区切りを入れるとさらに読みやすくなります。

確認問題 2

int t = 012; としたとき、t の値はどれですか。

  1. 12
  2. 10
  3. 3
  4. コンパイルエラーになる
答えを見る

正解:B(10)

先頭の 0 は「これは8進数」という印です。8進の 12 は 1×8 + 2 = 10 になります。時刻や日付を 0930 のように0埋めで書くと、意図せず8進数になって静かに値が変わります(09 は8進に9が無いのでエラー)。数値リテラルの先頭に0を書かないが鉄則です。

「変数・型・演算子」の目次

  1. 変数とは名前付きの箱
  2. int型と整数の世界
  3. 浮動小数点数 float / double
  4. char型と文字コード
  5. bool型と真偽——C23標準の書き方
  6. 定数——const と constexpr
  7. 算術演算子と優先順位
  8. 整数の割り算と剰余の罠
  9. 型変換——暗黙と明示
  10. 2進数・16進数リテラル(0b / 0x / 桁区切り')
  11. sizeofとメモリ上のサイズ
  12. オーバーフローという事件

もっと先へ:ポインタ・メモリ・ファイル入出力・セキュアコーディングを含む全26トラックと、段位検定・模試のフルセットは完全版に収録しています。

完全版の販売ページは準備中です。

ほかのトラック

📚 姉妹教材:手を動かして覚える Linux 教材 — Linuxとインフラの仕組みを地図で学ぶ

Web版