• 締切済み

int とcharの使い方と違い

教えてgooに投稿するのは初めてですがよろしくお願いします。 最近C言語を勉強し始めた初心者です。 ネットのサイトを見て独学でしています。 過去スレッドをさらっと見て聞きたいことが書いてなかったので投稿します。(同じスレッドがあったらすみませんOTL) #include<stdio.h> int main(void) { int str='a'; printf("str=%c\n",str); return0; } この上のプログラムでは str=a と出て、エラーが出ずにコンパイル出来ました。でも、 #include<stdio.h> int main(void) { int str[]="abc"; printf("str=%s\n",str); return0; } とするとエラーが出ます。 int とcharの使い方と違いについて詳しく教えてほしいです>< お願いします。

みんなの回答

回答No.7

int型からchar型に変えるべきだと思います。 char str='a'; 後、printf("str=%c\n",str);の%cはchar型に対応してます。 int型は基本的に、%dです。 int str[]="abc";の部分ですがここも書き換えで、 char str[]="abc"に治すべきだなとおもいました。 printf("str=%s\n",str);の部分は、%cにすべきだと思います。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

余談ですが ISO 9899:1999 的には ・signed char の範囲は -127~127 より狭くない ・unsigned char の範囲は 0~255 より狭くない ・単に char とだけ書いたときに sign か unsigned かは処理系に依存 です. ということで「char が 7bit の環境」は存在しないはず>#5. 最低 8bit になります. 上限はないので, 9bit でもいいし 32bit でもいい.

回答No.5

一応、補足をしておきますと char の表現範囲は 8bitの場合、0~255の場合と、-128~127の場合と -127~+127の場合とあります。 ひょっとしたらそれ以外にもあるかもしれません。 -127~+127なんてのはかなり特殊な例ですが、どの範囲になるかは環境次第です。 char型に対して符号の有無を確実にしたい場合は signed/unsignedを付けて下さい。 又、charは 8ビットとは限りません。7bitや 9bitである可能性もあります。 最後に "ABC"は文字列リテラルとなりますので、char *strで受けるのは間違いではありませんが、 好ましくないので char str[] か const char *strで受けて下さい。

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.4

'a'というのは数値です。多くの処理系では、aのasciiコードである97となります。 数値ですから、当然intの初期化にも使えます。 つまり、 int str='a'; と書くのは、 int str=97; と書くのと一緒です。 一方、配列の初期化は、次のように、初期化子を用いなくてはなりません。 int str[4]={0,1,2,3}; なので、 int str[4]={'a','b,'c','\0'}; と書くことになります。 したがって、本来はchar配列の初期化も、 char str[4]={'a','b,'c','\0'}; と書かなくてはならないのです。 ただ、これでは不便なので、char配列の初期化に限り、 char str[]="abc"; と書くことができるようになっています。この特例はcharに限ったものですので、 int str[]="abc"; はエラーになります。 エラーとせずに、 int str[4]={'a','b,'c','\0'}; と、解釈してくれても良さそうなものですが、昔の偉い人が「エラーにする」と決めたので、いまでもエラーになります。 なので、違いとしては、charの配列は文字列として使うので、少々特殊な初期化ができるようになっているということですね。 なお、処理系によっては'a'が97でなかったり、ワイド文字があったりするなどありますが、それについては詳しく触れないことにします。

c-gongo
質問者

お礼

ありがとうございます!自分が聞きたい事が理解できました。

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.3

int=数値、char=文字列 だと思っていませんか? intもcharも整数型のデータを意味します。両者の違いは メモリ領域の大きさ=表現可能な範囲の違いだけです。 charは8ビットで、intはシステム依存ですが、多くは32ビットです。 C言語で"ABC"と書いた場合、文字列へのポインタを表します。 つまり、メモリ上の何処かに"ABC"という領域があり、そのメモリ上の アドレスを示します。 よって、int str[] = "ABC"; は間違いで、char *str = "ABC"; です。 また、char配列で定義するなら char str[] = {"ABC"}; のように {}で囲みます。ここだけ特例で"ABC"が各1文字ずつのコードとして 配列の各要素に振り分けられます。非常に古いCコンパイラでは char str[] = {'A','B','C',0}; のように記述する必要がありました。 このように、'A'とはAという字の文字コード(数値)を表すので、 int型変数で受けることが出来ますが、"A"は先に述べたように 文字列のアドレスを示すので、int型変数で受けることは出来ず、 文字列ポインタ型の変数で受ける必要があります。

c-gongo
質問者

お礼

ありがとうございます。

  • Yanch
  • ベストアンサー率50% (114/225)
回答No.2

char 型は、1バイトで、文字1文字を表現するのに使用するデータ型です。 int 型は、整数を表現するのに使用するデータ型で、そのサイズは、プロセッサが処理するのに都合の良いサイズとされています。 例えば、32bitCPUの環境用のコンパイラだと、intは主に32bitとして処理されます。 仮にintを32bitとして話を進めると、 char の表現範囲:-128~+127 int の表現範囲:-2147483648~+2147483647 となります。 >int str='a'; 表現範囲の狭い型charから、表現範囲の広い型intへのキャストは暗黙的に行われます。 'a'はchar型の情報です。 >int str[]="abc"; も表現範囲の狭い型char配列から、表現範囲の広い型int配列にキャストされそうですが、 これは出来ません。 何故出来ないかは、バイナリ状態のデータをダンプするとわかると思いますが、 "abc"はchar型の配列です。 内部表現は {0x61, 0x62, 0x63, 0x00}と言う感じです。 0x61は'a'を表している、0x62は'b'を表している、0x63は'cを表している。 0x00は文字列の終端である事を表しています。 c言語では、文字列の終端は0x00で表す事になっている。 そして、int型の配列の場合、その内部表現は、 例えば、int array[] = {1, 2, 3, 4}; の場合、 {0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00} と言うような感じです。 内部的なデータの持ち方が違うので、char配列から、int配列の単純な変換は出来ないと言う事です。

c-gongo
質問者

お礼

詳しい説明ありがとうございます。とてもうれしいです。こんなに詳しく教えてくれるとは。感動です。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

int型もchar型も整数型の一種ですが、文字列を表すためには文字型(char, signed char, unsigned char)を使う必要があります。

関連するQ&A

  • int型とchar型について

    C言語初心者です。 よろしくお願いします。 ◎1----------------------- #include<stdio.h> int main(void) { int ss[4]="789"; printf("%c\n",ss[0]); return 0; } --------------------------- ◎2----------------------- #include<stdio.h> int main(void) { int *p; p="789"; printf("%c\n",*p); return 0; } --------------------------- ◎1、◎2の2つのプログラムについて疑問があります。 ◎1の「int ss[4]="789";」と◎2の「int *p;」のintの部分は今まで、何の疑問も抱かず、「char」として入力していました。 そこでchar型は1バイトの整数、int型は4バイトの整数ということで容量が違うだけで、intとしても大丈夫だろうと思ったのですが、 ◎1では、「'initializing' : 'char [4]' から 'int [4]' に変換することはできません。」とエラーが出て、◎2では「'char [4]' から 'int *' に変換することはできません。」とエラーが出ます。 intは文字列は扱えないということなのでしょうか? 以上intだと実行できない理由がわかりません。 初歩的なことですいませんが、教えていただけると嬉しいです。

  • [C]char型のダブルポインタ

    粗雑で申し訳ありませんが、 以下のソースをコンパイルできましたが、 うまく実行できません。 自分なりに間違いがないと思うのですが、 間違い等をご指摘頂ければ助かります。 #include <stdio.h> void func(char **ptr) ptr[][10] か (*ptr)[] なら通る *ptr[] は通らない { printf("----- func -----"); printf("%s\n", *ptr); printf("%c\n", **ptr); putchar('\n'); } int main(void) { char str[5][10] = {"AAAAA", *str[] にすると func で **ptr で通る "BBBBB", "CCCCC", "DDDDD", "EEEEE", }; printf("----- main -----"); printf("%s\n", *str); printf("%c\n", **str); putchar('\n'); func(str); return (0); } 実行結果 ----- main ----- AAAAA A ----- func ----- Bus error (core dump) 関数への受け渡しで、型が違うというお叱りを受けますが、 コンパイルはできました。 コンパイラはCCです。 ではよろしくお願いします。

  • void **(char や intのアドレス混在)について

    printf("%d",voidd[0]);にてほしい値が表示されません。 どうすればいいですか? よろしくお願いします。 #include<stdio.h> int main() { /* Calc.StringExpressionGet("1+((2+34)*2-111*77)*5-67*8/90"); Calc.StringExpressionResolve(); Calc.Print(); */ int num[3]; num[0]=111; num[1]=222; num[2]=333; char str[4]="ABC"; void **voidd; voidd=new void*[6]; voidd[0]=(void *)&num[0]; voidd[1]=(void *)&str[0]; voidd[2]=(void *)&num[1]; voidd[3]=(void *)&str[1]; voidd[4]=(void *)&num[2]; voidd[5]=(void *)&str[2]; printf("%d",voidd[0]); getchar(); return 0; }

  • 2つのプログラムの違い

    どうしても分からなかったので投稿しました。よろしくお願いします。 #include<stdio.h> int main(void) { int c; while((c=getchar())!=EOF){ putchar(c); } return 0; } のプログラムをコマンドプロンプトで入力すると、 abc abc なんですが、 #include<stdio.h> int main(void) { int c,i; i=0; while ((c=getchar())!=EOF) { putchar(c); i++; printf("%d\n",i); } return 0; } の場合、 abc a1 a2 a3 4 になります。 自分は abc a1 a2 a3 になると思ったのですが、a3と4の隙間と4は何故出て来たのでしょうか?

  • char型+char型ってint型? if(char型==int型)?

    C言語の「汎整数拡張(インテグラルプロモーション)」というものに関するものだと思います。 char型とchar型を加えた結果は、char型でしょうか。それともint型でしょうか。 (下のプログラムの printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */ という部分の結果は4なので、int型と考えるべきなのかな。) 私は、char型とint型の加算の結果はint型だと思っていましたが、 char型とchar型の加算の結果はやはりchar型だと思っていました。 (それが間違えているのでしょうか。) if(a[0]==i) /* char型とint型の比較(?) */ の部分では、左辺はchar型、右辺はint型ですが、このように型の違う変数を比較しても文法上構わないのでしょうか。 (私は、「比較は必ず型の同じもの同士でしかできない」と思っていました。) 左辺はchar型のように見えて、じつはint型ですか。 #include <stdio.h> int main(void) { char a[4]; int i=77; printf("sizeof(int)は%d\n", sizeof(int)); printf("sizeof(char)は%d\n", sizeof(char)); printf("sizeof('M')は%d\n", sizeof('M')); printf("sizeof(a[0])は%d\n", sizeof(a[0])); a[0]='M'; a[1]=7+6; a[2]=a[0]+a[1]; printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */ printf("sizeof(+a[0])=%d\n", sizeof(+a[0])); if(a[0]==i) /* char型とint型の比較(?) */ puts("a[0]==i"); else puts("a[0]!=i"); return(0); } ちなみにワーニングもエラーもなんにもでません。

  • C言語のint型の配列が分かりません

    #include<stdio.h> int main(void) { int str[ ]={0,1,2} printf("%s\n", str); return 0; } というプログラムをC言語でつくってみましたが動きません.(012と表示されて欲しかったのですが) int str[ ]={1,2,3}の部分をchar str[ ]={'0','1','2'}とすれば動きます. そこで質問なのですが, printf("~%s~", (配列名));  はchar型の配列にしか適応できないのですか? ※追記 puts関数の定義は int puts (const char *str); であるそうなので char型の仮引数にはchar型のアドレスを渡さなければいけません. ではprintf関数の定義は一体どんなものなのですか?

  • ASCIIコード入力

    プログラムを作っていてどうしてもわからなくなりまして… #include <stdio.h> int main(void) { char c; c=38; printf("%c\n",c); return 0; } この場合は&が出てくるからいいんですけど… #include <stdio.h> int main(void) { char c; scanf("%c",&c); printf("%c\n",c); return 0; } この場合は97をscanすると9が出てきます。ASCIIコード入力でaを表示させたいんですが、何が間違っているのでしょうか? 初心者なもので…お願いしますm(__)m

  • 配列について

    初歩的な質問ですいませんが、質問よろしくお願いします。 ◎1----------------------------- #include<stdio.h> int main(void) { char ss[10]="AB"; printf("ss=%s\n",ss); return 0; } ------------------------------------ ◎2-------------------------------- #include<stdio.h> int main(void) { char ss[10]; ss[0]='A'; ss[1]='B'; ss[2]=0; printf("ss=%s\n",ss); return 0; } ----------------------------------- ◎3------------------------------- #include<stdio.h> #include<string.h> int main(void) { char ss[10]; strcpy(ss,"AB"); printf("ss=%s\n",ss); return 0; } ----------------------------------- ◎4------------------------------- #include<stdio.h> int main(void) { char ss[10]; ss="AB"; printf("ss=%s\n",ss); return 0; } ---------------------------------- 以上4つのプログラムで、◎2と◎3は正常に動くと理解できたのですが、何故、◎1は正常に動き、◎4は「'const char [3]' から 'char [10]' に変換できません。」といったようなエラーが出てしまうか分かりません。 教えていただければ嬉しいです。

  • パイプってどうやって使うの?

    1つ目のプログラムの出力を2つ目のプログラムで受け取りたいのですが、どうすればいいですか? -- 1 -- #include <stdio.h> #include <windows.h> int main(void){     int a=0;     while(1){         fprintf(stdout,"%d\n",a++);         Sleep(1000);     }     return 0; } これを2のプログラムで受け取ります。 #include <stdio.h> int main(void){     char str[128];     while(1){         if(fgets(str,sizeof(str),stdin)==NULL)             break;     printf("%s",str);     }     return 0; } これをコマンドプロンプトで 1 | 2 と入力してみましたが、何も表示されません・・。 個別に実行すると正常に動作します。 環境はXPです。どうしたら受け渡しが出来るのでしょうか?

  • C言語の初心者です。これを実行してみてください。

    「a」って打ち込んだら「a」ってでましたか? #include<stdio.h> int main(void){ char a; printf("aaa\n"); scanf_s("%c", &a); printf("%c", a); return 0; }