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

char型と文字コード

読む目安 約11分・ゴール:charが1バイトの小さな整数であることを理解し、文字と数値を相互に変換できる

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

このトピックの要点

コンピュータは文字も数として持っています。charは1文字を入れる箱ですが、その正体はとても小さい整数です。

文字は数である

#include <stdio.h>

int main(void) {
    char c = 'A';

    printf("%c\n", c);   // 文字として表示
    printf("%d\n", c);   // 数として表示
    return 0;
}

出力は A と 65 です。'A' は文字コード(ASCII)で65番。同じ箱の中身を、%c で見るか %d で見るかの違いしかありません。

覚えておくと便利な番号は3つ。'A' が65、'a' が97、'0' が48です。大文字と小文字はちょうど32離れています。

数として扱えるから計算できる

#include <stdio.h>

int main(void) {
    char dai = 'C';
    char sho = dai + 32;       // 大文字→小文字
    char moji = '7';
    int  suuchi = moji - '0';  // 文字の'7' を 数の7 に

    printf("%c %c\n", dai, sho);
    printf("%d\n", suuchi * 2);
    return 0;
}

出力は C c と 14。'7' - '0' は 55 - 48 = 7 です。文字の数字を本物の数値に変えるこの式は、この先いたるところで登場します。

シングルクォートとダブルクォート

・'A' … 文字1つ。char に入る。
・"A" … 文字列。中身は 'A' と終端記号の2つ分(トラック9で扱います)。

別物です。char c = "A"; は型が合わずエラーになります。

動く例——見えない文字にも番号がある

#include <stdio.h>

int main(void) {
    printf("[%c] %d\n", 'A', 'A');
    printf("[%c] %d\n", 'Z', 'Z');
    printf("[%c] %d\n", '0', '0');
    printf("[%c] %d\n", ' ', ' ');
    return 0;
}

最後の行は空白文字です。画面には何も見えませんが、32番という番号がきちんと振られています。

罠・注意

日本語1文字は char に入らない。 UTF-8では「あ」は3バイトです。1バイトの char には収まりません。日本語1文字を扱う話は見た目より複雑で、トラック9で改めて扱います。

char が符号付きかどうかは環境依存。 -128〜127 の環境と 0〜255 の環境があります。128以上の値を char に入れて比較するコードは移植性を失います。

'A' の型は char ではなく int。 Cでは文字定数は int として扱われます。あとで sizeof('A') が 4 になるのを見て驚かないよう、ここで言っておきます。

ビット文字は数、数は文字。行き来できるようになると、暗号やちょっとしたゲーム処理が急に書けるようになるよ。

まとめ

char は1バイトの小さな整数で、文字コードを通して文字を表します。'A'=65、'0'=48、大文字と小文字の差は32。'7' - '0' で数字文字を数値にできます。'A' と "A" は別物、日本語1文字は char に収まりません。

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

確認問題

確認問題 1

char の箱に文字 A を入れます。空欄に入る書き方はどれですか。

char c = ____;
  1. "A"
  2. 'A'
  3. A
  4. 65.0
答えを見る

正解:B('A')

1文字はシングルクォートで囲んで 'A' と書きます。ダブルクォートの "A" は文字列('A' と終端記号の2つ分)なので型が合わずエラーです。クォート無しの A は変数名とみなされ、65.0 は小数なのでcharには素直に入りません(char c = 65; なら 'A' と同じ意味になります)。

確認問題 2

このプログラムの出力はどれですか(/は改行を表します)。

#include <stdio.h>

int main(void) {
    char c = 'A';
    printf("%c\n", c);
    printf("%d\n", c);
    printf("%c\n", c + 2);
    return 0;
}
  1. A/65/C
  2. A/A/A
  3. A/65/67
  4. 65/65/67
答えを見る

正解:A(A/65/C)

char の中身は文字コードという数値です。'A' は65なので、%c で見れば A、%d で見れば 65。c + 2 は 67 になり、それを %c で見ると文字コード67の C が出ます。同じ中身を「文字として見るか、数として見るか」の違いだけです。

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

  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版