первым увидеть этот образец кода:
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
int main()
{
union{
int32_t i32;
uint32_t u32;
int16_t i16[2];
uint16_t u16[2];
int8_t i8[4];
uint8_t u8[4];
} u;
u.u8[3] = 52;
u.u8[2] = 51;
u.u8[1] = 50;
u.u8[0] = 49;
printf(" %d %d %d %d \n", u.u8[3], u.u8[2], u.u8[1], u.u8[0]); // 52 51 50 49
printf(" %x %x %x %x \n", u.u8[3], u.u8[2], u.u8[1], u.u8[0]); // 34 33 32 31
printf(" 0x%x \n", u.i32); // 0x34333231
return 0;
}
объединение здесь только для доступа к памяти u
в 6 различных способов.
вы можете использовать u.i32
для чтения или записи, как int32_t
или
вы можете использовать u.u32
для чтения или записи, как uint32_t
или
вы можете использовать u.i16[0]
или u.i16[1]
для чтения или записи, как int16_t
или вы можете использовать u.u16[0]
или u.u16[1]
читать или писать, как uint16_t
или
или как это написать, как uint8_t
:
u.u8[3] = 52;
u.u8[2] = 51;
u.u8[1] = 50;
u.u8[0] = 49;
и читать, как это, как int8_t
:
printf(" %d %d %d %d \n", u.u8[3], u.u8[2], u.u8[1], u.u8[0]);
затем выход:
52 51 50 49
и читать как int32_t
:
printf(" 0x%x \n", u.i32);
затем выход:
0x34333231
, так как вы видите, что в этом примере объединение кода разделяет одно место памяти со многими именами/типами.
в примере кода u.i=0x3132;
это пишет 0x3132
внутри u.i
памяти, и в зависимости от порядка байтов вас система, которая является прямой порядок байтов здесь, то вы спросили printf("%s", u.s);
от компилятора, так что нам есть массив типа char
означает константный указатель на символ типа , так что это printf("%s", u.s);
будет читать u.s[0]
и печатает, что на выходе stdout
затем читает u.s[1]
и печатает это на выходе stdout
и так далее ..., пока один из этих u.s[i]
не будет равен нулю.
Это то, что делает ваш код, поэтому, если ни один из нас [0], нас [1], нас [2], нас [3] не равен нулю, тогда память за пределами вашего союза будет считана до тех пор, пока не будет найден один нуль или система ошибка памяти error
бывает.
'u.s' не является строкой, и вы не можете использовать'% s' для печати. Это технически неопределенное поведение. Сказав это, учтите, что '0x31 == 49 == '1'' и' 0x32 == 50 ==' 2'' и, надеюсь, это должно быть ясно для вас. – kaylum
Последние две группы из 8 бит (в малочисленных концах) '0011 0010' и' 0011 0001', которые в шестнадцатеричном виде являются '32' и' 31', которые в ASCII являются '' 2'' и '' 1'' , –
Предполагая, что sizeof (int) равно 4 без каких-либо битов заполнения, а порядок байтов - немногочисленный и ascii-кодирование, то это поведение определено. – 2501