C語言深度解剖 學習筆記

2021-05-22 13:30:49 字數 2927 閱讀 7267

第一章:關鍵字

1.register:能接受的變數型別,不能用&

2.static:靜態區域性變數 :對定義該變數的函式來說,一直存在,可用。對外不可用

靜態全域性變數:對本檔案或本模組內的任意函式可用。對外不可用

靜態函式:該函式作用域僅限於本檔案

3.資料型別:大小可以用sizeof測定

命名法則

轉換時的精度問題

儲存:原始碼,反碼,補碼的問題

注:當表示式中存在有符號型別和無符號型別時所有的運算元都自動轉換為無符號型別。

4.if

a.布林型別變數與0比較用if(bval)/if(!bval)

b.指標型別變數與0比較用if(p==null)/if(p!=null)

c.需要用空語句時用null;

5.case語句後必須跟整型或char型的常量或常量表示式,const修飾的是唯讀變數,因此不行。

6.void 對函式返回值和引數的限定,空型別,可以指向任何型別資料

7.define與const

define定義的是常量,沒有型別,在編譯期間進行替換並分別記憶體

const定義的是唯讀變數,具有特別型別,如int,在編譯期間不分別記憶體,只是確定其值

8.const: const int a;

int const a;

const int *p;  == int const *p;

const int * const p;  //p及指向的物件都不可變

int * const p; //p不可變,指向的 物件可變

以上定義相同,const修飾在型別符的前面或者後面效果一樣。

9.volatile:用它修飾的變數表示可能會不可**的被改變,編譯器不會對該變數的**進行優化,因此常用該關鍵字對特殊位址進行訪問

10.extern:「外來的」,因此外部檔案的變數或者函式時進行的申明。

11.typedef:

typedef int size;

typedef int add[10];

typedef int (*pf) (const char *, const char *);

去掉定義型別名字(如size,add,pf)後,剩下的就是用來修飾的變數型別,以上3例分別為int,int [10],typedef int (*) (const char *, const char *);

a.在語句構成上,typedef相當於static,extern等儲存類關鍵字,因此typedef不能與其他儲存類關鍵字共修飾,因為乙個變數不能有2種修飾方式。y

b.typedef char* pstr

int mystrcmp(const pstr,const pstr)中的pstr是個型別名,因此const pstr和pstr const是一樣的。因此只要為指標宣告typedef,那麼要在最終的typedef名稱中加乙個const,以確定使得該指標是常量,而不是物件,例如typedef const char

12.struct與class:struct成員預設為public,class成員預設為private

13.union與enum

14. 1,'1',"1"的區別:分別是整型,字元,字串型別,字元以asc碼形式儲存。

第二章:符號

熟悉掌握各運算子及其優先順序

第三章:預處理

1.#define 巨集定義常量或表示式

2.#undef 撤銷巨集定義

3.條件編譯:

#ifdef(或#ifndef, 或#if)

...#else

...#endif

a.#if後面跟常量

b.#elif意義與else if同,可進行多種編譯選擇

3.檔案包含:#include

4.記憶體對齊:

比如32位處理器,位址訪問預設自然邊界是4。訪問未對齊(不是4的倍數)的記憶體時,處理器要做2次訪問,為了提高程式效能,資料結構盡可能的在自然邊界上對齊。如果沒有對齊,可能造成2種結果:一是程式執行速度降低,二是系統分配額外的空間來做記憶體對齊操作,可能會造成程式結果的錯誤(具體可參考專門的文章)。可用pack關鍵字調整記憶體對齊數

第四章:指標與陣列

指標陣列:int *a[10]; //比*優先順序高,因此a首先是陣列位址,該陣列裡存放了10個int*型別的指標

陣列指標: int (*a)[10];//首先確定a是指標型別,然後是指向int [10]陣列型別的指標

函式指標:char* (*add)(void);//定義指標add,指向char* (*)(void)型別的函式

函式指標陣列:char* (*add[10])(void);//定義陣列add[10],存放10個char* (*)(void)型別的元素

指標加減法運算:如p+n,p當前位址+sizeof(p)*n,而p指向的型別可以轉換,任意型別的指標只占用4bytes

關於複雜的指標計算,可以用記憶體布局圖來分析

第五章:記憶體管理

一般程式記憶體分為三塊:靜態區,堆,棧(堆疊)

靜態區存放:static變數,全域性變數等

堆:有malloc或new分配的記憶體,生命週期有free或delete決定

棧:儲存區域性變數,其生命週期有函式決定,函式執行結束,該棧銷毀

這裡對棧需要說明一下:形參值參進入函式,函式在棧內分配記憶體copy,因此函式內部使用的是引數的copy,不改變引數本身,但生命週期結束後,棧銷毀,只能通過return返回對應的值,如要返回指標,則要注意對應記憶體是否已經銷毀。

注:1.定義指標的同時,一定要初始化,否則可能形成野指標,造成不可預計的錯誤

2.free函式用來斬斷指標和malloc分配的記憶體的關係,free後,對應指標沒有銷毀,指向不確定位址,因此需要重新初始化

如: char *p=(char*)malloc(sizeof(char));

...free(p);

p=null;

第六章:函式

遞迴函式

第七章:檔案結構

C語言深度解剖學習(一)

c語言關鍵字有32個,其中比較特殊的是sizeof,sizeof是關鍵字,而不是函式。c語言中定義與宣告的區別 定義 就是 編譯器 建立乙個物件,為這個物件分配一塊記憶體並給它取上乙個名字,這個名字就是我們經常所說的變數名或物件名。但注意,這個名字一旦和這塊記憶體匹配起來 可以想象是這個名字嫁給了這...

c語言深度解剖筆記

關鍵字 register 這個關鍵字請求編譯器盡可能的將變數存在 cpu內部暫存器中而不是通過記憶體定址訪問以提高效率。注意是盡可能,不是絕對。你想想,乙個 cpu的暫存器也就那麼幾個或幾十個,你要是定義了很多很多 register 變數,它累死也可能不能全部把這些變數放入暫存器吧,輪也可能輪不到你...

C語言深度解剖 筆記4

1最易變的關鍵字 volatile 型別修飾符 用volatile修飾的變數表示可以被某些編譯器未知的因素更改,比如作業系統 硬體或者其他執行緒等。遇到這個關鍵字宣告的變數,編譯器對訪問該變數的 就不再進行優化,從而可以提供對特殊位址的穩定訪問。比如 volatile關鍵字告訴編譯器某變數是隨時可能...