C語言深度剖析筆記

2021-09-02 17:39:07 字數 3131 閱讀 8811

1.變數定義:所謂的定義就是(編譯器)建立乙個物件,為這個物件分配一塊記憶體並給它取上乙個名字,這個名字就是我們經常所說的變數名或物件名。

2.變數宣告:1.告訴編譯器,這個名字已經匹配到一塊記憶體上了,下面的**用到變數或物件是在別的地方定義的。宣告可以出現多次。

2.告訴編譯器,這個名字已被預訂了,別的地方再也不能用它來作為變數名或物件名。

定義變數規則:禁止使用八進位制的常數(0除外)在計算機中,任何1以0開頭的數字都被認為是八進位制格式的數(當然十六進製制的0x不算)。所以,當我們寫固定長度的數字時,會存在一定的風險。舉例如下:

code[1] = 109;//對應十進位制的109

code[2] = 100;//對應十進位制的100

code[3]=052; // 對應十進位制的42,因為052是以0開頭,以八進位制形式儲存。

code[4] = 071;//對應十進位制的57

在轉義字元中後面跟八進位制數,用於表示ascii碼等於該值的字元,使用時也可能

會出現意想不到的錯誤

code[6] = 『\100』;儲存的值可能為64

sizeof:

sizeof在計算變數所佔空間大小時,括號可以省略,而計算型別大小時不能省略。且一般情況下,sizeof是在編譯時求值,所以sizeof(i++)不會引起***。但由於sizeof(i++)與sizeof(i)的

結果一樣,所以沒有必要且不允許寫這樣的**。

注意:在用sizeof測字串長度時,會算上』\0』結束字元的長度,但是如果把字串以單個字元的形式存在陣列中時不會算』\0』的長度。

而在用strlen測時不會算上』\0』的長度。

#include #include int main()

; printf("%lu\n",sizeof(s1));

printf("%lu\n",strlen(s1));

printf("%lu\n",sizeof(s2));

printf("%lu\n",strlen(s2));

return 0;

} 結果是:8 7 7 7

signed、unsigned關鍵字

32位的signed int 型別整數,其值表示的範圍為:-231~(231-1)

32位的unsigned int 型別整數,其值表示的範圍為:0~(2^31-1)

例:

int main()

printf("%d",strlen(a));

return 0;

} 答案是255;

分析:for迴圈內,當i的值為127時a[127]=-128,而-128是char型別資料能表示的最小的負數,當i繼續增加時a[128]的值肯定不能是-129,這時發生了溢位,最高位被丟棄,剩下的8位是原來9位補碼的低8位的值,即0x7f。當i繼續增加到255的時候,-256的補碼的低8位為0;然後當i增加到256時,-257的補碼的低8位全為1,即低8位的補碼位0xff,如此又開始一輪新的迴圈,因此a[255]=0;strlen函式遇到』\0』結束 因此是255;

迴圈語句的注意點:

1.在多重迴圈中,如果可能,應當將最長的迴圈放在最內層,最短的迴圈放在最外面,以減少cpu

跨切迴圈層的次數。

2.建議for語句的迴圈控制變數的取值採用"半開半閉區間寫法"

3.不要再迴圈內部修改迴圈變數,防止迴圈失控。

4.把迴圈巢狀控制在3層以內。

5.for語句的控制表示式不能包含任何浮點型的物件。

const:定義const唯讀變數,具有不可變性。

「近水樓台先得月」

const int p;//const修飾p,p是指標,*p是指標指向的物件,不可變

int const *p;同上

int *const p;//修飾的是p,p不可變,p指向的物件的值可變

const int * const p;//都不可變

一、列舉與define的區別:

1.#define 巨集常量是在預編譯階段進行簡單替換,列舉常量則是在編譯的時候確定其值。

2.一般在偵錯程式裡,可以除錯列舉常量,但不能除錯巨集常量。

3.列舉可以一次定義大量相關的常量,而#define巨集一次只能定義乙個。

二、\ddd

1~3位八進位制數所代表的字元

\xhh

1~2位十六進製制數所代表的字元

三、貪心法:

每乙個符號應該包含盡可能多的字元。

四、2/(-2)的值為多少?

經測試2/(-2)為-1,2%(-2)為0。

q = a/b;

r = a%b;

1.我們希望q*b+r==a

2.如果我們改變a的正負號,希望q的符號也隨之改變,但q的絕對值不會變。

3.當b>0時,我們希望保證r>=0且r

一、指標

1.乙個基本的資料型別(包括結構體等自定義型別)加上號就構成了乙個指標型別的模子。這個模子的大小是一定的,與"「號前面的資料型別無關;」*「號前面的資料型別只是說明指標所指向的記憶體裡儲存的資料型別。所以在32位系統小,不管什麼樣的指標型別,其大小都為4位元組。可以測試一下sizeof(void *)

int main()

結果: 8 8 8 (64位系統)

2.int p = null和p = null的區別

int p = null;

定義乙個指標變數p,其指向的記憶體裡面儲存的是int型別資料;在定義變數p的同時把p的值設定為0x00000000,而不是把p的值設定為0x00000000、這個過程叫初始化,是在編譯的時候進行的。

int *p;

p = null;

第一行**定義了乙個指標變數p,其指向的記憶體裡面儲存的是int型別的資料;但是這時候變數p本身的值是多少不得而知,也就是說現在變數p儲存的可能是乙個非法的位址。第2行**,給p賦值為null,即給p指向的記憶體賦值為null;但是由於p指向的記憶體可能是非法的所以除錯的時候偵錯程式可能會報告乙個記憶體訪問錯誤。

將**改寫一下:

int i = 10;

int *p = &i;

*p = null;

發現p指向的記憶體由原來的10變為0了;而p本身的值,即記憶體位址並沒有改變。

《C語言深度剖析》筆記

c語言深度剖析 筆記 1.在c語言中,凡不加返回值型別限定的函式,就會被編譯器作為返 回整形處理。2.register 變數必須是乙個單個的值,並且其長度應小於或等於整型 的長度。而且 register 變數可能不存放在記憶體中,所以不能用取 址運算子 來獲取 register變數的位址。3.int...

C語言深度剖析筆記(二)

系統大小端模式檢測 include int checksystem t t.a 0x12345678 return t.c 0x78 int main define是編譯預處理指令,在編譯預處理時換,不作正確性檢查,不論是否正確只進行帶入替換,只有在編譯已被展開的源程式時才會發現可能的錯誤並報錯。2...

C語言深度剖析筆記2

int a 5 a作為右值時,代表陣列首元素的位址,而非陣列的首位址。sizeof a 的值為sizeof int 5 為20 sizeof a 0 的值為sizeof int 為4 sizeof a 5 為4 為什麼不報錯呢?因為函式求值是在執行的時候,而關鍵字sizeof求值是在編譯的時候.雖然...