當前位置:首頁 » 編程語言 » c語言判斷大小端

c語言判斷大小端

發布時間: 2022-06-06 08:23:33

『壹』 C語言讀寫二進制文件讀取 大小端,該怎麼解決

1、二進制文本使用fopen函數的二進制模式「rb」就可以打開。對於程序來說,不管後綴名如何,文件分為兩種類型:文本文件和二進制文件。 C語言里有一系列文件操作函數。區分文本和二進制文件,需要在打開文件時設置不同的控制符mode的變數即可。

『貳』 C語言讀寫二進制文件讀取 大小端,該怎麼解

先看下面的代碼,然後我在簡短的解釋一下。

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <string>#define nmemb 7/****************************************************
Date types(Compiler specific) 數據類型(和編譯器相關)
*****************************************************/typedef unsigned char uint8; /* Unsigned 8 bit quantity */typedef signed char int8; /* Signed 8 bit quantity */typedef unsigned short uint16; /* Unsigned 16 bit quantity */typedef signed short int16; /* Signed 16 bit quantity */typedef unsigned int uint32; /* Unsigned 32 bit quantity */typedef signed int int32; /* Signed 32 bit quantity */typedef float fp32; /* Single precision */
/* floating point */typedef double fp64; /* Double precision */
/* floating point *///int32#define BigtoLittle32(A) ((( (uint32)(A) & 0xff000000 ) >> 24) |
(( (uint32)(A) & 0x00ff0000 ) >> 8) |
(( (uint32)(A) & 0x0000ff00 ) << 8) |
(( (uint32)(A) & 0x000000ff ) << 24))//int16#define BigtoLittle16(A) (( ((uint16)(A) & 0xff00) >> 8 ) |
(( (uint16)(A) & 0x00ff ) << 8))/************************************************************
* Conversion little endian float data to big endian
* *************************************************************/float ReverseFloat(const float inFloat)
{ float retVal; char *floatToConvert = (char*) & inFloat; char *returnFloat = (char*) & retVal; // swap the bytes into a temporary buffer
returnFloat[0] = floatToConvert[3];
returnFloat[1] = floatToConvert[2];
returnFloat[2] = floatToConvert[1];
returnFloat[3] = floatToConvert[0]; return retVal;
}struct matrix
{ int row; int column;
}s[nmemb];void set_s(int j, int x, int y)
{
s[j].row = x;
s[j].column = y;
}bool is_bigendian()
{ int a = 0x1234; char b = *(char *)&a; //b == the Low address part of a
//printf("%c ", b);
if (b == 0x34) { return false;
} return true;
}int main()
{ if (is_bigendian()) { printf("BigEndian ");
} else { printf("LittleEndian ");
}

FILE *fp;
set_s(0, 1, 50);
set_s(1, 1, 80);
set_s(2, 4, 20);
set_s(3, 50, 1);
set_s(4, 80, 2);
set_s(5, 100, 3);
set_s(6, 100, 4); int ans = sizeof(struct matrix); printf("size: %d ", ans); printf("size: %d ", sizeof(s)); if ((fp = fopen("test", "wb")) == NULL) { printf("EROOR "); return 1;
} for (int j = 0; j < nmemb; ++j) { printf("row: %d column: %d ", s[j].row, s[j].column);
}
fwrite(s, sizeof(struct matrix), nmemb, fp); for (int i = 0; i < nmemb; ++i) { float *m = (float*) malloc(sizeof(float) * s[i].row * s[i].column);
bzero(m, sizeof(float) * s[i].row * s[i].column); for (int j = 0; j < s[i].row; ++j) { for (int k = 0; k < s[i].column; ++k) {
m[k + j*s[i].column] = k;
}
}
fwrite(m, sizeof(float), s[i].row * s[i].column, fp); free(m);
}

fclose(fp); printf("11 "); /*
printf("%d ", sizeof(float));
FILE *fp;
if ((fp = fopen("test", "rb")) == NULL) {
printf("EROOR ");
return 1;
}
fread(s, sizeof(struct matrix), nmemb, fp);
for (int i = 0; i < nmemb; ++i) {
printf("row: %d column: %d ", s[i].row, s[i].column);
}

for (int i = 0; i < nmemb; ++i) {
float *m = (float*) malloc(sizeof(float) * s[i].row * s[i].column);
bzero(m, sizeof(float) * s[i].row * s[i].column);
fread(m, sizeof(float), s[i].row * s[i].column, fp);
for (int j = 0; j < s[i].row; ++j) {
for (int k = 0; k < s[i].column; ++k) {
printf("%lf ", m[k + j*s[i].column]);
}
printf(" ");
}
printf(" ");
free(m);
}
fclose(fp);
*/
return 0;
}

fopen和fclose是很常見的,在這里就不做解釋了。我們來看看fwrite和fread,本來以為這個很麻煩,但是用過之後發現這個二進制文件讀寫才是最簡單的。

size_t fwrite(const void * ptr,size_t size,size_t nmemb,FILE * stream);
fwrite()用來將數據寫入文件流中。
stream為已打開的文件指針
ptr 指向欲寫入的數據地址
寫入的字元數以參數size*nmemb來決定。
size表示寫入一個nmemb的內存大小。
fwrite()會返回實際寫入的nmemb數目。

size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream);
fread()用來從文件流中讀取數據。
stream為已打開的文件指針
ptr 指向欲存放讀取進來的數據空間
讀取的字元數以參數size*nmemb來決定
size表示讀取一個nmemb的內存大小。
fread()會返回實際讀取到的nmemb數目,如果此值比參數nmemb 小,則代表可能讀到了文件尾或有錯誤發生,這時必須用feof()或ferror()來決定發生什麼情況。
返回實際讀取到的nmemb數目。

詳情參見上面的代碼。

另外就是大小端的問題了。關於大小端的具體解釋網上有很多,在此不作解釋。參考上面寫的代碼,我判斷了自己機器是大端還是小端,並且實現了int16,int32已經float數據類型的大小端轉換,大端轉小端,在使用相同的代碼一次小端又變成了大端。

PS:float的大小端轉化我之前一直以為寫的是錯的,因為好多數據轉化之後輸出都是0。後來發現可能是與float類型在內存中的存放有關,我們的程序是對的。

『叄』 大小端模式的判斷處理器

通過下列的程序可以確認在某個硬體平台上的某個操作系統是大端還是小端:
VB6: '注意這個CopyMemory的聲明與一般的不一樣,'一般的都是(pDstAsAny,pSrcAsAny,ByValByteLenAsLong)'為了能夠逐位元組訪問u,所以前面兩個參數改成了按值傳遞,配合VarPtr函數獲取變數地址_RtlMoveMemory(ByValpDstAsLong,ByValpSrcAsLong,ByValByteLenAsLong)PrivateSubForm_Load()'VB的Integer佔用2個位元組!Long才是4個位元組'32位應用程序的指針是4個位元組sLong'儲存u從低地址到高地址的4個位元組=367328153'十六進制數:15E4FB99uptr=VarPtr(u)'VarPtr函數是內置函數,但是msdn不說,作用是獲取變數的地址aptr=VarPtr(a)bptr=VarPtr(b)cptr=VarPtr(c)dptr=VarPtr(d)CopyMemoryaptr,uptr+0,1'將u逐位元組按順序寫入a,b,c,dCopyMemorybptr,uptr+1,1CopyMemorycptr,uptr+2,1CopyMemorydptr,uptr+3,1'Windows系統,英特爾處理器:最後輸出的是99FBE415MsgBoxHex(a)&&Hex(b)&&Hex(c)&&Hex(d)EndSub在英特爾處理器,Windows10操作系統上,對話框顯示的結果是99 FB E4 15,與直接求出來的16進制值15 E4 FB 99正好相反,所以是小端的。
C++語言(VS2013下,控制台項目): #include<iostream>usingnamespacestd;typedefunsignedcharbyte;//轉換char(視為整數類型)為16進制字元串voidChtoHex(byteVal,char*dest){//輾轉相除法,倒序看得到結果bytetmp=Val%16;if(tmp>=0&&tmp<=9){dest[1]='0'+tmp;}elseif(tmp>=10&&tmp<=15){dest[1]='A'+tmp-10;}tmp=(Val/16)%16;if(tmp>=0&&tmp<=9){dest[0]='0'+tmp;}elseif(tmp>=10&&tmp<=15){dest[0]='A'+tmp-10;}//設置''dest[2]='';}//主函數intmain(){intu=367328153;//原始數據,8位16進制為15E4FB99bytea,b,c,d;//u從低地址到高地址的四個位元組//a~d對應的16進制字元串,預留3個字元charSa[3],Sb[3],Sc[3],Sd[3];byte*k=(byte*)&u;a=k[0];b=k[1];c=k[2];d=k[3];//轉成16進制字元串ChtoHex(a,Sa);ChtoHex(b,Sb);ChtoHex(c,Sc);ChtoHex(d,Sd);cout<<Sa<<<<Sb<<<<Sc<<<<Sd<<endl;system(pause);return0;}在英特爾處理器,Windows10操作系統上,控制台顯示的結果是99 FB E4 15,與直接求出來的16進制值15 E4 FB 99正好相反,所以也證明是小端的。
C語言(VC++6.0,控制台工程): #include<stdio.h>typedefunsignedcharbyte;//轉換char(視為整數類型)為16進制字元串voidChtoHex(byteVal,char*dest){//輾轉相除法,倒序看得到結果bytetmp=Val%16;if(tmp>=0&&tmp<=9){dest[1]='0'+tmp;}elseif(tmp>=10&&tmp<=15){dest[1]='A'+tmp-10;}tmp=(Val/16)%16;if(tmp>=0&&tmp<=9){dest[0]='0'+tmp;}elseif(tmp>=10&&tmp<=15){dest[0]='A'+tmp-10;}//設置dest[2]='';}//主函數voidmain(){intu=367328153;//原始數據,8位16進制為15E4FB99bytea,b,c,d;//u從低地址到高地址的四個位元組//a~d對應的16進制字元串,預留3個字元charSa[3],Sb[3],Sc[3],Sd[3];byte*k=(byte*)&u;a=k[0];b=k[1];c=k[2];d=k[3];//轉成16進制字元串ChtoHex(a,Sa);ChtoHex(b,Sb);ChtoHex(c,Sc);ChtoHex(d,Sd);printf(%s%s%s%s ,Sa,Sb,Sc,Sd);scanf_s(%d,&a);}在英特爾處理器,Windows10操作系統上,結果跟上面是一樣的,輸出的16進制數是反序的,證明是小端系統。
C#(VS2013下,控制台項目): usingSystem;namespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){intu=367328153;//原始數據,8位16進制為15E4FB99byte[]bytes;//u從低地址到高地址的四個位元組//獲取bytes=System.BitConverter.GetBytes(u);Console.WriteLine(bytes[0].ToString(X)++bytes[1].ToString(X)++bytes[2].ToString(X)++bytes[3].ToString(X));Console.ReadLine();}}}在英特爾處理器,Windows10操作系統上,結果跟上面還還是一樣的,輸出的16進制數是反序的,證明是小端系統。
MDK(Keil5,STM32F407)C語言: #includestm32f4xx.hintmain(void){intu=367328153;//原始數據15E4FB99int*k=&u;return0;}編譯連接然後下載到開發板上,然後啟動調試,通過監視窗口可以看到u的地址,然後在內存窗口可以看到位元組序是反序的,所以說明STM32F407是小端的。據某些資料說ARM內核是可以設置大小端的,但是STM32是外設自動進入了小端,似乎是無法調整的。

89C52(Keil5)C語言:
最後來一個大端的例子。手頭上沒有51的開發板,所以用的是軟體模擬。 #include<reg52.h>intmain(){intlongbit=sizeof(long);longu=367328153;//原始數據15E4FB99long*k=&u;return0;}注意看了,C52是8位的處理器,long才是4個位元組的,看監視窗口longbit的值就知道了(紫色框)。然後再看內存窗口,就會發現u的存儲是跟原始數據給的順序是一樣的,所以C51和C52是大端的!!

『肆』 C語言中使用union是怎麼判斷處理器大小端的

union Charge

{
char arr[2];
short num;
};
int main()
{

union Charge charge;
charge.arr[0] = 1;
charge.arr[1] = 2;

if (charge.num == 0x0201)
{
printf("小端\n");

}
else
{
printf("大端\n");

}

return 0;
}

『伍』 如何確定大小端

什麼大小端啊?是一根木桿的大小端嗎?放到水中,沉下去多的就是根部(大端)

熱點內容
什麼是白標和伺服器 發布:2025-02-08 21:15:50 瀏覽:481
租完伺服器怎麼搭建ip 發布:2025-02-08 21:11:47 瀏覽:394
c語言賦值後 發布:2025-02-08 21:08:40 瀏覽:756
dosphp 發布:2025-02-08 21:01:27 瀏覽:703
sm3雜湊演算法 發布:2025-02-08 20:55:00 瀏覽:286
抽獎源碼帶後台 發布:2025-02-08 20:33:54 瀏覽:226
歐博中央空調原始密碼是多少 發布:2025-02-08 20:33:47 瀏覽:335
運動使人快樂緩解壓力 發布:2025-02-08 20:27:01 瀏覽:98
linux命令大文件 發布:2025-02-08 20:25:06 瀏覽:898
C蟻群演算法 發布:2025-02-08 20:21:25 瀏覽:513