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公司生產)處理器是大端。這些處理器的當前版本是雙向的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM