• ベストアンサー

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[]);

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

  • ベストアンサー
  • 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