一、
c詭異離奇,缺陷重重,卻獲得了巨大的成功。
·編譯器設計:效率(幾乎)就是一切。編譯器的效率包括兩個方面:執行效率(**的執行速度)和編譯效率(產生可執行**的速度)。
除了開發和學習環境外,執行效率起決定作用。
·陣列下標0的開始。這個編譯器的設計者的選擇,因為偏移量的概念在他們心中已經根深蒂固。
·c語言的基本資料型別與底層硬體相對應。
·auto關鍵字是擺設(在c++11後,auto已經變成自動型別判定這一強大功能)
·c程式設計師要自己管理動態記憶體的使用,建立各種大小的陣列,測試陣列邊界。並且自己進行範圍檢查。
c++引入一些新方法,使得巨集這種預處理器幾乎無用武之地。(這句話並不理解)
編譯限制:在**移植的時候應該不同編譯器之間的差距。
·「安靜的改變」 算術的轉換 ,2個運算元的型別不同將會被轉換。
資料型別朝著浮點精度更高、長度更長的方向轉換,整形數如果轉換為signed不會丟失資訊,就轉換為signed,否則轉換unsigned。
當無符號數unsigned int 和signed int比較的時候,在標準c(anci c),有符號數將被自動轉換為無符號數。(注意當出現比較的時候,可能出現bug)
【盡量不要使用無符號數】包括年齡,國債等。
·二、這不是bug,而是語言特性
·switch: 1、 如果沒有default,而且所有的case都不匹配,那麼將跳過這個switch**段。
2、一條switch最多有257個標籤(256個可能的值和乙個eof)
3、把default打成defau1t(把「l」打成「1」),一般的lint程式檢測不出
4、const並不是常量
5、一般來說case後面要加break,不然將順序執行case 語句(fall through錯誤)
在定義c函式的時候,在預設情況下函式的名字是全域性可見的。
在函式前加extern的預設儲存型別說明符是冗餘的。
想要限制對這個函式的訪問必須在函式前加乙個static。
多義符號(多用符號)
static
在函式內部,表示該變數的值在各個呼叫中保持延續性
在函式這一級,表示該函式只對本檔案可見
extern
用於函式定義,表示全域性可見(屬於冗餘的)
用於變數,表示它在其他地方定義
void
作為函式的返回型別,表示不返回任何值
在指標宣告中,表示通用的指標宣告
位於引數列表中,表示沒有引數
*乘法運算子
用於指標,間接引用
位於引數列表中,表示沒有引數
&位的and操作符
取位址操作符
優先順序問題
表示式可能誤以為的結果
實際結果
.的優先順序高於*
(->操作符用於解決這個問題)
*p.f
p所指物件的字段f
(*p).f
對p取f偏移,作為指標,然後進行接觸引用操作
高於*int *ap
ap是個指向int陣列的指標
int(*ap)
ap是個元素為int指標的陣列
int *(ap)
函式( )高於*
int *fp()
fp是個函式指標,所指向的
函式返回int
fp是個函式,返回值是個int*型別
==和!=高於位運算子
(val&mask!=0)
(val&mask)!=0
val&(mask!=0)
算術運算子高於移位運算子
msb<<4+lsb
(msb<<4)+lsb
msb<<(4=lsb)
逗號運算子優先順序最低
有一條很實用的建議:乘法和除法優於加法和減法,在涉及其他操作符是一律加上括號。
運算子的結合性:結合性只用於表示式中同時出現2個相同的優先順序操作符的情況,用於消除歧義。
例如a=b=c; =具有右結合性,所以該句語句等同於,b=c;a=b;
(不如分開或是用括號,不要自找麻煩)
在函式中返回乙個陣列例如下面的**
char * localize_time(char * filename)
buffer是乙個自動分配記憶體的變數,也就是函式的區域性變數,當控制流離開宣告區域性變數的範圍時,自動變數將失效。
返回乙個指向區域性變數的指標,當函式結束,該變數已經被銷毀,誰也不知道這個指標指向位址的內容是什麼。
解決方案:
a、使用全域性宣告的陣列
簡單易用,任何人都有可能修改這個陣列。
函式的下一次呼叫會覆蓋當前的資料。、
b、使用靜態陣列 :static char buffer[20];
將修改範圍限定在函式範圍
函式的下一次呼叫會覆蓋當前的資料
c、顯示的分配記憶體
char * func()
防止函式外的修改
每次呼叫不會覆蓋以前的返回值
適合多執行緒
程式設計師要承擔記憶體管理的責任,必須記得要釋放記憶體,以免造成記憶體洩漏
在同一**塊中進行malloc和free操作,可以更為輕鬆進行記憶體管理
lint程式
lint程式是乙個檢測工具,可以檢查出bug和一些不可靠的編碼風格。後來為了編譯器做得更小、更快、更簡單,
把lint程式從編譯器中抽出來了。
《C專家程式設計》9 10章閱讀收穫
陣列和指標的關係有點像詩和詞的關係 他們都是文學形式之一,有不少共同之處。1 表示式中的陣列名 就是指標 2 c語言把陣列下標作為偏移量 為什麼c語言把陣列形參當做指標 效率 普通引數傳遞時都是傳值呼叫 對實參作乙份拷貝傳遞給呼叫的函式,函式不能修改真實引數,只能修改其拷貝。如果陣列也以這種方式傳遞...
C專家程式設計第一二章筆記
c語言有許多特性是為了方便編譯器設計者而建立的,這大大簡化了c語言本身,這讓c語言更容易學習與理解,同時增加了效率。陣列下標從0開始而不是1 c語言的資料基本型別直接與底層硬體相對應 沒有複數型別 auto關鍵字是擺設,它是預設的記憶體分配模式 表示式中的陣列名看作是指標 但並不等同 float被自...
C Primer 閱讀筆記(1 2章)
1 用istream物件作為條件時,其效果是檢驗流的狀態。如果流是有效的,即未遇到未知錯誤,那麼檢測成功。當遇到檔案結束符,或遇到乙個無效輸入時,istream的物件將會變成無效,處於無效狀態的istream物件會使條件變為假。2 cerr 乙個ostream物件,寫入cerr的資料是不緩衝的,通常...