一道面试题:判断当前计算机的大小端存储

1,269 阅读3分钟

这个程序我将会用两种不同的方法来模拟实现,在此之前如果有不清楚大小端是啥的朋友可以去看看我的另一篇博客,里面有详细介绍,链接如下:juejin.cn/post/705741… ,咱废话不多说,现在开始。

思路: 要判断当前计算机存放地址时是用大端存储还是小端存储,我们首先要知道地址在内存中是从左到右由低到高变化的,其次关键的点就是弄清一个数存放在内存中的第一个字节的内容是什么,举个例子:比如说定义一个int类型的整数1,因为int类型在内存中是以二进制补码的数值存储,存到内存中时是以16进制的形式存储,因此整数1写成16进制数就是00 00 00 01(4个2进制数转换1个16进制数),其低数值位为01,高数值位为00,因为大端存储是低数值位存放到高地址处,小端存储是低数值位存放到低地址数,若我们读取它的第一个字节的内容为0,则说明高数值位00被存放到低地址处,因此为大端存储;若其第一个字节内容为1,则说明低数值位01被存放到低地址处,因此为小端存储。那么如何读取一个数的第一个字节的内容呢?这里我们归纳了两种方法:

方法一,指针解引用:

在学习指针这一章节时,我们知道了有char这一类型的指针,而char* 刚好就是一个字节,因此我们可以通过强制类型转换,将整型指针(int*)强制转换为字符指针(char*),再对char* 进行解引用,得出来的值刚好就是第一个字节的内容,代码如下:

#include<stdio.h>
int check_sys()
{
	int i = 1;//00 00 00 01
	if (*((char*)&i) == 1)//将int*强制类型转换为char*再解引用
	{
		return 1;//小端
	}
	else
	{
		return 0;//大端
	}
}

int main()
{
	int ret=check_sys();
	if (ret == 1)
	{
		printf("小端\n");//低数值位放低地址处
	}
	else
	{
		printf("大端\n");//低数值位放高地址处
	}
	return 0;
}

调试结果:

屏幕截图 2022-02-11 151807.png 输出结果:

image.png


方法二,巧妙运用联合体:

:如果有不清楚联合体的同学可以看看我的另一篇博客,里面有详细的解释,链接地址如下: juejin.cn/post/706665…

我们知道,联合体中的成员是共用同一块空间的,这时我们可以利用这一特性来访问一个数第一个字节的内容,比如说如下联合体:

union Un
{
	char c;
	int  i;
}

该联合体中的c和i就共用一个字节的空间,因此我们可以为i赋值1,这个1就占四个字节的空间,然后再取出c,若这个1在这4个字节的空间中是以大端模式存储的,则c的值就应该为0,若以小端模式存储,则c的值就应该为1。

image.png

代码如下:

#include<stdio.h>
int check_sys()
{
	union U  //创建联合体U
	{
		char c;
		int i;
	}un;
	un.i = 1;  //为i赋值1
	return un.c;  
	//若c的值为0,则返回0;若c的值为1,则返回1
	 
}

int main()
{
	int ret=check_sys();
	if (ret == 1)
	{
		printf("小端\n");//低数值位放低地址处
	}
	else
	{
		printf("大端\n");//低数值位放高地址处
	}
	return 0;
}

调试结果:

image.png 输出结果:

image.png


这道题的介绍到这里就结束了,如果你觉得本篇文章对你多少有些帮助,可以点个赞或者点一波收藏支持一下哦,欢迎各位大佬批评指正,咱们下一道题目再见!