ログイン
kid's world

文字を覚える変数

今回はキーボードからの入力の受け付けについて学習する。これでプログラミングの幅がぐっと広がるはずだ。難しい計算も簡単に解いてくれるようなプログラムをどんどん作ってみよう。


はじめに

前回は,データを大量に扱うときに必要となる「ポインタ」と「配列」について解説した。変数はどのようにメモリを確保しているのか,また,プログラマがメモリを確保して使うにはどうしたらいいのかなど,メモリに関する話題について扱った。

少々難しかったかもしれないが,とても重要な話である。今回のテーマの「キーボードからの入力方法」と次回に予定している「文字列の扱い方」のどちらでもポインタや配列を使う。前回はピンとこなかったと思うが,今回以降でその重要性がどんどんとわかってくるだろう。

今回のお話

前半部分で「文字」と「関数」について簡単な説明を行う。今まで文字についてはあまり触れなかったし,関数も「ただ文が集まったもの」という程度の認識しかないと思う。そこで,ちょっとだけそのあたりの知識を補いたいと思う。後半部分でキーボードからの入力についての解説を行う。

文字を覚える変数

これまで,「数値」を覚える変数については何度か述べて,整数を扱うint型や実数を扱うfloat型などがあることを解説してきた。ところが,「文字」を覚える変数についてはまだ教えていなかった。忘れていたわけではない(笑)。話したくてウズウズしていたのだが,それは今回のためにとっておいたのだ。

char型

最初にずばりいってしまうと,C言語には文字を扱うために一般的に使われるcharという型がある。見てのとおり,「文字」の英語「character」の最初の4文字である。

「文字を扱う専用の型がある」といわずになんとも意味ありげに微妙な表現をあえてしているのだが,そのあたりの詳細はあとで述べよう。

ここで注意したいのは,「文字列」ではなく,「文字」を扱うということだ。文字列とは「abcdef」という,文字が並んだものであり,文字は「a」や「b」といった記号1つ1つのことである。

文字列を扱う方法は難しいので,ここではまだ解説しない。とりあえず「char型変数1つで,1文字を扱うことができる」と考えれば大丈夫だ。

int型やfloat型のサイズはコンパイラによって異なる場合もあるが,char型はどのコンパイラでも必ず1バイトと決められている。1バイトでは,256種類の値を表すことができる(「バイト」については2002年6月号の第3回を参照)。

……と,ちょっと待った。上記の説明では「char型では256個の文字しか区別できない」ことになってしまう。これでは,1万字以上はある日本語の漢字などは,char型では表現することはできないではないか!?

そうなのだ。char型では漢字は表現できない。扱えるのは「英数字と記号だけである」と今は考えておこう。ただし,日本語を扱えるOSであれば,追加的にカタカナを扱うことができる場合がある。英数字にカタカナを合わせても256個を超えることはないからだ。カタカナの話についてはあとで説明しよう。

文字定数

では,実際に文字を扱ってみよう。まずはchar型の変数を宣言する。たとえば,cという名前の変数にしたければ,次のように宣言する。

char c;

次に,この変数に文字を代入するわけだが,たとえば「A」という文字を代入したいときには,

c = A;

と書きたくなる。その気持ちはよくわかるが,それは誤りだ。なぜならもし「A」という変数があったとき,この文はどういう意味になるだろうか? ちょっと考えてみていただきたい。……そう,変数Aの内容を変数cに代入するという意味になってしまう。C言語では,そういうあいまいさをなくすために「これは文字である」という意味で,単一引用符「'」で文字を囲むのだ。つまり,

c = 'A';

と書けばよい。これで,変数の「A」ではなく,文字の「A」だと解釈されるようになる。以前,定数について解説したことがあったが,実はこの「'A'」も定数であり,文字定数と呼んでいる。

文字定数について,もう少し詳しく話そう。実は,Table 1に示すエスケープ文字も文字の一種で,単一引用符で囲んで文字定数とすることができる。「\n」についてはすでにおなじみだろう。これらの文字を書くと「意味」の欄に書いてあるような動作が行われたり,文字が表示されたりする。

Table 1: エスケープ文字

/c/input-table1.png

ちょっと理解に苦しむのは8進数と16進数だろうが,これについては後ほど説明する。

printf関数の変換文字

それでは話を戻して,変数cに代入した文字を画面に表示してみよう。ここでも数値を表示したときと同じように,printf関数のお世話になる。文字を表示するための変換文字は,「%c」である。したがって,変数cの内容をprintf関数で表示するには,

printf("%c\n",c);

と書く。

List 1にchar型を使った例を示そう。配列を使って,0番目から「A」「B」「C」「\a」を代入して,それを一度にprintf関数で表示している例である。実際にList 1を実行すると「ABC」と画面に表示され,何らかの音が鳴ることを確認しよう。Table 1に示したように,’\a’という文字は,ベルを意味する。「ピーッ!」と鳴ったり,「コン」と鳴ったり,画面がフラッシュしたりと,OSやコンパイラによってこの文字を表示したときの動作はさまざまである。

List 1: char型の使用例

#include <stdio.h>

main()
{
  char c[4];
  
  c[0]='A';
  c[1]='B';
  c[2]='C';
  c[3]='\a';
  
  printf("%c%c%c%c\n",c[0],c[1],c[2],c[3]);
}

文字は数値?

実は,char型は文字を扱うために特別に作られている型ではない。int型などと同じように,整数を扱うための型である。ただ,ほかの型と違うのは「サイズは1バイトでなければならない」ということだけである。

そのことを実際に試しているのがList 2だ。List 2では,char型の変数に10を代入し,インクリメント演算子でその値を1増やしている。printf関数では「%c」ではなくわざと「%d」を使い,変数cの値を表示している。

List 2:char型で足し算をする

#include <stdio.h>

main()
{
  char c;

  c=10;
  c++;

  printf("%d\n",c);
}

実行すると画面には「11」と表示される。なんと,char型は整数を扱う型だったのだ。これは驚きだ。ということは,文字は数値だといっているようなものだ。それは本当なのだろうか?

そこで,この疑問を検証するためにList1をちょっと変形したプログラムを作ってみた(List 3)。

List 3: 文字は数値として扱われる

#include <stdio.h>

main()
{
  char c[3];
  
  c[0]='A';
  c[1]='B';
  c[2]='C';
  
  printf("%d %d %d\n",c[0],c[1],c[2]);
}

一般的に使われているコンピュータであれば,List 3を実行すると画面には「65 66 67」と表示されるだろう。すなわち,「A」は「65」,「B」は「66」,「C」は「67」という数値として扱われているということだ。

List 4では,変数cに対して「'A'+2」などという,一見わけのわからない演算結果を代入している。コンパイルしても文句はいわれない。なぜなら'A'というのはchar型の65という立派な「整数」であって,それに2を足したにすぎないからだ。変数cには67という数値が代入されたことになる。char型の67は'C'と同じだ。したがって画面には「C」と表示される。

ASCII文字セット

このように,文字は数値として扱われているわけだが,それは文字と数値の変換表のようなものがあってこそ成り立つ話である。その変換表として,ほとんどのコンピュータでは,ASCII文字セットを使っている。

日本語を扱えるOSであればカタカナも扱える場合があると書いたが,それは俗に「半角カナ」と呼ばれている,8ビットのJISコード(JIS X 0201)のことだ。これは,ASCII文字セットに加えて,16進数のA1からDFまでを使って半角のカタカナを表現している。

最近は,パソコンでは半角のカタカナはあまり使われることはなく,逆に厄介者扱いされる場合もあるが,理解のために半角カナも含めたその文字コード表をTable 2に示そう。

Table 2: 文字コード表(JIS X 0201のラテン文字 - カタカナ用8ビット符号より抜粋)

/c/input-table2.png

この表は文字と16進数の数値の対応を表している。行が16進数の1桁目,列が2桁目である。たとえば「*」は,「2A」である。「空白(スペース)」は,「20」を使う。ほかの空いている部分は別の用途に使われるので,使ってはならない。

ここで,Table 1に示したエスケープ文字の「\△△△」と「\x□□」について説明しよう。

「\△△△」は任意の文字を8進数で表すことができる。「△△△」の部分に,3桁までの8進数を指定すれば,その値のchar型の文字になる。たとえば'C'は8進数で103なので,'\103'と書けば,'C'と同じ意味になる。もちろん「\n」というエスケープ文字と同じようにして,printf関数などで

printf("AB\103\n");

と書くことができ,このとき画面には「ABC」と表示されて改行が行われる。実際にC言語でよく使われるのは「'\0'」という文字で,0の値に対応する文字なのだが,これは次回に詳しく説明しよう。

また,「\x□□」は任意の文字を16進数で表すことができ,「□□」の部分に2桁までの16進数を指定する。'C'はTable 2を見ると16進数で43であることがわかるので,'\x43'と書けば,それは'C'を表したことになる。

どちらの表記法も,本来はキーボードからでは表現できない文字(Table 2の空欄の部分)を扱うときに使うためのものである。

char型のまとめ

英数字や記号(場合によっては半角カタカナも含む)を扱うには,1バイトのサイズを持つchar型を使うとよい。char型は文字を扱うために特別に作られた型ではなく,1バイトで表すことのできる整数を扱う型である。文字は1バイトの数値として表現され,文字と数値の対応表として,ほとんどのコンピュータではASCII文字セットを使っている。


関数」へ進む

広告


©Toshio Koide 1996-2007.

目次

リンクについて

リンクは御自由にどうぞ。

メール

mail.gif

広告