一道 C 笔试题目 :使用 union
今日有同学笔试遇到一道 C 语言题目,原题目如下:
#include <stdio.h> static union { int i; char a[2]; }; int main() { a[0] = 10; a[1] = 1; printf("%d", i); return 0; }
问输出为多少?
要解答这个题目需要以下之小知识点:
1. union 类型的特点是不同类型的数据共享同一段内存,union 结构体的大小为其所含占内存最大之成员之大小,但在同一时刻只能有一类成员存储于其中,即这里 i 不能和 数组 a 同时有效(即会互相干扰);
2. 计算机内存编址一般采用从小到大的顺序;
3. 数组在内存中占据一块连续的顺序即 a[1] 内存编址要大于 a[0] 之内存编址;
4. 数据的地址是以其在计算机中占据的地址低地址部分为地址的;
若以以上斯点论之,输出应为 266 ;
但是,计算机中有大端和小端的存储问题(与CPU也有关系),大端小端的说法来源于一个具有讽刺意味的小说,说的是有两个党派争论从哪一头敲破鸡蛋更好,一党坚持从小端敲破鸡蛋更好,即 Little Endian,而另一党则认为从大的一端敲破鸡蛋更好,即 Big Endian。因为数据存储时总是从低地址到高地址存储,计算机中所谓的大端存储是指占据超过一个字节的数据其高字节有效位存储于低内存地址编码中,即先开始存储高字节有效位,小端则正好相反。如 存储 0x1234 时,比方地址为 0x4000,占据的地址为 0x4000 和 0x4001,大端即有:0x4000 中存放 0x12, 0x4001 中存放 0x34,同理可想想小端的情况。计算机本身采用大端存储还是小端存储可能并没有对一般编程人员有太大意义,但对于嵌入式编程人员和汇编语言编程人员来说可能会使用到,所以即使不使用也应该记住的的确确是存在这样的实现选择。DEC (Digital Equipment Corporation,现在是Compaq公司的一部分)和Intel的机器(X86平台)一般采用小端。IBM, Motorola(Power PC), Sun的机器一般采用大端。 所以,基于上面的分析,还有一点需要明了:
5. 明确本机是大端存储还是小端存储,对于不同的存储方式,还会有另外一个答案;
所以,上面这道题目的答案应该是不确定的,答案取决于具体的计算机存储细节。
你的计算机是大端的还是小端的?试试以下的程序便知。
#include <stdio.h> static union { int i; char j; }; main() { i = 1; if ( j == 1 ) { printf("%s", "llittle endian"); } else { printf("%s", "big endian"); } }