- ベストアンサー
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[]);
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
>実はある学習用コンパイラは正しく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); 本当はデバッガを使いこなせるといいんですけどね。
その他の回答 (7)
#6 のお礼に関してです。 int aaa[]="abc" ;//わざとintにした このような初期化は規格上許されないと思いますが。 # 普通はパイルエラーになるはず。 コンパイラをは何をお使いですか?
お礼
今回の件は、フリーソフトのC machineというものを使いました。 今は配布中止になっているようですね。 いつもはVC++6.0を使っているのでエラーが出ます。
- gimmick
- ベストアンサー率49% (134/270)
>知りたいのは、あるコンパイラは以下のようにしても>正しく表示されるのですが、どうしてかということでした。 >int aaa[]="abc" ;//わざとintにした >printf("%s\n",aaa); 下のコードと同じような処理になっていると思います。 int *aaa = (int*)"abc"; //char*をint*にキャスト printf("%s\n", (char*)aaa); //関数内ではaaaがchar*として扱われる
お礼
回答ありがとうございます。 #6の補足に書いた方法で確認しました。 結局、おっしゃっているようにcharで宣言したのと同じになっているようですね。
- tatsu99
- ベストアンサー率52% (391/751)
#2です。 >ところで、どうして数字が右詰で確保されないのでしょうか? >0x00,0x00,0x00,0x41...aaa[0] 上記のように右詰で確保されるものをビッグエンディアンと呼びます。これはSunのSparc系、HPのモトローラ系のマシンで採用されています。一方、今回のように左詰で格納される方式をリトルエンディアンとよび、インテル86系のマシン(要はMAC以外の通常のパソコン)では、この方式をとります。 ビッグエンディアンのほうが人間の間隔にマッチしているので、私個人としては、ビッグエンディアンのほうが好みです。どちらが良いかが議論されることがあるそうですが、特にどちらが良いという結論はないようです。プログラマーとしては、そのマシンがどちらで実装されているかを意識しておいたほうが良いでしょう。特にビットの操作を行う場合は、ビッグかリトルかで処理内容が変わってきます。
お礼
回答ありがとうございます。 良く分かりました。
- wogota
- ベストアンサー率42% (66/154)
x86系(リトルエンディアン)では、printf文の直前の段階で aaa[4]に、0x41,0x00,0x00,0x00,0x42,0x00,0x00,… というような内容が格納されます。 よって、%sで表示すると、0x41,0x00という文字列とみなして Aとだけ表示されます。 配列のメモリの取り方などは、CPUのエンディアンやコンパイラの 実装によって変わってきますので、全ての環境でこのような 結果になるとは限りません。
お礼
回答ありがとうございます。 実はある学習用コンパイラは正しくABCと表示するのですが、これはいったいどうなっているのでしょうか? 推定で構わないので、お分かりでしたら回答お願いします。
- hinebot
- ベストアンサー率37% (1123/2963)
#1です。 intが32bit系の場合は、※の部分は#2の方のようになります。
お礼
回答ありがとうございます。 #2のお礼の疑問もお分かりでしたら、 よろしくお願いします。
- tatsu99
- ベストアンサー率52% (391/751)
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を意味します。
お礼
回答ありがとうございます。 aaa[0]=0x4141;→AA aaa[0]=0x41414141;→AAAAB となったので、おっしゃっているようにメモリ上に確保されているらしいことが確認できました。 ところで、どうして数字が右詰で確保されないのでしょうか? 0x00,0x00,0x00,0x41...aaa[0]
- hinebot
- ベストアンサー率37% (1123/2963)
恐らくですが、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'; としているのと同じことになっているのではないでしょうか?
お礼
回答ありがとうございます。
お礼
>>実はある学習用コンパイラは正しくABCと表示するの >>ですが、これはいったいどうなっているのでしょうか? すみません。これは私の勘違いでした。 知りたいのは、あるコンパイラは以下のようにしても正しく表示されるのですが、どうしてかということでした。 int aaa[]="abc" ;//わざとintにした printf("%s\n",aaa);
補足
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]); こんな感じでメモリ上にどう並んでいるか確認して ようやく理解できました。