プロが教えるわが家の防犯対策術!

整数はint型、文字はchar型を使うのが原則のようですが、
文字はコンピュータの中で数字で扱われていることと、
char型が0~255、int型がそれ以上の範囲の数字を扱えることを考えると
文字を扱う時もint型でかまわないのでは?と思いました。
実際、int型で1文字出力できました。具体的には下です。

int a;
a=getchar();
printf("%c\n",a);
return 0;

しかし、文字列をint型で扱おうとすると、コンパイル時にエラーとなります。

int a[50]="Hello";
printf("%s\n",a);
return 0;

なぜ、int型では文字列が扱えないのか理解できません。

A 回答 (6件)

getcharは文字コードを返すとともに、最後のEOFも返します。

EOFは普通-1なのでintで受け取らないとだめなんです。

charなのにintで取るのはこれくらいだと思います。あとは型をちゃんとあわせないとだめですね。

キャストをすれば使えますけれど、プログラムがわかりにくくなりますし、バグが入りやすいですから、ちゃんと型を意識したプログラムを作った方がよいですよ

この回答への補足

回答ありがとうございます。
わかりやすいプログラムは大事ですね。
やはりgetchar関数は珍しいものなんですね。
理解を深めるためにキャストを使った記述のしかたを具体的に教えてください。

補足日時:2007/03/18 18:10
    • good
    • 0
この回答へのお礼

回答ありがとうございました。

お礼日時:2007/03/19 00:12

出来ることと、すべきことは違います。



charとintを色分けしているのは、基本的に誰が見ても
charは文字を使っていると「わからせる」効果があります。
intで文字が使えないけど、使えたとしても使うべきでは
ありません。

なお、誰でもの「誰」は他人だけではなくて、将来の自分も
含みます。

この回答への補足

intを整数、charを文字
とわかりやすく区別すべきなのはわかります。
しかし、この質問はその前提の上であくまで理解を深めるためにしました。
そのへんの説明がたりなかったようです。すいません。

補足日時:2007/03/18 18:14
    • good
    • 0
この回答へのお礼

回答ありがとうございました。

お礼日時:2007/03/19 00:13

> コンパイル時にエラーとなります。


> int a[50]="Hello";

コンパイラが、何をどうしたいのか?判断できないからですね。
以下のような方法でint型の配列に文字を格納して試して見ては?

int a[50];
a[0]='H';
a[1]='e';
a[2]='l';
a[3]='l';
a[4]='o';

printf関数も、int型の配列に格納した文字を表示するように出来ていない事が確認できると思います。

> なぜ、int型では文字列が扱えないのか理解できません。

標準の関数でそうしてくれないだけです。
自分でそういう、int型の入れるに格納された文字を表示すれば、可能です。

この回答への補足

試した結果
int a[50]={'H','e','l','l','o','\0'};  ○
char a[50]={'H','e','l','l','o','\0'};  ○
int a[50]="Hello";  ×
char a[50]="Hello";  ○
となりました。

おそらく、記述の仕方で
{'H','e','l','l','o','\0'};はint型char型
"Hello"はchar型に使えるようです。

ここでまた思ったのですが、
intでも文字列が扱えるのであれば、なぜchar型が生まれたのでしょうか?
intで一本化すればよかったのではと思いました?

補足日時:2007/03/18 18:19
    • good
    • 0
この回答へのお礼

回答ありがとうございました。

お礼日時:2007/03/19 00:13

★『getchar』関数については回答者 No.1 さんのアドバイスどおりです。


・ここの質問者さんで『char c = getchar();』という使い方をしていた人がいましたが、
 EOF を戻すため int 型などにしないとチェックできません。
・int 型などでも文字列を管理は出来ます。実際、WCHAR 型は 2(4) バイトの整数型と
 同じ範囲です。でも、この場合は printf 関数の『%s』では利用できません。
・よって、関数の文字列への管理法(取り扱い方)が違うのです。printf 関数は文字列を
 『char』型の配列として処理するため、『int』型の配列で管理している文字列は正常に
 扱えません。→そういう仕様(ルール)です。

余談:
・Windows では文字列を内部で Unicode 文字で扱っているようです。
 ファイルの入出力などはマルチバイト(シフトJIS)文字でやり取りできます。
・今後、Unicode 文字(2バイト以上)で文字列を扱う機会が増えてくると思います。
・Win32 API 関数の wsprintf 関数には『%s』で『TCHAR』型(LPTSTR型)の文字列と
 『WCHAR』型(LPSTR型)の文字列を両方扱うことが出来ます。この 2 つの文字列の
 使い分けは『#define UNICODE』されていれば、LPSTR 型の文字列として解釈する
 ようになります。LPSTR 型は WCHAR 型の配列ですが、WCHAR 型は int 型の整数と
 同じです。→ヘッダファイル内で『typedef』されています。環境により int 以外
 かも知れません。私の環境では int と同じ整数型でした。
・以上。おわり。→C言語では『char』型配列を文字列として扱うルールです。
    • good
    • 0
この回答へのお礼

な、なんかむずかしい・・・
回答ありがとうございました。

お礼日時:2007/03/19 00:15

>intでも文字列が扱えるのであれば、なぜchar型が生まれたのでしょうか?


>intで一本化すればよかったのではと思いました?

パソコンのメモリに実際どのようにデータが入るか考えてみましょう。

char a[50]={'H','e','l','l','o','\0'}; この場合

72,101,108,108,111,0

メモリ内のデータはこんな感じ。1バイトずつ文字コードが並び、最後は0(ヌル文字)です。

int a[50]={'H','e','l','l','o','\0'}; この場合

72,0,0,0, 101,0,0,0, 108,0,0,0, 108,0,0,0, 111,0,0,0, 0,0,0,0

intが4バイト(リトルエンディアン)なら、こんな感じになります。4バイト中3バイトは常に0で使われません。かなり無駄ですね。特に昔はメモリやハードディスクの容量が少ないですから、少しの無駄も省かねばなりません(今も無駄使いは良くありませんが・・・)。この様に、1バイトの文字コードを扱う場合は、char型が適しています。SJISなどの2バイト文字コードも、char型2つを1文字として扱うことが出来ます。


余談:
最近はUnicodeなどマルチバイトの文字コードが主流になってきましたから、将来的にはchar型の文字列が使われなくなるかもしれませんね。

この回答への補足

>4バイト中3バイトは常に0で使われません。かなり無駄ですね。特に昔はメモリやハードディスクの容量が少ないですから、少しの無駄も省かねばなりません(今も無駄使いは良くありませんが・・・)。この様に、1バイトの文字コードを扱う場合は、char型が適しています。

なるほど!やっと「なぜchar型なのか?」という疑問が解けました。
確かに、int型では無駄が多いですね。

補足日時:2007/03/19 00:15
    • good
    • 0
この回答へのお礼

回答ありがとうございました。

お礼日時:2007/03/19 00:21

C では「文字列」というのは「char型の配列」なので, 「int型の配列」では扱えません.


まあ, 今どきなら「ワイド文字」とか「ワイド文字列」というのがあって, これを使えば 2バイト以上の文字を扱うことができる (厳密には語弊あり) ことになっています. ワイド文字は wchar_t という型なので
wchar_t a[] = L"Hello";
printf("%ws\n", a);
のように使え... たはず.
getchar は「char で表すことのできる全ての値」に加えて EOF も返せないといけないので, char ではなく int を返します. これのワイド版では wint_t だっけな?
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!