C言語のchar型(1文字)の基礎。'A'と"A"の違い、ASCIIコード、char=整数の仕組み、scanfでの1文字入力まで。
char は 1 文字 を入れる箱(1バイト)'A'(シングルクォート)printf("%c", c) で表示 / scanf(" %c", &c) で入力c + ('a'-'A')ch - '0'int(整数)と double(実数)を使ってきましたね。ここで初めて char(チャー)型を学びます。char は 1 文字 を入れる箱です。サイズは 1 バイト。書き方はとてもシンプル:char c = 'A'; // c に文字 A を入れる printf("%c\n", c); // → A (画面に A が出る)
'A'%c(character の c)'A'(シングル)と "A"(ダブル)はまったく別物'A' ― シングルクォートchar c = 'A';
"A" ― ダブルクォート\0)char s[] = "A";
'A' として見えるのは 「数値 65 を文字として解釈している」だけ なんです。char c = 'A'; と char c = 65; は完全に同じ意味printf("%c", 65) → A / printf("%d", 'A') → 65'A' + 1 が 'B' になる、という芸当ができる
| 文字 | 10進 | 16進 | 説明 |
|---|---|---|---|
| \0 | 0 | 0x00 | ヌル文字(文字列の終端の目印) |
| \t | 9 | 0x09 | 水平タブ |
| \n | 10 | 0x0A | 改行 |
| ␣ | 32 | 0x20 | 半角スペース |
| 文字 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|---|---|---|---|---|---|---|---|---|---|
| 10進 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 |
| 文字 | A | B | C | D | E | F | G | H | I | J | K | L | M |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 10進 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 |
| 文字 | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
| 10進 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 |
| 文字 | a | b | c | d | e | f | g | h | i | j | k | l | m |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 10進 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 |
| 文字 | n | o | p | q | r | s | t | u | v | w | x | y | z |
| 10進 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 |
'a' - 'A' = 32 がいつでも成立。これが「大文字 ↔ 小文字 変換」のキーになります。
#include <stdio.h> int main(void) { char c = 'A'; printf("c = %c\n", c); // → A (文字として表示) printf("c = %d\n", c); // → 65 (整数として表示) // 文字の「計算」もできる printf("%c\n", c + 1); // → B (65+1=66、'B'のコード) printf("%c\n", 'Z' - 3); // → W // 65 を char に入れても 'A' と等価 char d = 65; printf("%c\n", d); // → A return 0; }
char c = 'A'; char lower = c + ('a' - 'A'); // 'A' + 32 = 'a' // または: char lower = c + 32;
char ch = '7'; // これは 55 ('7'のASCII) int n = ch - '0'; // 55 - 48 = 7 (本当の整数7) printf("%d\n", n); // → 7
if (c >= 'A' && c <= 'Z') // 大文字? if (c >= '0' && c <= '9') // 数字? // 標準ライブラリ <ctype.h> にも isupper(c), isdigit(c) がある
char c = 'あ'; はエラーか警告になります。日本語の1文字は複数バイト(UTF-8 なら 3バイト)必要なので、charの配列で扱うか、wchar_t を使うか、文字コードを自分で扱う必要があります。ASCII の範囲(英数字と記号)だけが char で安全に扱える文字です。'A' や 'あ' が見えていても、メモリには 結局すべて数値(番号)として保存 されています。char が「実は整数」なのは特別な仕様ではなく、「文字に番号を割り当てた」だけ という当たり前の話です。scanf で入力するprintf と対になるのが scanf。書式は %c(character の c)。int の %d と同じ感覚で、変数の住所 & を渡す のがポイントです。#include <stdio.h> int main(void) { char c; printf("1 文字入力してね: "); scanf("%c", &c); // ← & を忘れない! printf("入力された文字: %c\n", c); return 0; } /* 実行例 1 文字入力してね: A ← A を入力して Enter 入力された文字: A */
%c(1 文字)&c のように 住所(アドレス) を渡す(int の scanf("%d", &n) と同じ)c に入る& の有無 だけ。
scanf と続けると「改行」が入ってしまうint n; char c; scanf("%d", &n); // 数字を入力 → Enter scanf("%c", &c); // 続けて 1 文字を入力したい… が、うまくいかない! printf("n=%d c=[%c]\n", n, c);
5 Enter A Enter」と入力したつもりでも、c には 'A' ではなく '\n'(改行)が入ってしまいます。原因は、入力が 「入力バッファ」という見えない待合室 を経由するから。5 Enter」と打つと、入力バッファにはこう並ぶ:scanf("%d", &n) は 5 だけを取り出して n に入れる。改行 \n は 残ったまま:scanf("%c", &c) は バッファの先頭の 1 文字 を取る。先頭は \n なので…:A を入力する前に、c はもう \n で埋まってしまう。" %c" と先頭スペースを入れる%c の前に 半角スペース 1 つ を書くと、scanf は 空白文字(スペース・タブ・改行)を全部読み飛ばして から 1 文字を取ってくれます。int n; char c; scanf("%d", &n); scanf(" %c", &c); // ← " %c" の先頭スペースが \n を吸収! printf("n=%d c=[%c]\n", n, c); // → n=5 c=[A] 期待通り!
%c の前にはスペースを 1 つ」。これだけで連続入力の改行残り問題がほぼ解決します。%d や %s はもともと先頭の空白を読み飛ばす仕様なので、この問題が起きません。%c だけ別ルール)
この講座の理解度をチェックしましょう!
char c = 'A'; のとき printf("%d", c) の出力は?char の中身は整数(ASCIIコード)です。'A' は 65 なので %d では 65 と表示されます。%c なら A。
'A'(シングル)と "A"(ダブル)の違いは?'A' は char 1バイト。"A" は char 配列で 'A' と '\0' の2バイトになります。
scanf("%d", &n) のあと、1文字を正しく読むには?" %c" のように先頭にスペースを入れると、残った改行などの空白を読み飛ばしてから1文字を取れます。