首先我們給出大小端的定義:
小端:較高的有效字節存放在較高的的存儲器地址,較低的有效字節存放在較低的存儲器地址。
大端:較高的有效字節存放在較低的存儲器地址,較低的有效字節存放在較高的存儲器地址。
將0x12345678寫入到以1000h開始的內存中,這里0x12346578中0x12~0x78的地址是從高到低
如果,我們的機器是小端存儲的話,結果為:
數據 地址
0x78 1000H
0x56 1001H
0x34 1002H
0x12 1003H
如果我們的機器是大端存儲的話,結果為:
數據 地址
0x12 1000H
0x34 1001H
0x56 1002H
0x78 1003H
寫到這里,讀者大概明白,大小端是怎么存儲在內存中,然后我們給出判斷大小端的方法.
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<string> 6 #include<queue> 7 #include<algorithm> 8 #include<map> 9 #include<iomanip> 10 #include<stdlib.h> 11 #define INF 99999999 12 using namespace std; 13 14 int panduan_1(){ 15 int a = 0x12345678; 16 char *c = (char*)&a; 17 for(int i = 0;i<4;i++){ 18 printf("%x\n",c[i]); 19 } 20 return ((c[0]==0x78)&&(c[1]==0x56)&&(c[2]==0x34)&&(c[3]==0x12)); 21 } 22 union p{ 23 int a; 24 char b; 25 }; 26 int panduan_2(){ 27 p p1; 28 p1.a = 1; 29 return p1.a==p1.b; 30 } 31 int main(){ 32 33 if(panduan_1()){ 34 cout<<"little duan"<<endl; 35 }else{ 36 cout<<"big duan"<<endl; 37 } 38 if(panduan_2()){ 39 cout<<"little duan"<<endl; 40 }else{ 41 cout<<"big duan"<<endl; 42 } 43 system("pause"); 44 return 0; 45 }
結果:
方法1:是利用定義,在地址上判斷存的是否是高低位的數據,來解決問題.
方法2:在union中所有的數據成員共用一個空間,同一時間只能儲存其中一個數據成員,所有的數據成員具有相同
的起始地址。即上述的union雖然定義了兩個成員,但其實這個union只占用了4個字節(32位機器中),往a成員
賦值,然后讀取b就相讀取a成員的低位第一個字節的值。如果機器使用大端模式,則u.a=1那a的最高字節值為1;
如果機器使用小段模式,則u.a=1則a的最低位字節為1。上述可知b和a有相同的起始位,所以讀取b如果等於1,
則為小端模式,b為0則為大端模式
import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; public class demo { /** * @param args */ public static void main(String[] args) throws Exception { // TODO Auto-generated method stub int a = 0x12345678; ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); dos.writeInt(a); byte[] b = baos.toByteArray(); for(int i = 0;i<4;i++){ System.out.println(Integer.toHexString(b[i])); } } }
結果:
JVM中,實際是以大端存儲的.
這樣,我們通過兩種語言來解決大小端問題.