1. 程式人生 > >C語言常見陷阱錯誤及知識點

C語言常見陷阱錯誤及知識點

“#”預處理機制(獨立於編譯期)遇到<>查詢系統 遇到“”先查詢自己的沒有查詢庫的

主函式 int main(int argc, char*argv[])  第二個引數代表要傳的字串 例如 ./app aa bb 就可以將aa bb傳進去 現在的第一個引數是 3 (這個引數會將操作命令也算入)

基本的資料型別

I.整數   char   一個位元組   -128~127   short 兩個位元組 -32768~32767   int   四個位元組 -2147483648~2147483647   long 四位元組(32x) 八個位元組(64x)

II.小數(實型)float 四個位元組 精確到小數點後六位  double 八個位元組 精確到小數點後八位

例題

char a,b,c,d;

a=30;

b=a++;

c=++a;

d=(a++)*10;

答案:a=33;  b=30; c=32; d=64;

解析:1)b=a++; 先賦值再++ 所以b=30 執行完這條語句後a變為31;

           2)c=++a;先++再賦值 c=32,此時的a變為 32;

           3)d=(a++)*10; 先賦值再++ 所以 d=32*10;但是 a,b,c,d 都為char所以會發生截斷 為64

例:

  int i=4; int j=5;  int k; k=i+++j; 執行完後 i? j? k?

答案為 i=5,j=5,k=9;

解析:+++有三個+號時 ++跟前面的結合 即  k=(i++)+j;

邏輯運算子 && || 短路原則 (非零真 零假)

對記憶體的操作:讀,寫,取地址   記憶體基本操作單元是位元組

記憶體分為 堆區 棧區 字元常量 程式碼 全域性(靜態)

堆區:程式設計師放的 由連結串列管理堆區空間

棧:除了全域性靜態變數以外的變數

字元常量:存字元常量

全域性(靜態):存全域性和靜態變數

堆區和棧區的區別:

1.申請方式(棧:系統 堆:程式設計師)

2.棧區效率高,堆區有記憶體碎片

3.生命週期(棧區:系統回收 堆區:遇到delet free)

4.生長方向(空間分配)(棧區:從大地址到小地址 堆區:從小地址到到大地址)

5.訪問

6.儲存內容

全域性和靜態區別:作用範圍  全域性更大 全域性是整個專案 靜態是定義的那個檔案 靜態是定義一次丙炔儲存其值

const在c語言和c++中的區別

區別1:
 C語言的const是定義了一個const變數,該變數只具備讀的功能,而不具備寫的功能。
 C++的const是定義了一個常量。

const int a = 5;
int array[a];//在C語言中是錯誤的,因為在C語言中是定義了一個只讀變數
int array[a];//在c++中是正確的,因為在C++中定義了一個常量

區別二:
C語言中不能定義const函式,而C++中可以定義const函式。
C++的const成員函式:不能修改類的成員變數的值。(此處就不列舉例子了)

指標常量和常量指標:

1、指向指標的常量:當const在*號前面就是指向常量的指標。

2、常量指標當const在*號之後

   char *const p1 = "12445";
   p1[0] = 'w';  //正確,可以修改指向記憶體的值
   p1 = "ddddd"; //錯誤,不能修改p1指向的記憶體

define const 區別:

1.編譯器處理方式不同
define巨集是預處理階段展開
const常量是編譯執行階段使用

define是巨集定義,程式在預處理階段將用define定義的內容進行替換,因此程式執行時常量表中並沒有用define定義的常量,系統不為其分配記憶體。
const常量是編譯執行時的常量,系統為其分配記憶體。

2.型別跟安全檢查不同
define巨集沒有型別,不做任何型別檢查,僅僅是展開
const常量有具體的型別,編譯執行時會執行型別檢查

3.儲存方式不同
define僅僅是展開,有多少地方使用就展開多少次,不分配記憶體
const常量會在記憶體中分配(可以在堆中也可以在棧中)

4.const可以節省空間,避免不必要的的記憶體分配。

define注意“邊緣效應”,
例:#define N 2+3 //N的值是5
int a = N/2,//在編譯時我們預想a=2.5,實際列印結果是3.5
原因是在預處理階段,編譯器將a=N/2處理成a=2+3/2,這就是define巨集的邊緣效應;
所以我們應該寫成#define N (2+3)

陣列:連續型別相同的

int a[5]={1,2,3,4,5};

a==&a[0];

陣列名代表首元素的首地址    &+陣列名:整個陣列的首地址  sizeof(陣列名)整個陣列

sizeof()不是函式是一個含引數的巨集

陣列偏移 

a+1向後偏移4個位元組

&a+1向後偏移a[5]

求*((int*)((int)&a+1))

   

(int)&a=0x10   0x10+1=0x11

*int(0x11) 連續四個位元組再取* 02000000

陣列與連結串列的區別

1.空間的連續性與否

2.支援不支援隨機訪問

3.空間的固定

4.插入 刪除