《C語言深度剖析》筆記
1.在c語言中,凡不加返回值類型限定的函數,就會被編譯器做爲返
回整形處理。
2.register 變量必須是一個單個的值,而且其長度應小於或等於整型
的長度。並且 register 變量可能不存放在內存中, 因此不能用取
址運算符 「&」來獲取 register變量的地址。
3. int main()
{
char a[1000];
int i;
for(i=0; i<1000; i++)
{
a[i] = -1-i;
}
printf("%d",strlen(a));
return 0; }
此題看上去真的很簡單,可是卻鮮有人答對。答案是 255。別驚訝,
咱們先分析分析。for循環內,當 i 的值爲 0時,a[0]的值爲-1。
關鍵就是-1在內存裏面如何存儲。咱們知道在計算機系統中,數值
一概用補碼來表示(存儲) 。主要緣由是使用補碼,能夠將符號
位和其它位統一處理;同時,減法也可按加法來處理。另外,兩個
用補碼錶示的數相加時,若是最高位(符號位)有進位,則進位被
捨棄。正數的補碼與其原碼一致;負數的補碼:符號位爲 1,其他
位爲該數絕對值的原碼按位取反,而後整個數加 1。按照負數補碼
的規則,能夠知道-1 的補碼爲0xff,-2 的補碼爲0xfe……當 i 的
值爲127時,a[127]的值爲-128,而-128是char類型數據能表示的
最小的負數。當 i 繼續增長,a[128]的值確定不能是-129。由於這
時候發生了溢出,-129 須要 9 位才能存儲下來,而 char類型數
據只有 8 位,因此最高位被丟棄。剩下的 8 位是原來 9 位補碼
的低 8 位的值,即 0x7f。當 i 繼續增長到255的時候,-256的
補碼的低 8位爲 0。而後當i增長到 256時,-257的補碼的低 8 位
全爲1,即低八位的補碼爲 0xff,如此又開始一輪新的循環……按
照上面的分析,a[0]到 a[254]裏面的值都不爲 0,而 a[255]的值爲
0。strlen函數是計算字符串長度的,並不包含字符串最後的‘\0’ 。
而判斷一個字符串是否結束的標誌就是看是否遇到‘\0’ 。若是
遇到‘\0’ ,則認爲本字符串結束。分析到這裏,strlen(a)的值爲
255應該徹底能理解了。這個問題的關鍵就是要明白 char類型默
認狀況下是有符號的,其表示的值的範圍爲[-128,127],超出這個
範圍的值會產生溢出。 另外還要清楚的就是負數的補碼怎麼表示。
弄明白了這兩點, 這個問題其實就很簡單了。
4.case 後面只能是整型或字符型的常量或常量表達式(想一想字符型
數據在內存裏是怎麼存的) 。
5. 不能對 void指針進行算法操做。
6. return 語句不可返回指向「棧內存」的「指針」 ,由於該內存在
函數體結束時被自動銷燬。
7. struct student
{}stu; sizeof(stu)的值是多少呢?是1。即空結構體的大小就定位 1
個byte。
8. 編譯器會將註釋剔除,但不是簡單的剔除,而是用空格代替原來
的註釋。
9. 注意:/*…*/這種形式的註釋不能嵌套,由於/*老是與離它最近的
*/匹配。
10.const修飾的只讀變量不能用來做爲定義數組的維數,
也不能放在 case關鍵字後面。
11. C語言裏(\)表示斷行。以反斜槓反斜槓以後不能有空格,反斜
槓的下一行以前也不能有空格。
12. 註釋先於預處理指令被處理。所以,試圖用宏開始或結束一段
註釋是不行的。
13.在32位系統下,無論什麼樣的指針類型,其大小都爲 4byte。
14. 往內存 0x12ff7c地址上存入一個整型數 0x100,能夠用下面的方
法:int *p = (int *)0x12ff7c;
*p = 0x100;
或者直接這麼寫代碼:*(int *)0x12ff7c = 0x100;
15. int a[5];a做爲右值時,表明數組首元素的首地址,而非數組的首
地址。
16.以指針的形式訪問數組;
如:#include<stdio.h>
void main()
{int a[5],i=0;
for(i=0;i<5;i++)
{a[i]=i;
printf("%d\n",*(a+i));
}
}
17. 如下標的形式訪問指針;
如:#include<stdio.h>
void main()
{int a[5],i=0,*p;
p=a;
for(i=0;i<5;i++)
{a[i]=i;
printf("%d, ",p[i]);
}
}
18. 對指針進行加1操做,獲得的是下一個元素的地址,一個類型爲
T的指針的移動,以 sizeof(T) 爲移動單位。
例:#include<stdio.h>
void main()
{int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
}
19. 函數自己是沒有類型的,只有函數的返回值纔有類型。
20. malloc函數的原型:(void *)malloc(int size)。malloc函數的返回值
是一個 void類型的指針,參數爲 int 類型數據。內存分配成功之
後,malloc函數返回這塊內存的首地址。你須要一個指針來接收這
個地址。malloc函數申請的是連續的一塊內存。注意malloc函數
申請內存有可能不成功,因此咱們在使用指向這塊內存的指針時,
必須用 if(NULL !=p)語句來驗證內存確實分配成功了。
注意:用 malloc函數申請 0字節時,內存不會返回 NULL指針,
而是返回一個正常的內存地址。可是你卻沒法使用這塊大小爲 0
的內存。對於這一點必定要當心,由於這時候 if(NULL !=p)語
句校驗將不起做用。 算法
點擊原文連接查看更多 數組