2016-02-19 10 views
5

だから私は、アーキテクチャのエンディアンがどのように見つかったのかといういくつかの例を見ました。 intデータ型を指す整数ポインタがあるとします。そして、int値が0x010A0B12だとしましょう。リトルエンディアンアーキテクチャでは、最下位バイト、すなわち12が最下位メモリアドレスに格納されます。したがって、4バイト整数の最下位バイトは12になります。型キャストcharポインタを整数ポインタ

今すぐチェックしてください。 charポインタpを宣言し、char *への整数型ポインタをキャストしてpに格納し、pの逆参照された値を出力すると、アーキテクチャのエンディアンにヒントが得られます。それが12なら、私たちはリトルエンディアンです。 01はビッグエンディアンを意味します。これは本当に、質問の

int a = 0x010A0B12; 
int *i = &a; 
char *p = (char*)i; 
printf("%d",*p); // prints the decimal equivalent of 12h! 

カップルここに...本当にきちんと聞こえます。ポインタは厳密に型付けされているので、文字ポインタは厳密にcharデータ型を指してはいけませんか? %dで印刷するとどうなりますか?文字ではなく、%cで印刷するべきですか?

+0

関連:http://stackoverflow.com/questions/34826036/confused-about-pointer-dereferencing?noredirect = 1&lq = 1 –

答えて

6

ポインタが強く型付けされているので、文字ポインタが厳密にcharデータ型を指してはいけませんか?

Cは、任意のポインタを安全char*およびvoid*に変換することができる規則を有しています。したがって、int*char*に変換することができ、移植も可能です。ポインタは、intの内部表現の最初のバイトを指しています。

は我々ではなく、文字のために、%cを印刷しないでしょうか?

可変長引数リストprintfもここにあります。型なしのパラメータprintfcharを渡すと、デフォルトの変換が適用されます。charintに変換されます。だから、%d形式は数字をうまく使い、期待通りに印刷します。

%cも使用できます。 %c指定子を処理するコードは、引数をintとして読み取り、に変換します。 0x12は特殊な文字なので、一様な印刷物は表示されません。

+0

おかげさまで、あなたが話している "printfのタイプのないパラメータ"は何ですか? – nirvanaswap

+0

@nirvanaswap 'print'の署名の最後にある3つのドット' ... '、つまり' int printf(const char * format、...) 'は任意の型の引数を渡すことを指定します。 – dasblinkenlight

-2

ポインタが強く型付けされているので、文字ポインタが厳密にcharデータ型を指してはいけませんか?

これは、定義されていない動作ですが、ほとんどの正常な実装では意味があります。だからほとんどの人はそれにokと言うだろう。

%dで印刷するとどうなりますか?

形式%dはint型の引数を必要とし、char型の実際のargは通常のCの規則でint型に昇格します。だからもう一度OKです。 pが指すバイトの内容は、常に有効なテキスト文字ではなく、任意のバイトである可能性があるので、おそらく%cを使用したくないでしょう。

+1

私は逆参照していますので、明らかに%pは私が探しているものではありませんか? – nirvanaswap

+2

OPのコードには未定義の動作はありません。 – dasblinkenlight

+0

@nirvanaswap:はい、申し訳ありませんが、私はこれを編集しました。 dasblinkenlightへ:未定義の動作があります。メモリ内の任意のバイトを個別にアドレス指定してアクセスできるという前提です。通常、これは当てはまりますが、OPが32ビットハードウェアレジスタの中間バイトにアクセスしようとしていることを想像してください.32ビットハードウェアレジスタは、32ビット全体とアライメントされたアドレスでのみ読み取ることができます。実行時の例外が発生します。 – ddbug

関連する問題