1. 程式人生 > >32位機與64位機資料型別

32位機與64位機資料型別

最近在Linux下移植程式時遇到了一個問題,將32位機下的程式移植到64位上,在用long型讀入檔案時發生了錯誤,讀出來的是0,後經測試原來是在32位機下和64機下某些資料型別表示的不一樣。測試程式如下:

#include <stdio.h>

int main ()
{
  printf ("char /n", sizeof(char));
  printf ("short /n", sizeof(short));
  printf ("int /n", sizeof(int));
  printf ("long /n", sizeof(long));
  printf ("long long/n", sizeof(long long));
  printf ("float /n", sizeof(float));
  printf ("double /n", sizeof(double));
  printf ("long double /n", sizeof(long double));
  printf ("pointer /n", sizeof(void*));

  return 0;
}

在Windows下,是這樣的結果

WinXP       32 x64
char        1   1
short       2   2
int         4   4
long        4   4
long long   8   8
float       4   4
double      8   8
long double 8   8
pointer     4   8

而在Linux下面,卻是另一個結果

Linux      x86 amd64
char        1   1
short       2   2
int         4   4
long        4   8
long long   8   8
float       4   4
double      8   8
long double 12  16
pointer     4   8

由此可見,在移植程式時,要特別注意long,long double和pointer指標型別的使用。

資料在記憶體中儲存的方法也不一樣:

Little-endian 是將低位位元組儲存在記憶體的低地址中,將高位位元組儲存在記憶體的高地址中。

Big-endian 是將高位位元組儲存在記憶體的低地址中,將低位位元組儲存在記憶體的高地址中。

  3. 64 位 long int 型別的佈局

低地址

高地址

Little endian

Byte 0

Byte 1

Byte 2

Byte 3

Byte 4

Byte 5

Byte 6

Byte 7

Big endian

Byte 7

Byte 6

Byte 5

Byte 4

Byte 3

Byte 2

Byte 1

Byte 0

例如,32 位的字 0x12345678 在 big endian 機器上的佈局如下:

最近在Linux下移植程式時遇到了一個問題,將32位機下的程式移植到64位上,在用long型讀入檔案時發生了錯誤,讀出來的是0,後經測試原來是在32位機下和64機下某些資料型別表示的不一樣。測試程式如下:

#include <stdio.h>

int main ()
{
  printf ("char /n", sizeof(char));
  printf ("short /n", sizeof(short));
  printf ("int /n", sizeof(int));
  printf ("long /n", sizeof(long));
  printf ("long long/n", sizeof(long long));
  printf ("float /n", sizeof(float));
  printf ("double /n", sizeof(double));
  printf ("long double /n", sizeof(long double));
  printf ("pointer /n", sizeof(void*));

  return 0;
}

在Windows下,是這樣的結果

WinXP       32 x64
char        1   1
short       2   2
int         4   4
long        4   4
long long   8   8
float       4   4
double      8   8
long double 8   8
pointer     4   8

而在Linux下面,卻是另一個結果

Linux      x86 amd64
char        1   1
short       2   2
int         4   4
long        4   8
long long   8   8
float       4   4
double      8   8
long double 12  16
pointer     4   8

由此可見,在移植程式時,要特別注意long,long double和pointer指標型別的使用。

資料在記憶體中儲存的方法也不一樣:

Little-endian 是將低位位元組儲存在記憶體的低地址中,將高位位元組儲存在記憶體的高地址中。

Big-endian 是將高位位元組儲存在記憶體的低地址中,將低位位元組儲存在記憶體的高地址中。

  3. 64 位 long int 型別的佈局

低地址

高地址

Little endian

Byte 0

Byte 1

Byte 2

Byte 3

Byte 4

Byte 5

Byte 6

Byte 7

Big endian

Byte 7

Byte 6

Byte 5

Byte 4

Byte 3

Byte 2

Byte 1

Byte 0

例如,32 位的字 0x12345678 在 big endian 機器上的佈局如下:


 4. 0x12345678 在 big-endian 系統上的佈局

記憶體偏移量

0

1

2

3

記憶體內容

0x12

0x34

0x56

0x78

如果將 0x12345678 當作兩個半字來看待,分別是 0x1234 和 0x5678,那麼就會看到在 big endian 機器上是下面的情況:


 5. 0x12345678 在 big-endian 系統上當作兩個半字來看待的情況

記憶體偏移量

0

2

記憶體內容

0x1234

0x5678

然而,在 little endian 機器上,字 0x12345678 的佈局如下所示:


 6. 0x12345678 在 little-endian 系統上的佈局

記憶體偏移量

0

1

2

3

記憶體內容

0x78

0x56

0x34

0x12

類似地,兩個半字 0x1234 和 0x5678 如下所示:


 7. 0x12345678 在 little-endian 系統上作為兩個半字看到的情況(對此表示懷疑,要實驗一下

記憶體偏移量

0

2

記憶體內容

0x3412

0x7856

從 32 位遷移到 64 位時,增長的主要型別是指標和派生資料型別,如控制代碼。在 Windows 64 位中,目前的指標和派生型別是 64位  long 型別。大小增加的其他一些型別還有:WPARAM、LPARAM、LRESULT 和 SIZE_T。其中一個原因是,它們作為引數使用,並且某些函式將指標作為引數使用

從“int”和“long”派生出的所有型別的大小仍然是 32 位,其中包括 DWORD、UINT 和 ULONG。小於 32 位的型別保留它們當前的大小。一個示例就是“short”資料型別,它仍然保留為 16 位的帶符號整數。