zoukankan      html  css  js  c++  java
  • 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
    ");
       }
       else
       {
          printf("Big endian
    ");
       }
    
       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公司生产)处理器是大端。这些处理器的当前版本是双向的。

  • 相关阅读:
    关于sizeof表达式作为数组元素个数的编译
    【deque】滑动窗口、双端队列解决数组问题
    【二叉树】重建二叉树
    字符数组与字符串指针
    【STL】C中的qsort与C++中的sort
    对C++不是类型安全语言的理解
    【vector】创建一个二维vector当作二维数组用
    批量处理改变文件名、文件后缀名
    位运算
    关于sqlserver帐号被禁用问题
  • 原文地址:https://www.cnblogs.com/sharecenter/p/14692935.html
Copyright © 2011-2022 走看看