计算机系统用小端(Little Endian)和大端(Big Endian)来描述多字节数据的存储地 址顺序模式,其中小端表示将低位字节数据存储在低地址的模式、大端表示将高位字节数 据存储在低地址的模式。在小端模式的系统和大端模式的系统分别编译和运行以下 C++代码段表示的程序,将分别输出什么结果?( )
unsigned x = 0xDEADBEEF;
unsigned char *p = (unsigned char *)&x;
printf("%X", *p);这题考大小端字节序。拿到题先别急着背结论,把十六进制数拆成四个字节,再想:小端是低位字节放低地址,大端是高位字节放低地址。指针p指向x的首地址,所以看第一个格子里填的是哪个字节就行。
最容易把大小端记反,或者混淆‘高位/低位’和‘高地址/低地址’的关系。很多人以为大端就是EF、小端就是DE,那是把网络字节序和主机字节序搞混了。还有人会纠结printf输出格式,其实%X只输出十六进制,跟字节序无关,关键看*p取的是哪个字节。记住口诀:小端是‘低低低’——低地址存低字节,大端是‘高高高’——低地址存高字节。
这道题考查的是计算机组成原理中的大小端字节序(Endianness)。在信息学竞赛的初赛和复赛里,这类题目通常披着C++代码的外衣,但核心完全是概念辨析。命题人喜欢用unsigned整数配合指针操作来‘挖坑’,因为代码看起来像在搞内存操作,其实就是在考你对字节在内存里排队的理解。
首先,我们把题目里的关键字段拆解清楚。
第一步:理解十六进制数 题目给出的变量是unsigned x = 0xDEADBEEF;。这是一个32位的无符号整数。在十六进制里,它被拆成了四个字节:
第二步:理解大小端的定义 这里有两个核心概念,必须掰扯明白,否则后面全错:
第三步:分析代码逻辑 代码的核心是这一行:unsigned char *p = (unsigned char *)&x;
&x 取的是变量 x 的起始地址(也就是内存里存放 x 的第一个字节的位置)。unsigned char * 类型,意味着指针 p 只能一次取一个字节。*p 就是取 p 指向的那个字节的值。因为 p 指向的是 x 的起始地址(&x+0),所以 *p 取到的就是内存里第一个字节的内容。
第四步:代入大小端规则
*p 等于 EF,printf("%X", *p) 输出 EF。*p 等于 DE,printf("%X", *p) 输出 DE。第五步:避坑指南 这里有两个大坑,学生很容易掉进去: 1. 记反了大小端:很多人会下意识觉得“大端是大写的,所以应该是DE”,其实大端是高位在前,低位在后,所以起始地址是DE。小端是低位在前,起始地址是EF。口诀是“小端低低低”(低地址存低字节),“大端高高高”(低地址存高字节)。 2. 混淆网络字节序:有时候题目会提到TCP/IP协议,那是大端的,但本题只问系统编译运行,跟网络协议无关。别被“网络是大端”这个常识带偏,导致在大端系统上误选了EF。 3. 指针类型陷阱:如果指针是 unsigned int *p,那 *p 就会取整个32位整数,输出就是DEADBEEF。但本题特意用了 unsigned char *,就是为了让你只取第一个字节。这是命题人故意设计的细节。
第六步:考频与趋势 回顾一下题库数据,这个知识点(数据存储单位)其实挺高频的。题库共考过52题,覆盖8个级别。从逐年分布看,2023年考了10题,2025年考了7题,2026年考了5题,说明近年热度很高,尤其是GESP和NOIP普及组、提高组初赛里经常出现。分赛事来看,GESP三级和四级各考了10题,NOIP普及组初赛12题,CSP提高级2题。这说明大小端是基础考点,但命题人也在往更灵活的方向变,比如结合指针类型、结合具体数值拆分。
预测未来怎么考 基于数据,大小端依然是高频考点,但单纯考“小端输出EF、大端输出DE”这种送分题,命题人大概率不会再出。未来可能会结合内存布局画图(给定地址范围,让你填字节)、字节序转换(htonl/ntohl函数,或者手动写循环交换字节),甚至出现在结构体对齐的题干里,让你判断某个成员变量在内存里的偏移量。另外,考虑到2025-2026年GESP三级四级考得特别多,未来在GESP考试中,大小端可能会和联合体(union)或者位域(bit-field)结合出现,考察你对内存连续性和字节边界的理解。
总结 这题虽然代码只有三行,但考点非常纯粹:大小端定义 + 指针取首字节。拿到题先别慌,把数拆成四个字节,想清楚起始地址存的是高位还是低位,答案自然就出来了。记住,小端是EF,大端是DE,选B。