朝起きて書いてみました.しかしこれは,何度も手入れしないといけないな….
- 1バイトの情報を表すためのデータ型は,charです.
- charと書いたら,signed charなのかunsigned charなのか規定されませんが,利用上は問題ありません.
- Cのプログラミング教育において,「charは1文字を表すためのデータ型」と言われますし,私も授業ではそう教えていますが,「あ」という文字は1バイトで表現できないことを忘れないようにしたいものです.(関連用語としては「文字コード」と「マルチバイト文字」なのですが,今回は用語の紹介にとどめます.)
- 'a' で表記する値は「文字定数」と呼ばれます.「文字リテラル」と呼ばれることもあります.
- "a" で表記する値は「文字列リテラル」と呼ばれます.「文字列定数」とも呼びます.
- ダブルクオートの間に書ける文字の長さは,任意です(任意長あるいは可変長といいます).1000文字並べてもかまいませんし,途中に「\0」や「\141」があってもかまいません.それと,"" という表記もできます(空文字列と呼ばれます).
- 文字列リテラルのデータ型は,char *と考えましょう.
- 配列と文字列の関係でも書きましたが,文字配列の初期値に「char a[] = "Oresama";」と書くことができます.このときは,配列変数aは文字列リテラルを参照しているのではなく,この配列変数の初期値が{'O', 'r', 'e', 's', 'a', 'm', 'a', '\0'}であるという意味になります.
- 「char a[10];」と配列変数を定義してから,「a[0] = 'X';」のように代入したとします.a[0] はchar型,'X' はint型なので,暗黙の型変換が起こり,'X' は char型に変換されて,a[0]に格納されます.
- charがunsigned charと同じなら,文字定数の取り得る範囲はunsigned charなので,問題なく代入できます.
- charがsigned charと同じなら,代入において値が変わる可能性があります.ただし,Cの(初学者向けの)プログラミングで出てくる値は,7ビットで表現されるASCIIコードの値です.ということで 'X' の代入であれば,値が変わるということはありません.
- charがsigned charであり,かつ「a[0] = '\377';」なら,どうでしょうか.255 を signed charに変換した上でa[0]に代入します.これも「たいていの処理系で」という条件がつきますが,int型の値の下位8ビットが格納されます.ということで,a[0]の値は-1になります.intからcharへの型変換によって,メモリやレジスタの中の「ビット表現」は変わることなく,その値の意味が,変数のデータ型によって変わる,と考えるといいでしょう.
- isalphaなどの,文字種を判定するライブラリ関数は,引数の型がcharではなくintです.
- オンラインマニュアルによると,型としてはintですが,値の範囲としてはunsigned charの範囲,またはEOFです.EOFはたいていの処理系で-1と定義されている定数です.
- 通常,判定の対象となる文字は,ASCIIコードの範囲内ですので,charがsigned charであるような処理系であっても,問題ありません.
- まとめ.
- 1文字(1バイト)の値はchar型で表現できますが,しばしばint型に拡張されます.1文字(1バイト)の値がunsigned char型の範囲に収まっている限り,charとintの暗黙の型変換は気にしなくてかまいません.
- charがunsigned charであっても,signed charであっても,ASCIIコードの中の文字であれば*1,常に非負整数であり,負の値になることはありません.
*1:1バイトが8ビット以上であるという条件も要請されます.もちろん現在動作するほぼすべての処理系が,この条件を満たします.どうしても気になるなら,"#include