int的長度由處理器(16位,32位,64位)和比哪一期決定。程序員
首先從處理器來說 :16位處理器中的int 佔有16位 即2個字節web
32位處理器中int佔有32位 即4個字節編程
64位處理器中int佔有64位 即8個字節windows
附錄:api
數據類型特別是int相關的類型在不一樣位數機器的平臺下長度不一樣。C99標準並不規定具體數據類型的長度大小,只規定級別。做下比較:安全
16位平臺數據結構
char 1個字節8位socket
short 2個字節16位函數
int 2個字節16位工具
long 4個字節32位
指針 2個字節
32位平臺
char 1個字節8位
short 2個字節16位
int 4個字節32位
long 4個字節
long long 8個字節
指針 4個字節
64位平臺
char 1個字節
short 2個字節
int 4個字節
long 8個字節(區別)
long long 8個字節
指針 8個字節(區別)
32位環境涉及"ILP32"數據模型,是由於C數據類型爲32位的int、long、指針。而64位環境使用不一樣的數據模型,此時的long和指針已爲64位,故稱做"LP64"數據模型。
現今全部64位的類Unix平臺均使用LP64數據模型,而64位Windows使用LLP64數據模型,除了指針是64位,其餘基本類型都沒有變。(註釋:相對於windows32操做系統來講 只有指針改編成64位,int long 都還仍然是32位)
TYPE LP32 ILP32 LP64 ILP64 LLP64
CHAR 8 8 8 8 8
SHORT 16 16 16 16 16
INT 16 32 32 64 32
LONG 32 32 64 64 32
LONG LONG 64 64 64 64 64
POINTER 32 32 64 64 64
3、使用int時也可使用intptr_t來保證平臺的通用性,它在不一樣的平臺上編譯時長度不一樣,但都是標準的平臺長度,好比64位機器它的長度就是8字節,32位機器它的長度是4字節,定義以下:
#if __WORDSIZE == 64
typedef long int intptr_t;
#else
typedef int intptr_t;
#endif
編程中要儘可能使用sizeof來計算數據類型的大小
以上類型定義都有相應的無符號類型。
另外還有ssize_t和size_t分別是sign size_t和unsigned signed size of computer word size。它們也是表示計算機的字長,在32位機器上是int型,在64位機器上long型,從某種意義上來講它們等同於intptr_t和 uintptr_t。它們在stddef.h裏面定義。須要注意的是socket的accept函數在有些操做系統上使用size_t是不正確的,由於 accept接收的int*類型,而size_t多是long int 類型。後來BSD使用sock_t來替代它。
轉摘 : (收藏)從1995年windows 95推出至今,絕大多數windows應用程序都已經從win16平臺轉移到win32平臺,windows 3.x及其表明的16位windows編程技術被迅速打入了冷宮。如今,microsoft公司的軟件工程師們針對intel公司的ia-64處理器構架 又開始了64位windows編程(win64)技術的設計,因爲windows 98是windows 9x系列中的最後一個產品,因此win64將被包含在正在開發的windows nt 5.0中,當intel的新一代64位處理器merced推出後,軟件開發人員就能夠開始使用64位編程技術,nt的企業計算能力勢必會獲得極大的提升。
由於4gb的地址空間知足 了目前絕大多數應用的需求,win64與win32之間的差別遠小於win32與win16之間的差別,因此win64不會像win32取代win16那 樣迅速取代win32。在從此至關長的一段時間內,win64將與win32和平共處,相互補充。軟件開發人員須要根據應用的特色選擇開發平臺,或者同時 創建應用程序的win64和win32版本,因爲win64與win32編程區別不大,在使用高級語言編程時只要遵循必定的原則,花費極少許的時間與精力 就能夠爲不一樣平臺建立相應的版本,而且在多數時候只要對源程序從新編譯鏈接一次就能夠了。
·llp64抽象數據模型·
c語言標準中沒有規定整型、長整型和指針等變量各有多少位,而是留給了計算平臺來肯定,所以每種系統及其應用都必須採用某種默認的抽象數據模型來做爲計 算的基礎,win32採用一種稱爲llp32的模型,即假定整型、長整型和指針變量的字長都是32位,相應定義的int、uint、long、ulong 和handle等數據類型也都是32位,這對於32位windows編程環境來講是合理的規定。若是win64中把整型、長整型和指針變量的字長都改成 64位,那麼不只要佔有之前兩倍的存儲空間,並且現有的應用程序及其使用的大多數數據類型都須要做更改,實現兩種平臺之間的可移植性就變得至關困難了。事 實上,在引入64位平臺後,應用程序須要實現64位尋址,並只在少數地方須要用到64位數據,而多數時候使用32位數據就足夠了,所以,win64採用了 一種稱爲llp64的抽象數據模型,除了把指針變量擴展到了64位外,整型和長整型變量等基本數據類型仍然保持32位。因爲基本數據類型都保持32位不 變,因此存儲在磁盤上的數據不用改變其結構和大小,遠程或本地進程之間的共享數據(如內存映射文件)也不用改變其結構和大小,這就大大減輕了程序員的工做 量。
爲了實現同一份源代碼既能 在win32下運行,也能在win64下運行,定義llp64模型只是走出了第一步,接下來還要定義一些與指針相關的數據類型,如對指針進行計算時須要的 數據類型等,編譯器會根據目標平臺來肯定這些數據類型是32位仍是64位。這些新的數據類型是用c語言的int和long類型定義的,所以保持了對 win32及部分windows api函數的向後兼容性,microsoft計劃在windows nt 5.0的beta 2版包含這些新數據類型,並逐漸移植全部的windows api函數到64位平臺,程序員在nt 5.0 beta 2版及相應的platform sdk推出後就能夠開始使用這些數據類型了,當64位平臺正式推出後,所編寫的程序多數只需從新編譯鏈接一次便可生成64位版本。
·新的數據類型·
新數據類型共有三類:固定精度數據類型(fixed-precision data types)、指針精度數據類型(pointer-precision data type)和指定精度指針(specific-precision pointers)。
1.固定精度數據類型在win32和win64中有相同的字長,爲了便於記憶,它們的名字中包含了其字長。
·int32和int64:字長分別爲32位和64位的有符號整型數;
·long32和long64:字長分別爲32位和64位的有符號長整型數;
·uint32和uint64:字長分別爲32位和64位的無符號整型數;
·ulong32和ulong64:字長分別爲32位和64位的無符號長整型數。
2.指針精度數據類型與目標平臺的指針的字長相同(由編譯器來肯定),這樣能夠把指針安全地轉換成指針精度數據類型來進行代數運算和位運算,而不用編程時到處考慮目標平臺的類型。
·int-ptr和uint-ptr:指針精度的有符號和無符號整型數,win32下字長爲32位,win64下字長爲64位;
·ssize-t和size-t:指針精度的計數器,用於肯定指針精度數據類型的字長,前者爲有符號計數器。
3.特定精度指針在win32和win64中都保持相同的字長,所以只在某些特殊狀況下才有用。
·-ptr64(64位指針):在win32中,32位指針經過符號擴展生成一個64位指針,擴展的結果可能沒有任何意義,不能再當作指針來使用;
·-ptr32(32位指針):在win64中,64位指針經過截去高32位生成一個32位指針,結果可能沒有任何意義,也不能再當作指針來使用。
使用這些新的數據類型能夠更清晰地顯示出程序中哪些地方進行的計算實質上與指針相關,這樣在進行類型轉換時就不容易出錯,而win32中原來定義的數據類型就沒有這個優勢,所以新數據類型有利於咱們編寫出更健壯的代碼,而且爲未來移植到64位平臺作好了準備。
·輔助開發工具·
在win64下編程與在win32下編程區別很小,由於你們熟悉的windows api函數除了涉及到指針的參數的類型可能改變外,其餘沒有什麼更多的變化,程序員原有的知識仍然有用。爲了幫助程序員修改現有的源代碼,轉而使用新的數 據類型,microsoft將在nt 5.0 beta 2版中包含一些開發輔助工具,其中包括一個定義新數據類型的頭文件basetsd.h和一個語法檢查器。語法檢查器能夠檢查出源程序中不正確的類型轉換、 指針截斷及其餘一些與64位相關的問題。例如它會指出下面的代碼存在着4311號指針截斷警告:
buff = (puchar)srbcontrol;
(ulong)buffer += srbcontrol->headerlength;
爲了消除警告,應該把ulong改成uint-ptr,這樣才能保證這段代碼既能在win32上運行,也能在win64上運行。程序員的目標是消除全部語法檢查器發出的警告,尤爲是4311號指針截斷警告。
·編程規則·
爲了順利實現兩種平臺的源代碼級可移植性,程序員應按照如下規則來編寫程序或者修改已有程序。
1.不能將指針轉換成 int、uint、long、ulong、dword等字長固定爲32位的類型,若是須要對指針作運算,應把指針轉換爲int-ptr或 uint-ptr,這兩種類型在不一樣平臺上纔有正確的字長。另外,因爲handle實質上是一個指針(void *),所以把handle轉換成long或ulong等類型也是不正確的。
2.若是肯定須要對指針進行截斷,那麼應使用ptrtolong()和ptrtoulong()兩個函數(在basetsd.h中定義)來進行,它們能夠屏蔽掉指針截斷警告,不過截斷的結果不可以再當指針使用了。
3.當某個api函數的 out參數能返回一個指針時,應當心謹慎處理參數,在win32中,能夠把一個ulong變量的地址進行強制轉換後傳遞給api函數,返回的指針就保存在 ulong變量中,但在win64中,返回的指針有64位,若是使用ulong變量的話就會破壞其餘變量的內容,正確而且簡單的方法是直接定義一個指針變 量,把指針變量的地址做爲參數傳遞給api函數。
4.謹慎處理多態參數。在 win32中,一個函數能夠用一個dword參數來接受多態參數,即該參數在不一樣狀況下可能具備不一樣的意義,如解釋成整型數或指針。在win64中,若是 一個多態參數可能被解釋成指針,那麼決不能把多態參數設爲dword類型,而應設爲uint-ptr或pvoid類型。win32自身的一部分api函數 (如raiseexception())由於不符合該條規則而須要進行修改。
5.使用新的 get/setwindowlongptr和get/setclasslongptr api函數。若是在窗口或類的數據區中存放了指針,就須要調用上面的函數來存取相應的變量,爲了幫助程序員在編程中正確處理這一點,頭文件 winuser.h把索引值gwl-wndproc、gwl-hinstance、gwl-hwdparent和gwl_userdata的定義取消了, 轉而定義了新的索引值gwlp-wndproc、gwlp-hinstance、gwlp-hwdparent和gwlp-userdata。這樣下面的 代碼將會引發編譯錯誤:
setwindowlong(hwnd,gwl-wndproc,(long)mywndproc);
由於gw-wndproc沒有定義,正確的代碼應爲:
setwindowlongptr(hwnd,gwlp-wndproc,(int-ptr)mywndproc);
6.許多窗口和類的數據結構中包含了指針,所以不能在代碼中強行指定偏移量來訪問數據成員,而應使用field-offset宏來計算偏移量。
7.因爲lparam、wparam和lresult一般用來存放指針或整數,在win64中它們所有被擴展成爲64位,所以不能把它們與dword、ulong、uint、int、int和long等類型混用,不然可能會無心識地把它們截短了。
關於在win64環境下編程還須要注意的其餘問題,以及win64平臺下api函數的變化及新增函數,有興趣的讀者可到microsoft的web站點查閱相關資料,或者參考最新版的platform sdk及msdn oline library。