C/C++ 关于大小端模式,大小端字节序转换程序
首先这些是什么?
小字节序和大字节序是存储多字节数据类型(int,float等)的两种方式。在小字节序机器中,多字节数据类型的二进制表示形式的最后一个字节首先存储。另一方面,在大字节序机器中,多字节数据类型的二进制表示形式的第一个字节首先存储。
假设整数存储为4个字节(对于使用基于DOS的编译器(例如C ++
3.0)的整数,则整数为2个字节),则值x为0x01234567的变量x将存储如下。
大小字节序的机器中整数ox01234567的内存表示
当上述程序在小端机器上运行时,给出“ 67 45 23 01”作为输出,而在大端机器上运行时,给出“ 01 23 45 67”作为输出。
有没有一种快速的方法来确定计算机的字节序?
没有。确定计算机字节序的方法。这是执行此操作的一种快速方法。
//大小端模式的判断 //方法一:利用联合体所有成员的起始位置一致, //对联合体中的int类型赋值,然后判断联合体中char类型的值的大小
#include<stdio.h> int main() { unsigned int i = 1; char * c =(char*)&i; if(*c) { printf("Little endian\n"); } else { printf("Big endian\n"); } return 0; }
在上面的程序中,字符指针c指向整数i。由于取消引用字符指针时字符的大小为1个字节,因此它将仅包含整数的第一个字节。如果机器是小端,那么* c将为1(因为最后一个字节先存储),而如果机器是大端,则* c将为0。
字节序对程序员重要吗?
大多数情况下,编译器会处理字节序,但是在以下情况下字节序成为一个问题。
在网络编程中很重要:假设您在小字节序的机器上向文件写入整数,然后将此文件传输到大字节序的机器上。除非没有大字节序到大字节序转换,否则大字节序计算机将以相反的顺序读取文件。您可以在这里找到这样一个实际的例子。
网络的标准字节顺序为大端,也称为网络字节顺序。在网络上传输数据之前,先将数据转换为网络字节顺序(大字节序)。
有时在使用类型转换时很重要,下面的程序是一个示例:
#include <iostream> #include <iomanip> using namespace std; //signed typedef signed char int8; typedef short int16; typedef int int32; typedef long long int64; //unsigned typedef unsigned char uint8; typedef unsigned short uint16; typedef unsigned int uint32; typedef unsigned long long uint64; #pragma pack(push) #pragma pack(1)//单字节对齐 typedef struct{ uint32 ID; uint32 Num; uint32 Type; uint32 lat; uint32 lng; uint32 alt; uint32 speed; }Waypoint;//Payload_Data #pragma pack(pop) void EndianSwap(uint8 *pData, int startIndex, int length); int main() { Waypoint wp,wp_ori; int len = sizeof(Waypoint); cout << "size of Waypoint: " << len << endl; wp.ID = 0x00000011; wp.Num = 0x00002200; wp.Type = 0xDD0CB0AA; wp.lat = 0x00330000; wp.lng = 0x44000000; wp.alt = 0xABCD1234; wp.speed = 0x12345678; wp_ori = wp; int i = 0; uint8* pData = (uint8*)(&wp); for (i = 0; i < len; i += 4) { EndianSwap(pData,i,4); } cout << endl; cout << uppercase << hex << "改变字节序前: 0x" << setfill('0') << setw(8) << wp_ori.ID << endl; cout << uppercase << hex << "改变字节序后: 0x" <<setfill('0') << setw(8) << wp.ID <<endl; cout << endl; cout << uppercase << hex << "改变字节序前: 0x" << setfill('0') << setw(8) << wp_ori.Num << endl; cout << uppercase << hex << "改变字节序后: 0x" << setfill('0') << setw(8) << wp.Num << endl; cout << endl; cout << uppercase << hex << "改变字节序前: 0x" << setfill('0') << setw(8) << wp_ori.Type << endl; cout << uppercase << hex << "改变字节序后: 0x" << setfill('0') << setw(8) << wp.Type << endl; cout << endl; cout << uppercase << hex << "改变字节序前: 0x" << setfill('0') << setw(8) << wp_ori.lat << endl; cout << uppercase << hex << "改变字节序后: 0x" << setfill('0') << setw(8) << wp.lat << endl; cout << endl; cout << uppercase << hex << "改变字节序前: 0x" << setfill('0') << setw(8) << wp_ori.lng << endl; cout << uppercase << hex << "改变字节序后: 0x" << setfill('0') << setw(8) << wp.lng << endl; cout << endl; cout << uppercase << hex << "改变字节序前: 0x" << setfill('0') << setw(8) << wp_ori.alt << endl; cout << uppercase << hex << "改变字节序后: 0x" << setfill('0') << setw(8) << wp.alt << endl; cout << endl; cout << uppercase << hex << "改变字节序前: 0x" << setfill('0') << setw(8) << wp_ori.speed << endl; cout << uppercase << hex << "改变字节序后: 0x" << setfill('0') << setw(8) << wp.speed << endl; return 0; } void EndianSwap(uint8 *pData, int startIndex, int length) { int i,cnt,end,start; cnt = length / 2; start = startIndex; end = startIndex + length - 1; uint8 tmp; for (i = 0; i < cnt; i++) { tmp = pData[start+i]; pData[start+i] = pData[end-i]; pData[end-i] = tmp; } }
运行结果如下:
什么是双端?
双端处理器可以在小端和大端两种模式下运行。
小型,大端和双端机器的例子是什么?
基于Intel的处理器很少使用字节序。ARM处理器是小端。当前一代的ARM处理器是双向的。
摩托罗拉68K处理器是高端厂商。PowerPC(摩托罗拉公司生产)和SPARK(Sun公司生产)处理器是大端。这些处理器的当前版本是双向的。