'char'型に文字列リテラルを代入したときの原因と直し方
1文字を表すchar型の変数に、ダブルクォートで囲んだ文字列リテラルを代入しようとしたときに出るエラーです。シングルクォートとダブルクォートは別物です。
エラーメッセージの読み方
main.c:4:18: error: initialization of 'char' from 'char *' makes integer from pointer without a cast [-Wint-conversion]
main.c- ファイル名
4- 行番号
18- 列番号 — この位置でgccが構文解析に失敗しました
initialization of 'char' from 'char *' makes integer from pointer without a cast [-Wint-conversion]- 内容 — 期待していたもの、または受け付けられなかったもの
このエラーが出る典型パターン
パターン1
1 #include <stdio.h> 2 3 int main(void) { 4 char grade = "A"; ^ 5 printf("%c\n", grade); 6 return 0; 7 }
"A"はA1文字とその後の終端文字からなる文字列(char*型)です。1文字だけを表すchar型に代入するにはシングルクォートの'A'を使います。
直し方: "A" を 'A' にします。
パターン2
1 #include <stdio.h> 2 3 int main(void) { 4 char initial = "K"; ^ 5 printf("%c\n", initial); 6 return 0; 7 }
ダブルクォートの"K"はポインタ型なので、char型の変数にはそのまま代入できません。
直し方: "K" を 'K' にします。
パターン3
1 #include <stdio.h> 2 3 int main(void) { 4 char sign = "+"; ^ 5 printf("%c\n", sign); 6 return 0; 7 }
記号1文字であっても、ダブルクォートで囲むと文字列(ポインタ)になります。char型にはシングルクォートを使います。
直し方: "+" を '+' にします。
パターン4
1 #include <stdio.h> 2 3 int main(void) { 4 char answer = "Y"; ^ 5 printf("%c\n", answer); 6 return 0; 7 }
1文字であってもダブルクォートで囲むと文字列(ポインタ)になります。char型にはシングルクォートを使います。
直し方: "Y" を 'Y' にします。
パターン5
1 #include <stdio.h> 2 3 int main(void) { 4 char op = "*"; ^ 5 printf("%c\n", op); 6 return 0; 7 }
記号1文字でも同じ規則です。演算子の記号を保持したいだけならシングルクォートが必要です。
直し方: "*" を '*' にします。
よくある誤解
'x'と"x"は見た目が近いですが、'x'は1文字を表す整数値(char型)、"x"は'x'と'\0'の2文字からなる配列へのポインタ(char*型)です。この違いがそのまま代入先の型の不一致になります。
実務での勘所
実はCでは'x'のような文字定数の型はcharではなくintです(sizeof('x')は多くの環境で4になり、sizeof(char)の1とは一致しません)。歴史的な経緯によるC言語特有の仕様で、C++では'x'の型はchar(sizeofは1)に変更されているため、CとC++で微妙に振る舞いが異なる数少ない箇所の1つです。実用上はchar型の変数に代入する時点で自動的に切り詰められるため問題になりにくいですが、sizeofの結果だけを見て「charのはず」と決めつけると混乱します。