farseerfc.wordpress.com 導入

2.6 I386平臺C函數的可變參數表(Variable Arguments)

基於前文(2.4節)分析,我們可以不通過函數簽名,直接通過指針運算,來得到函數的參數。由於參數的壓棧和彈出操作都由主調函數進行,所以被調函數對於參數的真實數量不需要知曉。因此,函數簽名中的變量聲明不是必需的。爲了支持這種參數使用形式,C語言提供可變參數表。可變參數表的語法形式是在參數表末尾添加三個句點形成的省略號“...”:

void g(int a,char* c,...);

省略號之前的逗號是可選的,並不影響詞法語法分析。上面的函數g可以接受2個或2個以上的參數,前兩個參數的類型固定,其後的參數類型未知,參數的個數也未知。爲了知道參數個數,我們必須通過其他方法,比如通過第一個參數傳遞:

g(3,”Hello”,2,4,5);//調用g並傳遞5個參數,其中後3個爲可變參數。

在函數的實現代碼中,可以通過2.4節敘述的 …

farseerfc.wordpress.com 導入

2.7 I386平臺的其它函數調用模型

上文介紹的只是I386平臺上C函數調用的標準模型,被稱作__cdecl。事實上,Microsoft Visual C++編譯器還支持其它一些函數調用模型,所有調用模型名稱皆以雙下劃線開頭,下面列出所有函數調用模型的異同:

1 __cdecl

參數壓棧順序:逆序(從右至左)

參數堆棧恢復者:主調函數(caller)

__cdecl明確地指出函數使用C函數調用模型,這是默認的調用模型。

2 __stdcall

參數壓棧順序:逆序(從右至左)

參數堆棧恢復者:被調函數(callee)

__stdcall是微軟所謂的標準調用模型。可惜的是它與__cdecl不兼容。幾乎所有的Win32API函數使用這種函數調用模型,希望在DLL之間,或者在程序和WinNT操作系統之間傳遞函數指針的函數也應該使用這種模型。與__cdecl模型的不同之處在於,__stdcall模型下由被調函數恢復堆棧。主調函數在call語句之後,不需要再加上add語句。而被調函數的ret語句則被添加一個參數,代表函數參數堆棧的長度。因此,被調函數需要明確的知曉函數參數的數量和類型,所以在__stdcall模型下不支持可變參數表,所有參數必須寫明 …

farseerfc.wordpress.com 導入

2.1   X86概述

所謂X86體系結構,是指以Intel 8086芯片爲首的芯片所沿襲的CPU結構,一些文檔中又被稱作IA32體系結構。包括的芯片有但不限於:Intel 8086至 80486,奔騰(Pentium)系列處理器1至4,賽揚系列處理器,酷睿系列處理器,以及AMD的相應型號產品。X86體系結構在早期屬於16位處理器,自80386之後擴展爲32位處理器,所以一些文檔中又把80386之後的32位處理器體系稱作I386。自Pentium4後期,AMD的Athlon64開始,I386被進一步擴充爲64位處理器,含有64位尋址能力的X86體系結構被稱作X86-64或IA32-64。總之,市售的個人電腦用CPU,除蘋果的Macintosh之外,全部採用X86體系結構芯片。

在X86早期,16位的尋址能力只支持64KB(2^16=64K)內存,這顯然是不夠的。Intel採用分段尋址的方法,用4位段位+16位偏移量,提供了總共1MB(2^20=1M)的尋址能力。所以在X86的16位編程中,有兩種指針類型 …

farseerfc.wordpress.com 導入

1.2   逗號運算符(,)、邏輯運算符(&&,||)與運算符重載的陷阱

很多人甚至不知道逗號(,)也是個C++運算符。與語法上要求出現的逗號(比如分隔函數參數的逗號)不同的是,出現在表達式中的逗號運算符在語義上表示多個表達式操作的連續執行,類似於分隔多語句的分號。比如:

for(inti=0,j=9;i<10;++i,--j)std::cout<<i<<”+”<<j<<”=9\n”;

在這句語句中,出現了兩個逗號,其中前者是語法上用來分隔聲明的變量的,並非逗號運算符,而後者則是一個逗號運算符。根據C++標準,逗號運算符的執行順序爲從左到右依次執行,返回最後一個子表達式的結果。由於只有最後一個表達式返回結果,所以對於一個語義正常的逗號表達式而言,前幾個子表達式必須具有副作用。同時,從語言的定義中也可以看出,逗號表達式對求值的順序有嚴格要求 …

farseerfc.wordpress.com 導入

1.1   條件運算符(?:)

條件運算符(?:)是C++中唯一的三目運算符(trinary operator),用於在表達式中作條件判斷,通常可以替換if語句,與Visual Basic中的iif函數、Excel中的if函數有同樣的作用。語法形式如下:

condition ? true_value : false_value

其中condition *條件是任何可以轉換爲bool類型的表達式,包括但不僅限於**bool*int、指針。與ifwhile的條件部分稍顯不同的是,這裏不能定義變量,否則會導致語法錯誤。

另外,條件語句會切實地控制執行流程,而不僅僅是控制返回值。也就是說,兩個返回值表達式中永遠只有一個會被求值,在表達式的執行順序很重要時,這點尤爲值得注意。比如:

int *pi=getInt();

int i=pi …

farseerfc.wordpress.com 導入

填補信仰、喚醒良知

我們聽盡了呼籲與號召,對於良知,我不必譴責喪失它的國人,不必盛讚良知的美好。我只想討論,喪失了良知的原因——空缺的信仰。

一、空缺信仰喪失良知

現代的國人缺少信仰,以至於喪失良知。曾幾何時,中華民族由良好的信仰凝聚而成。三皇五帝時,族民們以炎黃爲信仰;春秋戰國時,士大夫之族以周制禮樂爲信仰;漢代以後,百姓延習孔孟之說、老聃之道,以儒家學說爲信仰;自大唐起,以佛教爲首的現代宗教紛紛傳入中原,人民開始以它們作爲信仰。

直至鴉片戰爭、五四運動,西方文化入侵中華,國人開始拋棄國學,轉而去研究科學;文化大革命,十年文化浩劫,人們批判舊的信仰,卻沒有合適的新的信仰前來填補。從此,國人的信仰出現空缺,國人的良知也被一塊塊蠶食殆盡。

二、信仰、科學、迷信

在許多國人的心目中,信仰就等於迷信。從小到大的教育告訴我們 …