1. 程式人生 > >C語言中的各種小知識點(自己做的筆記)

C語言中的各種小知識點(自己做的筆記)

由於學習上和工作中對C語言用的比較多,但是手頭上又有很多工作要做,不可能隨時記得住,所以以此為筆記,衡而記之。(實時更新)只寫淺顯的結果,不寫原理!對於工程人員來說,大部分情況是夠用的。

1、sizeof()與strlen()的區別
sizeof()用於計算變數或者資料型別的記憶體容量的函式。怎麼理解這個變數和資料型別呢?變數就是值可以變的量,在計算機中就是一段連續的記憶體(實際上是一些實體記憶體碎片,這裡說的是虛擬記憶體)。簡單一點,資料型別就是諸如int,char等。這個函式返回的結果單位是位元組。'\0'包括在內。strlen()用於計算給定字串的長度。百科中有說明,就是一個計數器,從字串的某個位置開始,遇到'\0'結束,所得到的個數,'\0'除外。舉幾個例子:------------------------------char *str1="abcde";

char str2[]="abcde";
char str3[8]={'a','b','c',''d};
char str4[] = "0123456789";int a[5]={1,2,3,4,5};++++++++++++++++++sizeof(str1)=4 (計算的是變數str1記憶體,而str1是個指標)sizeof(*str1)=1 (*str1是第一個變數,而型別是char,所以是1)sizeof(str2)=6 (a,b,c,d,e,\0)=6*sizeof(char)sizeof(str3)=8 (str3已經被定義為長度為8的陣列)sizeof(str4)=11 (0,1,2,3,4,5,6,7,8,9,\0)sizeof(a)=5*4=20 (依賴於int,一個int佔用4個位元組)--------------------------------------------char a1[12];char a2[3]={'\0'};char a3[14]="12345"++++++++++++++++++++++

strlen(a1)=不定。(怎麼去計數呢?)

strlen(a2)=0 (一個開始就結束了)strlen(a3)=5 (很難說,爭議比較大。)--------------------------------------------
2、陣列和指標的區別
這部分參考了《C專家程式設計》的內容。(很多人把陣列和指標等同)相當於編譯的時候,指標也有一個地址,在用的時候,去這個地址取指標,而指標代表的是地址,然後再去這個地址拿資料。特殊的一個例子:void func(char str[100]){........}

sizeof(str) = 4 (實際上就是指標的大小,因為在傳遞時候是傳遞地址,寫不寫後面的100是無關緊要的。)

所以也可以寫成:

void func(char* str){...} 或者 void func(char str[]){...}

3、巨集定義(編譯過程中預處理)
例如,定義一個常量
#define   PI   3.1415926定義一個函式#define  MIN(x,y)  ((x<y)?x:y)
4、資料的宣告
直接用這篇部落格:http://blog.jobbole.com/109117/
5、volatile關鍵字
主要作用是保證資料讀取的準確性。當對變數做修飾之後,每次讀取變數的值,都會從變數的地址處拿值(這一點跟我們通常理解的讀取變數值是一樣的)。因為有些情況下,需要對變數做頻繁的資料修改,同時也是告訴編譯器,這個變數的值是要隨時都會更改的,不要對程式碼做優化。
6、const和static的區別
7、 位操作

8、資料型別計算過程中的轉換
9、各個資料型別所佔用的位元組

32位編譯器:

指標:4 個位元組int:4個位元組unsigned int:4個位元組short:2個位元組unsigned short:2個位元組float:4個位元組double: 8個位元組long: 4個位元組long long: 8個位元組unsigned long: 4個位元組char:1個位元組
10、如何判斷某個值是否為0
對於bool型別:FALSE是0, TRUE是1,所以可以直接判斷(if(TRUE))
對於int型別:int n; if( n == 0)對於float型別:if (|x| < 0.000001)對於空型別:NULL = 0
11、記憶體對齊(以結構體和聯合體為例)
記憶體對齊主要是為了提升計算機的效率。例如32位機,如果採用了記憶體對齊,當程式執行的時候,會每次讀取一定長度的資料來處理,而不用管到底是哪一個。記憶體對齊的大致原理如下(個人的理解):(bool變數不考慮記憶體,就是不計算)

(1)結構體的第一個成員的首地址偏移量是0

(2)結構體中每個成員的地址偏移量是 這個成員的大小(所佔位元組數)的整數倍

(3)整個結構體的大小是結構體中成員長度的最大值的整數倍,哪裡不夠在哪裡補充。

這個是什麼意思呢,舉兩個例子。

struct A

{

      char   a;

      char   b;

      int c;

}

第一個成員的偏移量是0,

第二個成員的偏移量應該是這個成員長度的整數倍,由於其長度為1,所以其偏移量是1

第三個成員的偏移量應該是這個成員長度的整數倍,由於其長度為4,所以其偏移量是4

那麼第三個成員和第二個成員之間的空隙怎麼辦呢,系統去補空位

此結構體的總長度是最大成員的長度的整數倍,通過前面的分析,可以看到結果是8個位元組

用下圖來表示

如果結構體中還有結構體呢?
12、動態輸入字元(不知道字元個數)
自己寫了一個程式,可直接執行。上圖
13、函式的引數傳遞

14、字串常量和字串變數
字串常量:在一個雙引號內的字串序列或者轉義字元組成。例如“DDD\n”, "abc"等。字串常量儲存在靜態記憶體裡面,是不能被改變的,如果試圖通過指標訪問的形式來改變的話,就會出現錯誤。所以,在定義字串常量的時候加上const。例如下面的形式:
const char* str = "abc";

而str[1] = 'd' 或者 *(str+1)='d' 都是錯誤的。

字串變數:C語言中字串變數是通過陣列的形式來表示的。例如:char str[] = "i love you"; 或者 char str[20] = "i love you"等。那麼這個時候就可以通過陣列訪問的形式改變值了。例如:str[3] = 'm'
15、strcpy(),strlen()函式
這裡主要討論長度的問題。
strlen(str)計算字串長度時,是不包含結尾處的'\0'strcpy(str1, str2) 會copy str2中的'\0'到str1中strcmp(str1, str2) 字串從左向右逐個字元相比較(ASCII值),直到出現不同的字元,或者遇到'\0'。strcat(str1,str2) str2的字串會新增到str1的後面,同時會覆蓋str1後面的'\0', 最後會自動在str1的後面新增'\0'。
16、指標的一些知識點(包含如何用絕對地址去呼叫函式)

17、程式執行時的記憶體組織和分配(結合開發經驗和所學,現賣)
18、一個迴圈連結串列的例子(1到N數數,數到M就剔除)
19、