c语言中联合的输出问题

请问给数组i赋值后,为什么数组c也都得到了这些不变的值?
c[0]=39,c[1]=0,c[2]=0,c[3]=0.

#include<stdio.h>
int main()
{
    union
    {
        int i[2];
        long k;
        char c[4];
    }r,*p=&r;
    p->i[0]=0x39;
    p->i[1]=0x38;
    printf("%x %x %x %x %x %x",p->c[0],p->c[1],p->c[2],p->c[3],p->i[0],p->i[1]);
    return 0;
}

因为union中的属性使用的是相同的内存空间,只是表示的不一样而以,以你的这个代码为例,在32位机上,union变量的最大内存空间是8个字节int i[2],给i数组赋值后,整个8个字节就有数据了,只是不同的字节上数据不一样,这样取k和c的值时,会根据数据类型取指定字节长度的数据,所以也就有数据了。而计算机中表示多字节数据时有大小端的概念,X86是小端模式,既高字节保存在高地址。一个int所占用的内空间刚好是char c[4]所占用的内存空间。i和c的起始地址一样,c占用的内存空间是i[0]的空间,变量的地址分配为高地址往低地址方向,而i[0]的低地址存储i的低位数据0x39,所以c[0]是0x39。

union的概念和大小端模式。

由于这个整数在内存中是以小端字节序存储的,因此它的低字节0x38存储在联合体的第一个字符元素c[0]中,而高字节0x39存储在联合体的第二个字符元素c[1]中。因此,输出结果中的第一个字节是0x39,而不是0x38。

union是一种特殊的数据类型,它允许在同一内存位置存储不同的数据类型。联合体中的每个元素都从同一内存位置开始,因此修改其中任何一个元素都会影响其他元素。联合体通常用于处理位字段和其他需要在不同数据类型之间进行转换的情况