前言
在C语言的学习中我们初次涉及大小端的概念,实际上在两台不同的主机上要通信时我们都需要处理大小端的问题,不然会造成数据的不一致,所以我们往后学习网络时也会涉及大小端的问题,今天就让我们来看看大小端是什么!
为什么有大小端
不同的机器内存排布顺序可以由高到低,也可以由低到高,所以有大小端一词。
大小端判定
小伙伴可以直接用下面的代码去自己的平台下跑一跑,通常我们的机子都是小端
int check_sys()
{
int a = 1;
char ch = *(char*)&a;
return ch;
}
int main()
{
if (check_sys() == 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
上面的判断方法剖析:
对于一段内存区间,我们指针访问那块内存区间的时候都是拿到的内存区间的最小地址,假如访问一个整形,我们的指针是四字节,假设是0x 00 00 00 00到0x 00 00 00 03,那么我们的指针指向的是0x 00 00 00 00,然后才会依次将数据拿上来。
现在我们的a变量是16进制表示,它的高位是在左边,低位在右边,a变量的类型是int,大于1字节,所以当他放入一块内存的时候要考虑它的字节的摆放顺序。
这里的大端:低位放到高地址处,而小端刚好相反。
上述代码char ch = *(char*)&a
就是将a变量的地址强转为char*,解引用就会拿到一个char的大小,也就是低地址上面一字节,那么通过这一个字节是0还是1我们就可以判断是大端还是小端。
方法2:采用联合体判断:
int check_sys()
{
union{
int a;
char ch;
}u;
u.a = 1;
if (u.ch = 1)
{
return 1;
}
else
{
return 0;
}
}
int main()
{
int ret = check_sys();
if (ret == 0)
{
printf("大端\n");
}
else
{
printf("小端\n");
}
return 0;
}
要弄懂上面的代码,我们首先要知道联合体是什么
联合也是一种特殊的自定义类型 这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间
union{
int a;
char ch;
}u;
联合体大小:
联合的大小至少是最大成员的大小。
当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
如下:
union Un1
{
char c[5];
int i;
};
union Un2
{
short c[7];
int i;
};
第一个为8,第二个为16。
ps:char c[5]
实际上也是按照1来对齐,实际上也就是连续放了五个char类型的变量;
有了上面的储备知识u.a = 1;
这行代码实际上就是将这块内存空间放入0x00 00 00 01进去,放进去的时候大小端的低地址的第一个字节放的内容就可以用来判断。
我们定义的char ch
通过联合体的性质我们知道是从低地址开始使用,那么我们访问ch的时候实际上就是将内存当中的第一个字节拿出来。其实和第一种方法也就一模一样了。
总结
创作不易,三连支持一下吧!!