int to char casting

前端 未结 4 1598
鱼传尺愫
鱼传尺愫 2020-12-16 18:41
int i = 259;       /* 03010000 in Little Endian ; 00000103 in Big Endian */
char c = (char)i;  /* returns 03 in both Little and Big Endian?? */

In

相关标签:
4条回答
  • 2020-12-16 19:08

    Since you're casting from a larger integer type to a smaller one, it takes the least significant part regardless of endianness. If you were casting pointers instead, though, it would take the byte at the address, which would depend on endianness.

    So c = (char)i assigns the least-significant byte to c, but c = *((char *)(&i)) would assign the first byte at the address of i to c, which would be the same thing on little-endian systems only.

    0 讨论(0)
  • 2020-12-16 19:16

    When casting from int(4 bytes) to char(1 byte), it will preserve the last 1 byte. Eg:

    int x = 0x3F1;         // 0x3F1 = 0000 0011 1111 0001
    char y = (char)x;      // 1111 0001  --> -15 in decimal (with Two's complement)
    char z = (unsigned char)x;    // 1111 0001 --> 241 in decimal
    
    0 讨论(0)
  • 2020-12-16 19:18

    Endianness doesn't actually change anything here. It doesn't try to store one of the bytes (MSB, LSB etc).

    • If char is unsigned it will wrap around. Assuming 8-bit char 259 % 256 = 3
    • If char is signed the result is implementation defined. Thank you pmg: 6.3.1.3/3 in the C99 Standard
    0 讨论(0)
  • 2020-12-16 19:20

    If you want to test for little/big endian, you can use a union:

    int isBigEndian (void)
    {
        union foo {
            size_t i;
            char cp[sizeof(size_t)];
        } u;
    
        u.i = 1;
        return *u.cp != 1;
    }
    

    It works because in little endian, it would look like 01 00 ... 00, but in big endian, it would be 00 ... 00 01 (the ... is made up of zeros). So if the first byte is 0, the test returns true. Otherwise it returns false. Beware, however, that there also exist mixed endian machines that store data differently (some can switch endianness; others just store the data differently). The PDP-11 stored a 32-bit int as two 16-bit words, except the order of the words was reversed (e.g. 0x01234567 was 4567 0123).

    0 讨论(0)
提交回复
热议问题