• ベストアンサー

int型の文字について

文字も結局は数字とうことで、以下のようにしてみましたが、ABCとは表示されずAしか表示されません。 どうしてintだとAしか表示されないのですか? int aaa[4] ;//わざとintにした aaa[0]=0x41; aaa[1]=0x42; aaa[2]=0x43; aaa[3]='\0'; printf("%s\n",aaa[]);

  • mk1234
  • お礼率94% (1832/1940)

質問者が選んだベストアンサー

  • ベストアンサー
  • onosuke
  • ベストアンサー率67% (310/456)
回答No.6

>実はある学習用コンパイラは正しくABCと表示するの >ですが、これはいったいどうなっているのでしょうか? intが8bitの処理系なら,一応そうなりますね。 (エミュレータとセットなのかな?) こんなコードを走らせて,その実行結果をいろいろ考えると理解が深まるかも。 int i[4]={ 0x41,0x42,0x43,'\0'}; short s[4]={ 0x41,0x42,0x43,'\0'}; long l[4]={ 0x41,0x42,0x43,'\0'}; char c[4]={ 0x41,0x42,0x43,'\0'}; printf("int %x \n", *(int*)i); printf("short %x \n", *(int*)s); printf("long %x \n", *(int*)l); printf("char %x \n", *(int*)c); 本当はデバッガを使いこなせるといいんですけどね。

mk1234
質問者

お礼

>>実はある学習用コンパイラは正しくABCと表示するの >>ですが、これはいったいどうなっているのでしょうか? すみません。これは私の勘違いでした。 知りたいのは、あるコンパイラは以下のようにしても正しく表示されるのですが、どうしてかということでした。 int aaa[]="abc" ;//わざとintにした printf("%s\n",aaa);

mk1234
質問者

補足

int hoge=0x123456; unsigned char *p_hoge=(unsigned char*)&hoge; printf("%x \n", p_hoge[0]); printf("%x \n", p_hoge[1]); printf("%x \n", p_hoge[2]); こんな感じでメモリ上にどう並んでいるか確認して ようやく理解できました。

その他の回答 (7)

noname#5537
noname#5537
回答No.8

#6 のお礼に関してです。 int aaa[]="abc" ;//わざとintにした このような初期化は規格上許されないと思いますが。 # 普通はパイルエラーになるはず。 コンパイラをは何をお使いですか?

mk1234
質問者

お礼

今回の件は、フリーソフトのC machineというものを使いました。 今は配布中止になっているようですね。 いつもはVC++6.0を使っているのでエラーが出ます。

  • gimmick
  • ベストアンサー率49% (134/270)
回答No.7

>知りたいのは、あるコンパイラは以下のようにしても>正しく表示されるのですが、どうしてかということでした。 >int aaa[]="abc" ;//わざとintにした >printf("%s\n",aaa); 下のコードと同じような処理になっていると思います。 int *aaa = (int*)"abc"; //char*をint*にキャスト printf("%s\n", (char*)aaa); //関数内ではaaaがchar*として扱われる

mk1234
質問者

お礼

回答ありがとうございます。 #6の補足に書いた方法で確認しました。 結局、おっしゃっているようにcharで宣言したのと同じになっているようですね。

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.5

#2です。 >ところで、どうして数字が右詰で確保されないのでしょうか? >0x00,0x00,0x00,0x41...aaa[0] 上記のように右詰で確保されるものをビッグエンディアンと呼びます。これはSunのSparc系、HPのモトローラ系のマシンで採用されています。一方、今回のように左詰で格納される方式をリトルエンディアンとよび、インテル86系のマシン(要はMAC以外の通常のパソコン)では、この方式をとります。 ビッグエンディアンのほうが人間の間隔にマッチしているので、私個人としては、ビッグエンディアンのほうが好みです。どちらが良いかが議論されることがあるそうですが、特にどちらが良いという結論はないようです。プログラマーとしては、そのマシンがどちらで実装されているかを意識しておいたほうが良いでしょう。特にビットの操作を行う場合は、ビッグかリトルかで処理内容が変わってきます。

mk1234
質問者

お礼

回答ありがとうございます。 良く分かりました。

  • wogota
  • ベストアンサー率42% (66/154)
回答No.4

x86系(リトルエンディアン)では、printf文の直前の段階で aaa[4]に、0x41,0x00,0x00,0x00,0x42,0x00,0x00,… というような内容が格納されます。 よって、%sで表示すると、0x41,0x00という文字列とみなして Aとだけ表示されます。 配列のメモリの取り方などは、CPUのエンディアンやコンパイラの 実装によって変わってきますので、全ての環境でこのような 結果になるとは限りません。

mk1234
質問者

お礼

回答ありがとうございます。 実はある学習用コンパイラは正しくABCと表示するのですが、これはいったいどうなっているのでしょうか? 推定で構わないので、お分かりでしたら回答お願いします。

  • hinebot
  • ベストアンサー率37% (1123/2963)
回答No.3

#1です。 intが32bit系の場合は、※の部分は#2の方のようになります。

mk1234
質問者

お礼

回答ありがとうございます。 #2のお礼の疑問もお分かりでしたら、 よろしくお願いします。

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.2

aaa[0]=0x41; aaa[1]=0x42; aaa[2]=0x43; aaa[3]='\0'; とすると、内部メモリ上では、 0x41,0x00,0x00,0x00 ....aaa[0] 0x42,0x00,0x00,0x00 ....aaa[1] 0x43,0x00,0x00,0x00 ....aaa[2] 0x00,0x00,0x00,0x00 ....aaa[3] と確保されます。 ここで、printf("%s\n",aaa[]); とすると、0x41がAとなり、次が0x00ですから終端となり Aのみが表示されます。'\0'は0x00を意味します。

mk1234
質問者

お礼

回答ありがとうございます。 aaa[0]=0x4141;→AA aaa[0]=0x41414141;→AAAAB となったので、おっしゃっているようにメモリ上に確保されているらしいことが確認できました。 ところで、どうして数字が右詰で確保されないのでしょうか? 0x00,0x00,0x00,0x41...aaa[0]

  • hinebot
  • ベストアンサー率37% (1123/2963)
回答No.1

恐らくですが、intが16bitの処理系であるため、 aaa[0]=0x41; aaa[1]=0x42; aaa[2]=0x43; としたとき、実際のメモリー上の並びが(low-highとして) 41,00,42,00,43,00,00,00   ※ となり、char型で caaa[0]=0x41; caaa[0]='\0'; としているのと同じことになっているのではないでしょうか?

mk1234
質問者

お礼

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

関連するQ&A

  • int型での文字列の扱いについて

    整数は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型では文字列が扱えないのか理解できません。

  • intに文字

    int x; printf("数字:"); scanf("%d",&x); としたとき xに数字じゃなく文字が入力した場合に これをもう一回表示させるのにいい方法ありますか?

  • 文字列を大文字にするプログラムがわかりません。

    小文字を大文字に、大文字はそのまま、それ以外は表示しないプログラムなんですが、 「それ以外を表示しない」というところが書けません。 #include <stdio.h> int main(void) { char x; char *p; puts("文字列を入力"); scanf("%s", &n); for(p = &n; *p != '\0'; p++){ if(*p >= 'a' && *p <= 'z'){ *p = *p - 'a' + 'A'; } } printf("%s\n", &n); return 0; } これではもちろん数字などはそのまま表示されてしまいます。 しかも、4文字までは普通に大文字で表示されるんですが 6文字だとcoredumpedしてしまいます。 すいませんが、ソース書いて教えていただけると嬉しいです。

  • strtokでの空文字への置き換え

    大したことじゃないと言えばそうかもしれませんが、ちょっと氣になるんで質問させてください。 C言語でstrtokという函數ありますよね。 第1引數の文字列を、第2引數の文字列を構成する文字で區切る。 第2引數の文字を見つけたら、それを空文字('¥0')に置き換える。 字句の最初の文字へのポインタを返す。 このようなものだと理解しています。 次のプログラムを實行してみました。 #include <stdio.h> #include <string.h> int main(void) { char string[]="XYZ1231ABC"; int i; printf("%s\n", string); putchar('\n'); printf("%s\n", strtok(string, "1A")); printf("%s\n", strtok(NULL, "1A")); printf("%s\n", strtok(NULL, "1A")); printf("%s\n", strtok(NULL, "1A")); putchar('\n'); for(i=0; i<=10; i++) printf("string[%d]=%c\n", i, string[i]); return 0; } 結果 XYZ1231ABC XYZ 23 BC (null) string[0]=X string[1]=Y string[2]=Z string[3]= string[4]=2 string[5]=3 string[6]= string[7]=A string[8]=B string[9]=C string[10]= 私が思うには、string[7]は空文字に置き換わってしまうはずだと思うんですが、 結果は'A'のままです。 ここが '¥0'に置き換わるかどうかは しょり系によって異なるのでしょうか。

  • 文字列をint型へ変換するには?

    c言語初心者です。 こちらのプログラムだとうまく表示されません何故でしょう? わかる方是非教えていただきたいと思います。 #include<stdio.h> #include <stdlib.h> int main() { int  num ;     char sum1[4]; printf("数字 str1 =>"); scanf("%d",&num); num= atoi(sum11); printf("sum1= [%d]\n",num); } コマンドに数字を入力したあとintに変換してnumに表示させたいのですが、、、、

  • int型とfloat型の演算結果

    C初心者です。 int型とfloat型で割り算をして処理を表示させてます。 以下、実処理の一部です。 int a; int b; a = 3; b = 2; (1) printf("答え=%d:1のはず\n",a/b); (2) printf("答え=%d:1のはず\n",a/(float)b); (3) printf("答え=%d:1のはず\n",(float)a/b); (4) printf("答え=%d:1のはず\n",(float)a/(float)b); 私の予想では(1)~(4)まですべて1が表示されると思っていました。 実際は(1)のみ1で(2)~(4)は0でした。 (2)~(4)はなぜ0と表示されるのですか? ・整数型と実数型で演算した場合、実数型に合わせられてること ・表示が整数型であること なので1が表示されると予想したのですが・・・。

  • 入力文字と配列がわからない><

    文字列と配列がよくわかりません・・・。 以下のプログラムで「おく」と入力すると ・ ィ と表示されます・・・。 何がおかしいのでしょうか; int main(){   char a[4];   scanf("%s", a);   printf("a[0] = %c \na[1] = %c \n", a[0], a[1]); }

  • 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の使い方と違いについて詳しく教えてほしいです>< お願いします。

  • C言語 文字列の比較 compare

    プログラミング初心者です。 60文字以内の文字列を入力して、 大小関係を比較・表示するプログラムなのですが・・ 「AはBより大きい」という結果しか出ません。 どこが間違っているのか、ご指摘お願いしますっ。 #include<stdio.h> int main(void) { char moji1[61]; char moji2[61]; printf("文字列Aを入力===>"); scanf("%60s" ,&moji1); printf("文字列Bを入力===>"); scanf("%60s" ,&moji2); if(moji1-moji2>0){ printf("===AはBより大きい===\n"); } else if(moji1-moji2<0){ printf("===AはBより小さい===\n"); } else if(moji1-moji2==0){ printf("===AとBは等しい===\n"); } return 0; } int compare(char *x, char*y) { while(*x==*y){ if(*x=='\0') return 0; x++; y++; } return (*x-*y); }

  • 文字列のswap

    文字列をswapするプログラムを作りたいと思っています。 やってみると、最初の一文字しかswapされません。 どうしてこれではいけないのでしょうか? よろしくお願いします。 以下が作ったプログラムです。 #include<stdio.h> void swap(char *a,char *b); int main() { char a[2][5]={"abc","efg"}; printf("befor a[0]:%s a[1]:%s?n",a[0],a[1]); swap(&a[0],&a[1]); printf("after a[0]:%s a[1]:%s?n",a[0],a[1]); } void swap(char *a,char *b) { char *tmp; tmp=*a; *a=*b; *b=tmp; } 実行結果は befor a[0]:abc a[1]:efg after a[0]:ebc a[1]:afg となります。 befor a[0]:abc a[1]:efg after a[0]:efg a[1]:abc となって欲しいです。

専門家に質問してみよう