写一个程序判断机器的的数据表示采用的是大端还是小端?
分析:大小端问题:计算机存储数据的最基本的单位是byte(字节,8bit)。
c语言中,32位机的情形下:
char 1byte;
short 2bytes;
int 4bytes;
对于 short, int 这种多字节的数据类型,计算机内部是如何表示呢?
计算机对多字节数据类型数据的存储分为大端模式和小端模式:
小端模式:低位字节,在低地址;高位字节,在高地址。
大端模式: 低位字节,在高地址;高位字节,在低地址。
因此:对于同一个整数,其存储表示在大小端模式下不一定相同;相同的存储内容,在大端模式和小端模式下,表示的也未必是同一个整数。
例如:unsigned int a = 0x12345678;
小端模式下:其第一个字节 = 0x78; 第二个字节= 0x56; 第三个字节= 0x34;第四个字节=0x12;
大端模式下:其第一个字节 = 0x12; 第二个字节 = 0x34; 第三个字节=0x56; 第四个字节= 0x78;
以上四个字节的编号,是从低地址,到高地址编号;
在网络编程中,网络传递的字节序,是大端模式;通常需要大小端的转化:
常用的转化函数有:
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
如何判断一个机器采用的大端模式还是小端模式呢? 可以根据大小端模式的性质,实现编码:代码如下:
#include <stdio.h>
#include <assert.h>
int isLittleEndian();
int isLittleEndian_1();
int main(int argc, char *argv[]) {
assert(isLittleEndian() == isLittleEndian_1() );
if(isLittleEndian() ) {
printf("Little Endian\n");
}else {
printf("Big Endian\n");
}
if(isLittleEndian_1() ) {
printf("Little Endian\n");
}else {
printf("Big Endian\n");
}
return 0;
}
int isLittleEndian(){
unsigned int a = 0x12345678;
unsigned char *p = (unsigned char *) &a;
return *p == (unsigned char) a;
}
typedef union {
unsigned char byte;
unsigned int dword;
} char_or_int;
int isLittleEndian_1() {
char_or_int endian;
endian.dword = 0x12345678;
return endian.byte == 0x78;
}
[wzb@embedded endian]$ man htonl | cat
BYTEORDER(3) Linux Programmer’s Manual BYTEORDER(3)
NAME
htonl, htons, ntohl, ntohs - convert values between host and network
byte order
SYNOPSIS
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
DESCRIPTION
The htonl() function converts the unsigned integer hostlong from host
byte order to network byte order.
The htons() function converts the unsigned short integer hostshort from
host byte order to network byte order.
The ntohl() function converts the unsigned integer netlong from network
byte order to host byte order.
The ntohs() function converts the unsigned short integer netshort from
network byte order to host byte order.
On the i80x86 the host byte order is Least Significant Byte first,
whereas the network byte order, as used on the Internet, is Most Sig-
nificant Byte first.
CONFORMING TO
POSIX.1-2001.
Some systems require the inclusion of <netinet/in.h> instead of
<arpa/inet.h>.
SEE ALSO
gethostbyname(3), getservent(3)
BSD 1993-04-15 BYTEORDER(3)
[wzb@embedded endian]$