1.數(shù)值類型的選擇:溢出特征重要而負(fù)值不重要,操作二進(jìn)制位時(shí)避免符號(hào)擴(kuò)展的問(wèn)題,應(yīng)該使用unsigned(無(wú)符號(hào)值) char 8位 -127~127 最大值255 short int 和 int 均為 16位 -32767~32767 最大值65535
2.long long類型可以保證一個(gè)64位數(shù)
3.char *p1,p2; 這樣聲明p1是一個(gè)指向字符的指針,p2只是一個(gè)字符變量 聲明兩個(gè)指針 char *p1,*p2;
4.需要保證定義和聲明的一致性,在.c文件中進(jìn)行定義,在.h文件中進(jìn)行聲明,需要使用的時(shí)候,只要包含對(duì)應(yīng)的頭文件即可,定義變量的.c文件要包含該頭文件 應(yīng)該把全局變量的聲明放到頭文件,不要把外部函數(shù)的原型放到.c文件中 (ps:有關(guān)外部函數(shù):在C里面,函數(shù)有效空間默認(rèn)是extern,不用聲明這意味著,平時(shí)寫代碼的時(shí)候如果某個(gè)函數(shù)僅僅是本文件使用記得在前面加 static,這是個(gè)習(xí)慣問(wèn)題要有意識(shí)這樣做其他文件要引用這個(gè)函數(shù)只需要提供函數(shù)原型就行了 寫在.h文件里面,一般是一個(gè)模塊一個(gè).c和一個(gè).h文件 .h文件包含所有外部需要看見的東西,不需要給外部看到的東西 全部加static,但編譯的時(shí)候 要提供含有函數(shù)的.c文件)
p1和p2均被聲明為同樣的char指針,而p3被聲明為char指針,p4則被聲明為char變量
另外一個(gè)例子
這里p被聲明成const,但不是p指向的字符,因?yàn)閜的聲明不會(huì)深入到typedef的內(nèi)容來(lái)發(fā)現(xiàn)它涉及了指針 6.
這段代碼被聲明報(bào)錯(cuò),因?yàn)镃語(yǔ)言需要向前聲明,不能在定義typedef類型之前使用它 解決辦法
7.定義一對(duì)相互引用的結(jié)構(gòu)體
8.typedef int (*funcptr)(); 定義了一個(gè)類型funcptr,表示一個(gè)指針,這個(gè)指針指向返回值為int的函數(shù)
9.char *(*(*a[N]) () ) (); 分析方法,由外至內(nèi) *(*(*a[N]) () ) () 是一個(gè)char型 (*(*a[N]) () ) ()char型指針 *(*a[N]) () 返回char型指針的函數(shù) (*a[N]) ()返回char型指針的函數(shù)指針 *a[N]返回char型指針的函數(shù)指針的函數(shù) a返回char型指針的函數(shù)指針的函數(shù)的指針數(shù)組
另外的例子char *(*pfpc)(); *(*pfpc)() 是一個(gè)char (*pfpc)()是一個(gè)指向char的指針 *Pfpc返回指向char指針的函數(shù) pfpc指向返回char指針的函數(shù)的指針
10.有關(guān)數(shù)組: 數(shù)組和指針具有等價(jià)性,可以用指向malloc的指針?lè)峙涞膬?nèi)存的指針來(lái)模擬數(shù)組,但是sizeof不能給出數(shù)組大小
關(guān)于動(dòng)態(tài)分配多維數(shù)組:
sizeof不能得到malloc內(nèi)存塊的大小,他只能得到指針的大小 動(dòng)態(tài)分配數(shù)組大小后,繼續(xù)改變他的大小可以使用realloc函數(shù),如果重新分配成功,函數(shù)返回新的地址空間的指針
11.在一個(gè)文件中定義了一個(gè)數(shù)組,在另外一個(gè)文件中要獲得這個(gè)數(shù)組的大小,不能使用sizeof,因?yàn)閟izeof在編譯時(shí)起作用,不能獲得定義在另一個(gè)文件中的數(shù)組大小。 解決方法一:在頭文件中定義一個(gè)常量 解決方法二:在數(shù)組的最后一位設(shè)置一個(gè)哨兵值 解決方法三:設(shè)置一個(gè)變量在文件一中儲(chǔ)存變量大小,然后在文件二中調(diào)用這個(gè)變量來(lái)獲得數(shù)組大小
12.void main不是正確的定義,main的返回值必須是int 只有以下兩種定義方式是正確的:用malloc和realloc動(dòng)態(tài)分配的內(nèi)存也可能包含垃圾內(nèi)容,需要使用者進(jìn)行初始化,但是calloc動(dòng)態(tài)分配的內(nèi)存默認(rèn)全部為0
14.char a[] = "Hello world!"; char *p = "Hello world!"; 當(dāng)對(duì)p[i]賦值的時(shí)候會(huì)發(fā)生錯(cuò)誤,因?yàn)槿绻皇窃跀?shù)組中指明字符的初始值,那么他會(huì)轉(zhuǎn)化成一個(gè)無(wú)名的靜態(tài)數(shù)組,導(dǎo)致不能被修改
char *p = "Hello world!"這個(gè)是一個(gè)字符串常量,可以像一個(gè)字符數(shù)組一樣使用它,但是你不能更改這個(gè)字符串的值比如 a[2]='e'這樣不行,
15.char a[3] = "abc"; 這種寫法是一種極限寫法,雖然合法,但是不能使用strcpy和printf %s 因?yàn)樗麤]有結(jié)束符'/0'
16.struct x1{...}; typedef struct {..}x2; 區(qū)別,第一個(gè)聲明了結(jié)構(gòu)標(biāo)簽聲明實(shí)例的時(shí)候需要寫成 struct x1 a;,第二個(gè)聲明了一個(gè)類型定義 聲明實(shí)例的時(shí)候只需要寫成 x2 b; C和C++不同點(diǎn)是不能用結(jié)構(gòu)標(biāo)簽自動(dòng)生成類型定義名,在C++中第一個(gè)聲明可以使用x1 a; 但是在C中就必須加上struct,或者就直接用第二種方法typedef,那么聲明成一個(gè)類型定義,就可以直接使用x1 a;
17.任何一個(gè)malloc調(diào)用都要對(duì)應(yīng)一個(gè)free釋放內(nèi)存
18.不能用== 和 !=來(lái)比較結(jié)構(gòu)
19.向接受結(jié)構(gòu)的函數(shù)中傳入常量值 plotpoint((struct point){1,2}); 傳入了一個(gè)結(jié)構(gòu)常量
20.2字節(jié)的short int變量必須存儲(chǔ)在偶地址上,4字節(jié)的long int變量必須存儲(chǔ)在4的整數(shù)倍地址上,要求所有數(shù)據(jù)必須對(duì)齊 在struct { char a; int b; } 結(jié)構(gòu)標(biāo)簽中,a和b中間會(huì)留下一個(gè)空洞,以確定int對(duì)齊 所以數(shù)據(jù)成員應(yīng)該按照元素類型大小進(jìn)行排列,而不是按照數(shù)組大小進(jìn)行排列
21.sizeof有可能返回大于結(jié)構(gòu)大小的期望值,因?yàn)闉榱吮WC結(jié)構(gòu)數(shù)組的對(duì)齊有可能在尾部有填充的空洞
22.struct和union(聯(lián)合)的區(qū)別是union是一個(gè)成員的相互重疊的結(jié)構(gòu),某一時(shí)刻只能使用一個(gè)成員,聯(lián)合的大小是他最大成員的大小,union只有第一個(gè)成員可以被初始化
23.枚舉enum和使用一組define的區(qū)別:區(qū)別很小 標(biāo)準(zhǔn)中允許枚舉和其它整形類別自由混用而不會(huì)出錯(cuò)。 枚舉的一些優(yōu)點(diǎn): 自動(dòng)賦值(只要給第一個(gè)數(shù)賦值以后就依次加1); 調(diào)試器在檢驗(yàn)枚舉變量時(shí), 可以顯示符號(hào)值; 它們服從數(shù)據(jù)塊作用域規(guī)則。
24.結(jié)構(gòu)聲明中的位域 struct record{ char *name; int refcount : 4; unsigned dirty : 1; }; 后面的數(shù)字表示該域用位計(jì)量的準(zhǔn)確大小
25.有關(guān)i++的表達(dá)式 (1)引入了序列點(diǎn)的概念:兩個(gè)序列點(diǎn)之間一個(gè)對(duì)象最多只能被修改一次,而且只有在確定將要保存的值的時(shí)候才能訪問(wèn)前一個(gè)值 引入新序列點(diǎn)的操作符:&&,||,?:,逗號(hào)操作符處 a[i] = i++;這個(gè)式子會(huì)導(dǎo)致未定義行為,因?yàn)檫@里i沒有被確定保存,無(wú)法判斷a[i]中的i是新值還是舊值,它被修改了兩次 (2)后綴的++和--只有在輸出其舊值才進(jìn)行自增和自減運(yùn)算 所以 i = 5; printf("%d",i++*i++); 得到的結(jié)果是25,最后i的值是7
26.不用臨時(shí)變量就交換兩個(gè)數(shù)的值 利用異或操作符 int a = 2; int b = 4; a ^= b ^= a ^= b;
27.使用操作符的優(yōu)先級(jí)來(lái)控制計(jì)算順序是無(wú)效的 f() + g() * h(); 程序不會(huì)按照操作符的順序運(yùn)行g(shù)() h() f(); 同樣道理用到(i++) * (i++); 一個(gè)特殊的情況是使用&& ||,這兩個(gè)操作符會(huì)引出一個(gè)額外的序列點(diǎn),對(duì)后面的操作進(jìn)行短路 常用這個(gè)性質(zhì)來(lái)檢測(cè)操作是否安全 if(d!=0 && n/d) 短路掉了d等于0的情況 {...} if(p!=NULL || *p == '/0') 如果p是空指針,對(duì)p進(jìn)行賦值會(huì)導(dǎo)致程序崩潰 {...}
28. C++中應(yīng)該優(yōu)先使用++i; 因?yàn)樾矢?/p>
29.int a = 1000; int b = 1000; long int c = a * b; 這個(gè)表達(dá)式的問(wèn)題在a*b是按照int型運(yùn)算的,返回給c的右值可能是a*b溢出或者被截?cái)嗪筠D(zhuǎn)換成long型的值 正確的寫法是 int a = 1000; int b = 1000; long int c = (long int )a * (long int )b;
30.double degC, degF; degC = 5/9*(degF-32); 輸出的值是0,因?yàn)?/9被當(dāng)做int形運(yùn)算(二元操作符的兩個(gè)操作符都是整數(shù),則進(jìn)行整數(shù)運(yùn)算) 可行的方法是 degC = (double)5/9*(degF-32); 或 degC = 5.0/9*(degF-32); |
|
來(lái)自: 千年長(zhǎng)嘆 > 《c語(yǔ)言學(xué)習(xí)》