![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
C言語を習い始めた者ですが、ビット幅とその出力についてわからないことが二つでてきました。以下のソースコードを見てください。
#include <stdio.h>
int main(void)
{
char ss[] = "ABCDEF";
void *vpt;
int idt;
vpt = ss;
idt = * (char *)vpt;
printf("char:%x\n", idt);
idt = *(int *)vpt;
printf("char:%x\n", idt);
return 0;
}
出力結果は
char:41
char:44434241
となります。
一つ目のわからないことは char:41 についてです。私はchar型のビット幅は8ビットで文字ABの16進数を出力すると予想していました。ところが結果は 文字A の16進数の41のみが出力されました。Aの二進数は
1010、 Bの二進数は1011で それぞれ4ビットずつ持っていて合わせて8ビットになるのでそう考えていました。よくわかりませんが結果から、文字一文字に対して8ビットつまり1バイトに相当するのでしょうか?
二つ目は char:44434241 についてです。一つ目の質問に書いた推測が正しければ1文字を1バイトと考えて16進数にすると Aは41 Bは42 Cは43 Dは44 になります。しかしポインタの先頭のアドレスはAになっているはずなのになぜか出力は char:41424344 ではなくchar:44434241になっています。順序が逆になっているのでしょうか?
Cをはじめたばかりなので基本的なところがわかっていないかもしれませんが、説明に不足があればつけたしますのでどうかよろしくお願いします。
No.3ベストアンサー
- 回答日時:
まず
>char ss[] = "ABCDEF";
ですが、これは
'A','B','C','D','E','F','\0'
が配列に格納されます。
'A' = 文字Aを表す文字コード = 0x41です。
0x0Aではありませんし、1011という4ビットの数字でもありません。
従って
>idt = * (char *)vpt;
>printf("char:%x\n", idt);
は、ポインタの指す中身をchar(8bit)として取り出して、int(ここでは32bitかな?)に格納し、16進数で表示していますから、41と表示されます。
続いて、
>char:44434241
の件ですが、ご使用の環境はint型が32bitでintelのx86系でしょうか?
>idt = *(int *)vpt;
でポインタの指す中身を32bitの整数として取り出している訳なんですが
intelのx86系のCPUではリトルエンディアンといって、整数の上位と下位を入れ替えてメモリに配置します。
たとえば 0x12345678 という数値はメモリ上 0x78 0x56 0x34 0x12 と配置されます
つまり、0x41 0x42 0x43 0x44 と配置されたデータを整数として表現すると0x44434241となってしまうわけです。
エンディアンについて参考URLいれておきます。
参考URL:http://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%B3% …
ウィキベィアでエイディアンについて読みました。初めてエイディアンという言葉を知りました。私のはご指摘いただいたとおりリトルエイディアンでした。なぜ逆になるのかわからなかったのですがエイディアンの機能について参考URLより確認し理解することができました。本当にありがとうございました。
No.5
- 回答日時:
おそらく他の方が回答されている通りだとは思いますが、処理系不明の状況で勝手に決めつけるのは正しい姿勢とはいえません。
一般論で回答すると...
> 私はchar型のビット幅は8ビットで文字ABの16進数を出力すると予想していました。
char型のビット幅は処理系定義です。<limits.h>のCHAR_BITマクロを調べてください。出力された41は'A'の値です。ただし、文字コードがASCIIかどうかは分かりません。シフトJISやEUC-JPかもしれませんし、UTF-8かもしれません。TRONコードかもしれません。もっと別の文字コードの可能性もあります。
> Aの二進数は1010、 Bの二進数は1011で それぞれ4ビットずつ持っていて合わせて8ビットになるのでそう考えていました。
処理系に関わらず、そんなことにはなりません。
> 文字一文字に対して8ビットつまり1バイトに相当するのでしょうか?
'A'や'B'のような基本実行文字集合に属している文字は、1バイトに相当します。ただし、8ビットかどうかは(前述の通り)処理系に依存します。つまり、1バイトが8ビットかどうかは処理系に依存します。
> 一つ目の質問に書いた推測が正しければ1文字を1バイトと考えて16進数にすると Aは41 Bは42 Cは43 Dは44 になります。しかしポインタの先頭のアドレスはAになっているはずなのになぜか出力は char:41424344 ではなくchar:44434241になっています。順序が逆になっているのでしょうか?
ある型のポインタを、要求する境界調整が異なる型へのポインタにキャストし、参照外しを行った場合の動作は未定義です。バイトオーダー(エンディアン)云々以前に、まったくデタラメの値だったとしても文句はいえません。
No.2
- 回答日時:
2つ目の質問に関しては、No.1さんの言われる通り、リトルエンディアンだからですが、
1つ目の質問に関しては根本的に16進数とASCIIコードを混同されています。
16進数の値:0xABとABのキャラクターコードは全く別な値です。
参考URL:http://www9.plala.or.jp/sgwr-t/c_sub/ascii.html
No.1
- 回答日時:
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# const char** p;のとき、free(p)でC4090エラーとなるのはなぜですか 3 2023/03/31 16:28
- C言語・C++・C# 【C言語】全角文字の配列を、全角のまま1文字ずつ出力する方法 4 2023/05/09 15:08
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# C言語で再起関数とポインタを用いて文字列反転をする方法がわかりません。 4 2023/04/29 20:32
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
小数点入りの文字列をfloat型に...
-
C言語にて構造体のメンバがNULL...
-
char*を初期化したいのですが
-
csvファイルをfscanfで読み込む...
-
ポインタ配列
-
const char* s1とただのchar s1...
-
fread()関数とfwrite()関数につ...
-
ポインタを使って回文かどうか...
-
'\\0'とはなんですか?
-
c言語でポインタ変数を用いた配...
-
strcat関数を自作したいです
-
char 文字列型 の表現範囲が-12...
-
Run-Timeエラーの原因に関して...
-
ASCIIコードへの変換方法
-
VC++6.0にて、文字列処理にて困...
-
fstream型オブジェクトを関数の...
-
charポインタへの文字列による...
-
char AA[]{"全角文字"};から"全...
-
C言語のintとcharの違いってな...
-
CStringからchar*への型変換に...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語のintとcharの違いってな...
-
char*を初期化したいのですが
-
C言語にて構造体のメンバがNULL...
-
CStringからchar*への型変換に...
-
strcat関数を自作したいです
-
new charとnew char[N]の違いは?
-
csvファイルをfscanfで読み込む...
-
char型にint型の数値を代入する。
-
動的メモリの初期化方法について。
-
C言語で文字列をかえす正しい書...
-
文字列str内の全ての数字を...
-
char 文字列型 の表現範囲が-12...
-
DWORDとcharの変換
-
fstream型オブジェクトを関数の...
-
小数点入りの文字列をfloat型に...
-
C言語のプログラムについてです
-
const char* s1とただのchar s1...
-
文字列内の数字削除
-
c言語でポインタ変数を用いた配...
-
szとlpszの違い
おすすめ情報