《C專家程式設計》學習筆記2

2022-08-14 07:09:14 字數 3379 閱讀 5286

乙個 l的 nul用於結束乙個ascll字串

兩個l 的null 用於表示什麼也不指向的指標

標準的c編譯器至少允許一條switch語句中有257個case標籤。為了滿足乙個8bit的字元的所有情況。

switch的另乙個問題是它內部的任何語句都可以加上標籤,並在執行時跳轉到**,這就有可能破壞程式流的結構化。(類似於goto)

證明在c語言中const並不表示常量,可以在switch-case語句的case中加乙個狀態case:const i,編譯時會抱錯,非常量;

break語句中斷了什麼?break語句事實上跳出的是最近的那層迴圈語句或switch語句,由此導致at&t的第一次網路故障。

ansi c引入的另乙個特性是相鄰的字串常量將被自動合併成乙個字串的約定。留意 字串末尾的逗號是從最早的c語法中繼承下來的,不管存在與否,沒有任何意義。

軟體物件在大多數情況之下應該預設地採用有限可見性。當程式設計師需要將它全域性可見時,應該採用顯式的手段。

c語言中的符號過載:

static 在函式內部,表示該變數的值在各個呼叫期間一直保持延續性;

在函式這一級,表示該函式只對本檔案可見

extern用於函式定義表示全域性可見(屬於冗餘的)

用於變數,表示它在其他地方定義

sizeof不是乙個函式,sizeof是c/c++中的乙個操作符(operator),簡單的說其作用就是返回乙個物件或者型別所佔的記憶體位元組數;

易錯的c語言運算子優先順序問題

.的優先順序高於*,而-〉的作用就是消除這個問題,例如 *p.f 的含義就是*(p.f)

的優先順序高於* 例如 int*ap表示ap是乙個元素為int指標的陣列

==和!=高於位運算子    例如(val & mask!=0)的含義是 val& (mask!=0)

==和!=高於賦值運算子  例如 c=gerchar()!=eof 的含義是c=(getchar(0!=eof)

算術運算子高於移位運算子  例如 msb<<4+lsb 的含義是msb<<(4+lsb)

逗號運算子在所有運算子中優先順序最低

在表示式中如果有布林操作,算術運算和位操作等混合運算,你始終應該在適當的地方加上括號

所有的賦值符都具有右結合性,就是說表示式的最右邊的操作最先執行,然後從右到左執行,.例如a=b=c 順序是  b=c,然後a=b;類似的具有左結合的運算子(如&,|)則是從左到右依次執行。

列舉有乙個優點:#define定義的名字一般在編譯的時候被丟棄,而列舉的名字則通常一直在偵錯程式中可見,可以在除錯**時使用它們。

typedef和#define的區別

……#define是預處理指令,在編譯預處理時進行簡單的替換,不作正確性檢查,不關含義是否正確照樣帶入,只有在編譯已被展開的源程式時才會發現可能的錯誤並報錯;

……typedef是在編譯時處理的。它在自己的作用域內給乙個已經存在的型別乙個別名

把typedef看成是一種徹底的「封裝」型別,在宣告它之後不能在往裡面增加別的東西。

1)可以用其他型別說明符對巨集型別名進行擴充套件,但對typedef所定義的型別名卻不能這樣做;

例如             #define a  int

unsigned a  i; /*沒問題*/

typedef   int  a;

unsigned a  i;/*錯誤,非法*/

2)在連續的幾個變數中,用typedef定義的型別能夠保證宣告中所有的變數均為同一種型別,而用#define定義的型別則無法保證

例如             #define int_ptr int*

int_ptr a ,b;

巨集擴充套件為 int* a,b; a是指標 b是int型

但是 typedef char*  char_ptr;

char_ptr a,b;

此時 ab型別是相同的;

典型應用……………………

typedef int * pint ;

#define pint int *

那麼:const pint p ;//p不可更改,但p指向的內容可更改

const pint p ;//p可更改,但是p指向的內容不可更改。

pint是一種指標型別 const pint p 就是把指標給鎖住了 p不可更改

而const pint p 是const int * p 鎖的是指標p所指的物件。

…………………………此處可以將typedef理解成完全封裝,所以const就和p直接繫結了……………………………………

c語言中的物件必須有且只有乙個定義,但它可以有多個extern宣告.

指標和陣列的區別:

定義指標時,編譯器並不為指標所指向的物件分配空間,它只是分配指標本身的空間,除非在定義時同時賦給指標字元常量進行初始化 注意只有對字串長;量才是如此;

不能指望為浮點數的常量分配空間;

例如 float *pip=3.14;/*錯誤,編譯無法通過*/

在ansi c中,初始化指標時所建立的字串常量被定義為唯讀,與指標相反,由字串常量初始化的陣列是可以修改的。

(承接p192)

對陣列的下標的引用總是可以寫成「乙個指向陣列的起始位址的指標加上偏移量」。

對陣列的引用如a[i]在編譯時總是按被編譯器改寫成*(a+i)的形式。

只有字串常量才可以初始化指標陣列。指標陣列不能由非字串的型別直接初始化。

::被稱為「全域性範圍分解符」。跟在它前面的識別符號就是進行查詢的範圍。如果::前面沒有識別符號。就表示查詢範圍為全域性範圍。

每個成員函式都有乙個this指標,它是隱式賦給該函式的,它允許物件在成員函式內部引用物件本身。

當乙個類的物件被建立時,建構函式會被自動呼叫,程式設計師永遠不應該顯式呼叫建構函式。至於全域性和靜態物件,它們的建構函式會在程式開始時被自動呼叫,而當程式終止時,他們的析構函式會被自動呼叫。

多型是一種執行時效果,它是指c++物件在執行時決定應該呼叫哪個函式來實現某個特定操作的過程。

c++的異常(exception)用於在錯誤處理時改變程式的控制流。異常通過發生錯誤時把處理自動切換到程式中用於處理錯誤的那部分**,從而簡化錯誤處理。

new能真正建立乙個物件,而malloc()函式只是分配記憶體。

在c++中,宣告可以出現在語句可以出現的任何地方,在c語言中的**塊中,所有的宣告必須出現在所有的語句的前面。

庫函式呼叫和系統呼叫區別何在?

函式庫呼叫時語言或應用程式的一部份,而系統呼叫時作業系統的一部分。

語言排斥強語言型別,允許不同資料型別的轉換,如單精度,雙精度浮點數和

字元auto關鍵字是擺設,只對建立符號表入口的編譯器設計者有意義。

標準c中float自動轉化成double型別,但是在ansi c中不再如此;

一般性的宣告可以被分離到頭檔案中,並且可以被許多原始檔使用,

#define命令需要更仔細的分辨

任何學習或者使用c語言的人都應該使用ansi c。

C專家程式設計學習筆記 2

第4章 令人震驚的事實 陣列和指標並不相同 1.區別定義和宣告 宣告相當於普通的宣告 它所說明的並非自身,而是描述其他地方的建立的物件.定義相當於特殊的宣告 它為物件分配記憶體 2.當書寫了extern char p,然後用p 3 來引用其中的元素時,編譯器將會 1 取得符號表中p的位址,提取儲存與...

《C專家程式設計》筆記2

無論在什麼時候,如果遇見了這樣一條語句malloc strlen str 幾乎可以斷定它是錯誤的,malloc strlen str 1 才對 總結 進步是計算機軟體工程和程式語言設計藝術逐步發展的重要動因 includeint main int argc,char argv 以上 編譯都不會通過,...

C專家程式設計學習筆記一

typedef和巨集文本替換的重要區別 首先,可以用其它型別說明符對巨集型別名進行擴充套件,但對typedef所定義的型別名卻不能這樣做。其次,在連續幾個變數的宣告中,用typedef定義的型別能夠保證宣告中所有的變數均為同一種型別,而用 define定義的型別則無法保證。編譯器位於編譯過程的哪乙個...