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公司生产)处理器是大端。这些处理器的当前版本是双向的。

posted @ 2021-04-23 11:11  恋恋西风  阅读(3041)  评论(0编辑  收藏  举报