1、共用体占用的空间大小
共用体中各个字段都会利用同一片存储空间。共用体占用的总内存大小为各个字段中占用字节数最多的字段所占用的空间。
#include <stdio.h>
union my_register {
struct {
unsigned char byte1;
unsigned char byte2;
unsigned char byte3;
unsigned char byte4;
} bytes; //匿名结构体声明了一个结构体变量bytes
unsigned int num;
};
int main() {
union my_register un;
printf("sizeof(un)= %ld\n", sizeof(un));//4
return 0;
}
之所以 sizeof(un) 占4个字节,是因为在共用体中,bytes字段占4个字节,num字段占4个字节,所以共用体也就占用4个字节。
共用体内存占用结构图:
如下共用体 node 的内存占用结构图:
union node { //共用体占据的空间大小为8个字节
double a; //8个字节
char b; //1个字节
int c; //4个字节
};
2、使用共用体,实现IP转整数的功能
【分析】
IP的样式为"xxx.xxx.xxx.xxx",其中每个“xxx"范围都是0~255,而255的表示就是8个1。而8位为1字节,所以IP的每个”xxx“都可以用1个字节表示,且要求为无符号类型。4个部分一共就是4个字节,所以一个IP可以对应一个无符号整型的值(都是4字节)。
【代码】
#include <stdio.h>
//使用共用体实现IP转整数的功能
union IP {
struct {
unsigned char byte1;
unsigned char byte2;
unsigned char byte3;
unsigned char byte4;
} bytes;
unsigned int num; //当取得4个字节时,就获取到了一个无符号整数
};
int main() {
union IP p;
char str[100];//保存读入的IP地址
int arr[4];
while (~(scanf("%s", str))) {
sscanf(str, "%d.%d.%d.%d", arr, arr + 1, arr + 2, arr + 3); //获取IP中每个部分的值
p.bytes.byte1 = arr[0];
p.bytes.byte2 = arr[1];
p.bytes.byte3 = arr[2];
p.bytes.byte4 = arr[3];
printf("IP to int = %u\n", p. num);
}
return 0;
}
【运行结果】
192.168.0.1 //输入值
IP to int = 16820416
192.168.0.2 //输入值
IP to int = 33597632
【存在的问题】192.168.0.1与192.168.0.2之间相差了1,但是它们映射得到的整型结果并不是相差1,这是为什么呢?
【解答】这涉及到大端机和小端机,大端机:数据的低位存储在高地址位;小端机:数据的低位存储在低地址位。
内存占用图:(大端机:如果以整数来看待,1就是最低位,192就是最高位)
而当前机器是小端机,所以内存占用图应该如下:(0号字节放低位,3号字节放高位)
所以,当将其转为整数的时候,和192.168.0.2的差距就很大了。
【修改】根据小端机的特点,修改程序:
#include <stdio.h>
//使用共用体实现IP转整数的功能
union IP {
struct {
unsigned char byte1;
unsigned char byte2;
unsigned char byte3;
unsigned char byte4;
} bytes;
unsigned int num;
};
int main() {
union IP p;
char str[100];//保存读入的IP地址
int arr[4];
while (~(scanf("%s", str))) {
sscanf(str, "%d.%d.%d.%d", arr, arr + 1, arr + 2, arr + 3);
p.bytes.byte1 = arr[3];
p.bytes.byte2 = arr[2];
p.bytes.byte3 = arr[1];
p.bytes.byte4 = arr[0];
printf("IP to int = %u\n", p. num);
}
return 0;
}
【运行结果】
192.168.0.1
IP to int = 3232235521
192.168.0.2
IP to int = 3232235522
3、判断机器是大端机还是小端机
#include <stdio.h>
//判断机器是大端机还是小端机
int is_little() {
int num = 1;
//通过判断0号位字节的值是否为1来确定是否为小端机
//将当前4字节当做4字节大小的字符数组
return ((char *)(&num))[0];
}
int main() {
printf("is_little = %d\n", is_little()); //1
return 0;
}
为什么能通过判断0号字节位的值就能确定机器是大端机还是小端机呢?