0

タイトルが示すように、次のコードを実行すると「奇妙な」結果が得られます。

#include <stdio.h>

int main()
{
    char buff[4] = {0x17, 0x89, 0x39, 0x40};
    unsigned int* ptr = (unsigned int*)buff;
    char a = (char)((*ptr << (0*8)) >> (3*8));
    char b = (char)((*ptr << (1*8)) >> (3*8));
    char c = (char)((*ptr << (2*8)) >> (3*8));
    char d = (char)((*ptr << (3*8)) >> (3*8));

    printf("0x%x\n", *ptr);
    printf("0x%x\n", a);
    printf("0x%x\n", b);
    printf("0x%x\n", c);
    printf("0x%x\n", d);

    return 0;
}

出力:

0x40398917
0x40
0x39
0xffffff89
0x17

取得できないのはなぜ0x89ですか?

4

3 に答える 3

0

キャストを使用memcpyしない

char buff[4] = {0x17, 0x89, 0x39, 0x40};
unsigned int* ptr = (unsigned int*)buff;

これは正しくありません: buffint オブジェクトまたは配列を指していないため、キャスト(unsigned int*)buffが定義されていません。

をisbuffとして再解釈する安全な方法は次のとおりです。unsigned intmemcpy

char buff[4] = {0x17, 0x89, 0x39, 0x40};
unsigned int ui;
assert (sizeof ui == sizeof buff);
memcpy (buff, &ui, sizeof ui);

もちろん、を使用memcpyする場合、コピーするビット表現が宛先タイプに対して有効であることを確認する必要はありません。

これを行うための移植可能ではあるが縮退した方法の 1 つは、表現が既存のオブジェクトと一致することを確認することです (以下はばかげたコードであることに注意してください)。

char *null_ptr = 0;
char null_bytes[sizeof null_ptr] = {0};
if (memcmp (null_ptr, null_bytes, sizeof null_bytes)==0) {
    char *ptr2;
    memcpy (null_bytes, ptr2, sizeof null_bytes);
    assert (ptr2 == 0);
}

このコードはmemcpy、完全に定義された動作を使用し、完全に定義しています (役に立たない場合でも)。OTOHの振る舞い

int *ptr3 = (int*)null_bytes;

はまたはnull_bytesのアドレスではないため、定義されていません。intunsigned int

于 2013-07-03T02:40:40.277 に答える