這也算和平同學的點題作文了,呵呵。 他對於Linux下很多時候,api函數大量使用int作為常用類型感到不解,問我,我呢,就試著回答一下哈。 原帖在這裡:http://student.csdn.net/space.php?uid=121080&do=thread&id=9168 問題如下: 根據<c++ primer>建議,表示像“容量”這樣的變量時,因為不可能出現負數,所以建議用size_t類型。但是linux下的程序,好像比較喜歡使用int。 為什麼不使用size_t(或者unsigned int)而使用int?表示范圍不是少了一半嗎? 我的回答: 嗯,這個問題算是比較偏門了,不過,我做過Windows開發,也做過Linux開發,兩個平台都用過,沒什麼道理哈,僅僅談點自己的感覺,嗯,不一定准確,大家有高見,還可以補充。 我覺得這個問題首先是一個文化問題。什麼叫文化,就是做這類事情的人們的一個通常的共識,就是大家都習慣這麼做事。我很早,嗯,07年開始轉向Linux開發的時候,就發現這點不同。 Windows呢,是微軟公司開發的,大公司,強調嚴謹的開發風格,大家可以從它推崇匈牙利命名法就看的出來。它對於變量命名,類型命名是有嚴格規定的,要求盡量准確,不給後來者留歧義。比如,很多Struct*,它會使用typedef顯式定名為一種新類型PStruct來管理,這樣,大家從字面上就可以一眼看出來,而不用到用的時候,跑去數星星。數星星很容易數錯的。我就干過壞事,嘿嘿。 這個道理也很簡單,微軟是開發OS的,說白了,它的主要產品功能,除了Windows的操作功能,還需要提供大量的api給廣大程序員用,沒辦法啊,如果沒人給他的操作系統開發應用程序,他的OS賣不動的。 這就要求微軟不僅僅關注終端用戶的體驗,也特別關注程序員用戶的體驗,而明示的api,顯然是一種很好的用戶體驗,程序員不容易犯錯誤,被api的提供者約束著做正確的事情,程序員bug少,成功率就高,進而開發成本就低,於是,形成良性循環。 同時,這也為微軟的客服部門減少好多投訴哦,大家換位思考一下,如果微軟的api含糊不清,大家是不是要發飙?呵呵。 這裡面體現出來一個很重要的思想,微軟是把廣大應用程序員,也作為什麼都不懂的終端用戶在看待,試圖從api上構建最大的開發友好度,因此,它對於命名法很嚴格,api定名表意很清晰,同時,對於各種變量、類型,不厭其煩,多次定義,為了是讓各個行業的程序員, 用起來都盡量貼合自己的行業習慣。 這是有道理的,比如我現在在電力系統,我們定義變量類型,喜歡用Int16、Int32、Int64,Float16、Float32、Float64這類命名,int、double這些C/C++基本類型,反而不太流行。為啥,很多時候工業現場的人,不知道你這個類型到底是多少bits的,就會出錯。這是為了用戶看著清晰,也是行業習慣,所以,我很多時候開始寫程序前,都要先去定義這麼一批新的變量類型,方便和同事們溝通代碼啊。 而Unix呢,不太一樣,我看過《Unix編程藝術》這本書,這裡面講了很多Unix程序員的文化。這麼說吧,我簡單點,Unix的開發者,默認使用者是和其水平相當的程序員,大家所有溝通的語言,都是計算機本專業的,大家很多時候用默認,暗示,就好了。 所以,Unix下的習慣,沒有那麼多分門別類的變量類型,大家還有個好習慣,呵呵,int包打一切。我看到幾乎大多數Unix的函數,就是gcc的基本庫,函數老是int來,int去,其實,給我的感覺,在Unix下,什麼都是int,為啥,Unix很講究把同類資源數組化管理,比如打開的文件句柄,就是一個整數,進程ID,整數,線程ID,整數,用戶ID,整數,甚至,設備都是整數表示。嗯,socket不說了,Windows下是一個特定數據類型SOCKET,而Unix下,你猜對了,沒錯,int,整數。 這叫什麼?其實是向量化管理,在系統內部檢索的時候,可以想象,Unix系統的開發者,大量使用數組,利用int這個整數在哈希檢索目標,達到效率最高。反正,我們不管什麼資源,在Unix內部,就是一個int型的ID表示,這其實已經是Windows句柄的概念了。 這兩種命名方法,其實各有優缺點,Windows的變量類型多,程序員學習的時候,成本高,但是,學會了就不容易出錯。而Unix的學習曲線低,沒那麼多類型名要去背,不過呢,用起來出不出錯,自理啊,Unix的開發者,相信大家的實力。嗯,只是我自己有點信不過我自己,嘿嘿。 不過要我說呢,還真說不好誰對誰錯,其實都有道理,關鍵看OS的設計者,心目中的目標用戶的水平如何了。 回到和平同學的問題,用int,少一半,其實是有道理的,因為int是有符號的,有一半的表示范圍是負數,在表示很多容量的時候,比如說吧,malloc的數組,或者socket的表示范圍,確實負數沒有意義。因此,看起來被浪費了。 這其實不然,為什麼,原因很簡單。 int就算少一半,你能用多少?和平同學別見怪啊,我說句話,你問這個問題就表示還有點學生思維,總是想多多益善,就是我要把所有的資源都納入我的管理,呵呵。其實我們做工作做久了的,對於數據的邊界、范圍,反而有個思想,夠用就好,沒必要多。 int表示少一半,2G有吧,嗯,大多數用戶的數組,可不可能超過1G?其實,大多數時候,我們在這個地方用int,表示的范圍都很少的。少一半也夠用。socket不說了吧,理論上只有65536,int再少幾半也夠用,呵呵。 夠用就行了,不用擔心的,真要是需要用大表示,自己做unsigned long來表示,也是可以的。 而且,Unix這麼設計,有個最大的優點,就是數據的自描述特性得到了前所未有的發揮。我們都知道,在表示范圍、容量的時候,int只使用了正數部分,那負數部分做什麼?我來回答你,表示非法值,這個很重要。 試想一下,如果我們用的數據類型裡面,無法表示非法值,那麻煩了,api設計的時候,必須單獨設計一個參數,來傳遞非法值,這又涉及到&傳址調用,或者*直接傳指針調用,程序設計復雜度直線上升,設計的人也累,學的人也累,用起來更累。 這麼說可能不直觀,我舉個例子: 比如我要設計一個read函數,從某個文件id讀取一段數據,大家注意啊,Unix下,文件ID可以表示任何串行化設備的。包括socket,可以用resv這類伯克利socket api,也可以直接使用C基本庫的read,都對,因為使用int表示,Unix可以把所有串行化設備統一編址處理,用一類函數處理完。 函數原型我這麼設計,設計了兩個,大家比較一下: Code:
本文出自 “肖舸的blog” 博客,請務必保留此出處http://tonyxiaohome.blog.51cto.com/925273/309032