原创 內存篇之堆與棧的繞口令

    堆(heap)/棧(stack或call stack)是兩塊功能完全不同的系統內存區,堆內存是由malloc/free函數動態申請和回收,而棧則是編譯器與啓動代碼或線程創建代碼配合,約定用CPU某寄存器標識最新使用位置的一段內存(

原创 補遺篇之volatile

    C中volatile關鍵字在程序操作變量時,強制讀寫變量所在內存,以阻止編譯器對某些特殊變量的錯誤優化。反過來,只有靠程序員用volatile過濾一些特殊情況後,編譯器才能大膽優化。volatile作用可總結爲:阻止三種情形下的兩

原创 補遺篇之內聯與內嵌

    從沒想過有人會把這兩個毫不相關的概念混爲一談,可招聘時還真就碰到問內聯答內嵌的情況。上網一查,原來內嵌彙編也常被叫內聯彙編,中文表述IT名詞時真就這麼乏力麼?蹩腳的撞名一個接一個。     內聯函數即inline函數,其作用是“建

原创 內存篇之程序內存佈局

    程序內存佈局是理解軟件本質的基礎要素。支持一個程序運行的所有內存大體可分爲以下幾部分,或者說程序運行需要系統爲其提供如下幾部分存儲區域:     棧:由編譯器自動分配釋放,存放函數參數,局部變量等,特點爲後進先出。     堆:程

原创 C陷阱篇之運算符優先級

    C語言運算符有不同優先級,標準裏對這些優先級的規定基本符合人們的正常認知習慣,但其中還有個別容易混淆。其實也不需要死記硬背所有優先級,只要注意幾個例外就可以了: “+-”與”>>”運算符     因爲<<和>>某些情況下相當於乘/

原创 補遺篇之C字符串

    C並沒有字符串類型,C字符串是一個以null('\0')結尾的字符數組,用null標識字符串結束。如{'a','b','c','d','\0'},只有包含這個'\0’纔算C字符串。注意null也好,'\0'也罷,都只是0的不同表達

原创 補遺篇之sizeof

    sizeof是C的單目運算符,它給出操作數存儲所需的字節數,其操作數可以是表達式或類型名。sizeof()是運算符,不是函數,沒有函數調用開銷。其結果是在編譯階段由編譯器自動給出,相當於常數,不象函數那樣在運行時纔得到返回值。  

原创 補遺篇之單行道標誌const

    面試時,問及const的含義,很多人會答:"const表示常量",這可不是考英文翻譯,const應該更近似"只讀"而不是常量。const語法    對非指針變量,const無論放在類型前或後,都表示變量屬性爲只讀,運行過程中不能也

原创 關於C語言優化

     前幾天看網上新聞,有人建議把編程納入高考,且不論是否靠譜,卻至少說明一件事:會寫點程序不再有什麼可炫耀的,將來更有可能成爲全民普及技能。其實即使現在,很多人寫程序的興奮感還沒消退,就悲哀地發現自己程序寫得蹩腳,反倒成爲了周圍人的

原创 內存篇之指向棧的指針

    下面程序運行有什麼樣的結果?     char *GetString(void)     {       char array[6];       strcpy(array, “hello”);       return arra

原创 C陷阱篇之常見手誤

    C的某些語法容易讓人不小心觸雷,比如 從0開始的下標     很多高級語言中,定義n個元素的數組,下標範圍是從1到n,但C特殊,n元素的C數組中沒有下標爲n的元素,只有從0到n-1的下標。所以使用C數組時不要犯這種錯誤: int

原创 內存篇之堆的錯誤釋放

    在我開始寫程序時因爲擔心某些分支下忘記釋放內存導致泄漏,就想能不能保險點,多加幾次釋放,但很快發現堆內存不能重複釋放,一些錯誤釋放甚至會導致系統崩潰。這類錯誤可分幾種情況: 1)重複釋放某指針指向的內存,多數由於調用了不同層的子函

原创 C陷阱篇之語法正確語義錯誤的編譯器侷限

    編譯器功能只是語法檢查,只要語法正確,那它就遵循一個原則:程序員總是對的。其實也只能這樣,如果腦子裏想着A,實現的卻是B,而A/B語法上都成立,那編譯器除了認爲你正確,還能做什麼呢?只能我們自己注意區分A/B相似且語法都成立的下列

原创 內存篇之野指針

    前面兩文中內存錯誤釋放以及錯誤訪問指向棧的指針,從另外角度,其中一部分錯誤還可以歸結爲訪問了野指針。野指針又稱懸掛指針,代表那些指向不可用內存區域的指針。操作野指針,程序會發生難以預料的錯誤。形成野指針主要有以下原因: 1)指針

原创 C優化篇之減少運算量

    程序優化的另一個出發點是減少運行過程中的運算量,有兩個大的思路:     1)把部分計算量轉移到離線,或者說把一部分工作挪到程序之外,人爲處理,以減輕程序本身壓力。比如查表、浮點轉定點以及其他數學算法的優化等。     2)分析和