0. 如何判断系统是大端还是小端? 在/usr/include中(包括子目录)查找字符串BYTE_ORDER(或_BYTE_ORDER,_BYTE_ORDER),确定其值。这个值一般在endian.h或machine/endian.h文件中可以找到,有时在feature.h中,不同的操作系统可能有所不同。一般来说,Little Endian系统BYTE_ORDER(或_BYTE_ORDER,__BYTE_ORDER)为1234,Big Endian系统为4321。 大部分用户的操作系统(如windows, FreeBsd,Linux)是Little Endian的。少部分,如MAC OS ,是Big Endian 的。本质上说,Little Endian还是Big Endian与操作系统和芯片类型都有关系。
1. 哪些体系结构是大端或小端?
谈到字节序,必然牵涉到两大CPU派系。即Motorola的PowerPC系列CPU,采用大端方式存储,而x86系列采用小端方式存储。 vc6.0 里默认是按小端格式输出,这是因为X86结构是小端模式。而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。 大端:PowerPC、MAC OS、KEIL C51 小端:x86、ARM、DSP、vc6.0 大端:低地址存放高字节数据,高地址存放低字节 小端:低地址存放低字节数据,高地址存高低字节2. 为什么会有大小端模式之分呢? 这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节存储的问题。因此就导致了大端存储模式和小端存储模式。例如一个16bit的short型x,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节,0x22为低字节。对于大端模式,就将0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。小端模式,刚好相反。
3. 为什么要注意字节序问题? 为什么要注意字节序的问题呢?你可能这么问。当然,如果你写的程序只在单机环境下面运行,并且不和别人的程序打交道,那么你完全可以忽略字节序的存在。但是,如果你的程序要跟别人的程序产生交互呢?
在这里我想说说两种语言。C/C++语言编写的程序里数据存储顺序是跟编译平台所在的CPU相关的,而JAVA编写的程序则唯一采用big endian方式来存储数据。试想,如果你用C/C++语言在x86平台下编写的程序跟别人的JAVA程序互通时会产生什么结果?就拿上面的0x12345678来说,你的程序传递给别人的一个数据,将指向0x12345678的指针传给了JAVA程序,由于JAVA采取big endian方式存储数据,很自然的它会将你的数据翻译为0x78563412。什么?竟然变成另外一个数字了?是的,就是这种后果。因此,在你的C程序传给JAVA程序之前有必要进行字节序的转换工作。 无独有偶,所有网络协议也都是采用big endian的方式来传输数据的。所以有时我们也会把big endian方式称之为网络字节序。当两台采用不同字节序的主机通信时,在发送数据之前都必须经过字节序的转换成为网络字节序后再进行传输。ANSI C中提供了下面四个转换字节序的宏。4. PowerPC系列采用big endian方式存储数据,而x86系列则采用little endian方式存储数据。
如题:
char c = 'abc' 在大段和小段下,打印c的结果是什么? 请写一个C函数,若处理器是Big_endian的,则返回0;若是Little_endian的,则返回1。- #include <stdio.h>
- int checkCPU( )
- {
- union w
- {
- int a;
- char b;
- } c;
- c.a = 1;
- return(c.b ==1);
- }
- int main()
- {
- printf("%d\n",checkCPU());
- return 0;
- }
- #include <stdio.h>
- union {
- int x;
- char y[3];
- }w;
- int main()
- {
- w.y[0]=10;
- w.y[1]=1;
- printf("%d\n",w.x); //266
- return 0;
- }
可参考: