基于c語言知識點的補遺介紹
使用C很長時間,但是很難說對c的各個點都十分的透徹。雖然c不像c++那樣復雜,但是還有很多嘰里旮旯兒:并不是他們有多難,而是在于他們平時用的不多,或者和人的第一直覺相悖,再或者初學時經(jīng)驗有限理解不深根本沒有記住。
下面的這些東西可能來自《c專家編程》或者網(wǎng)絡。最近發(fā)現(xiàn)基礎的經(jīng)典的書籍常讀常新,原因可能有兩個:
1、隨著自己經(jīng)驗的增長,你的認識可能會不一樣,思維的方式也會有所變化,而得到的東西自然會是新的東西。
2、早些時候經(jīng)驗有限,有些點可能根本就沒有完全理解?,F(xiàn)在你可以理解的更深刻。
這方面的書籍再比如《代碼大全》,前幾天翻了一下,又有不同的認識。
進入正題:
1、有符號和無符號的比較:
printf("%d\n", sizeof('A')):打印的值是4(或者是int的長度)而不是1。因為c有類型提升,它會首先把'A'提升為int類型,然后在傳給sizeof。表達式中的參數(shù)會提升為int或者double,然后在進行運算,之后再進行裁剪,獲得指定類型的值。
if (-1 <= sizeof(int)):sizeof的返回值是unsigned int,-1會被類型轉換為unsignedint,然后在進行比較。。
這里涉及到的是類型提升,隱式類型轉換。它會在表達式中發(fā)生,也會在函數(shù)入?yún)⒅邪l(fā)生。
2、枚舉在內存中的大?。赫妓膫€字節(jié)。
3、局部變量也是字節(jié)對齊的:
E_T g;
E_T f;
E_T e = false;
char c1;
char c2;
int i1;
char c3;
int i2;
printf("%p, %p, %p, %p, %p, %p, %p, %p\n", &g, &f, &e, &c1, &c2, &i1, &c3, &i2);
--表示是補齊的位。
4、宏定義中的#和##:#的功能是將其后面的宏參數(shù)進行字符串化操作(Stringfication),簡單說就是在對它所引用的宏變量通過替換后在其左右各加上一個雙引號。
而##被稱為連接符(concatenator),用來將兩個Token連接為一個Token。
5、浮點數(shù)不可以用等于比較。
6、void foobar2() 表示函數(shù)入?yún)€數(shù)有多個,不確定。如果表示沒有產生,應該是:void foobar2(void)
7、全局變量會被初始化為0,但是,棧中的局部變量不會被初始化。
8、inline函數(shù)和宏:內聯(lián)函數(shù)是真正的函數(shù),但是它是在編譯期的優(yōu)化。
9、 int a[5]; printf("%x\n", a); printf("%x\n", a+1); printf("%x\n", &a); printf("%x\n", &a+1);
最后一個,&a+1,&a表示數(shù)組,所以,應該是增加數(shù)組大小:4*5個字節(jié)。
10、10U表示一個無符號類型的數(shù)字10.
11、移位運算的優(yōu)先級比較低,低于四則運算。
12、左移n位,相當于乘與2的n次方。右移相當于處于2的n次方。
13、指針和數(shù)組:
1)、void fun(char buf[100])
{
printf("%d, \n", sizeof(buf));
}
打印的值是4,而不是100。
2)、在一個文件中char p[10] = "";
在另外一個文件中聲明:extern char *p;
然后,在聲明的文件中sizeof(p),答案是4。也就是,sizeof計算的是聲明的類型。
3)對于編譯器而言,一個數(shù)組就是一個地址,一個指針就是一個地址的地址。
4)所有作為函數(shù)參數(shù)的數(shù)組名編譯器都會轉換為指針,在其他所有的情況下,數(shù)組的聲明就是數(shù)組,指針的什么就是指針。
數(shù)組和指針相同情況的規(guī)則:
1、表達式中的數(shù)組名(與聲明不同)被編譯器當作一個指向該數(shù)組的第一個元素的指針。
2、下標總是與指針的偏移量相同。
3、在函數(shù)的聲明中,數(shù)組名被編譯器當作指向該數(shù)組第一個元素的指針。這個操作時編譯器完成的。原因是出于效率的考慮。因為這樣就是引用傳遞而非值傳遞。值 傳遞需要拷貝。這也可以看的出sizeof是在匯編中操作的。
arry[-1]的行為是未定義的。
總結:
1)a[i]這樣的形式對a進行訪問,總是被編譯器改寫為像*(a+i)的形式。
2)指針始終是指針,你不可以把它改寫成數(shù)組,但是可以通過數(shù)組的形式訪問。
3)數(shù)組作為函數(shù)的參數(shù),會被編譯器改寫成指針。
4)指針和數(shù)組的什么必須配對。
14、聲明與定義:聲明可以由多個,定義只有一個。定義是特殊的聲明,它為對象分配了內存。而聲明時普通的聲明,描述其他地方創(chuàng)建的對象。
聲明的優(yōu)先級規(guī)則:
a:從他的名字開始按照優(yōu)先次序依次讀取:
b:優(yōu)先級的高低:
1、聲明中被括號括起來的那部分。
2、后綴操作符:
括號()表示是一個函數(shù);
方括號[]表示是一個數(shù)組;
3、前綴操作符:*表示指向什么的指針;
4、const緊跟變量則修飾變量不可修改,緊跟類型則指向的東西不可修改。
15、多維數(shù)組:
a[2][3]:a是一個數(shù)組,有兩個元素。每個元素又是一個數(shù)組,有三個元素。
內存布局:a[0][0],a[0][1],a[0][2],a[1][0]...地址一直變大。
多維數(shù)組,數(shù)組的數(shù)組作為函數(shù)的形參,會被轉化為數(shù)組指針,數(shù)組的指針,也是行指針。本質上也是指針。
16、結構體默認的字節(jié)對齊一般滿足三個準則:
1) 結構體變量的首地址能夠被其最寬基本類型成員的大小所整除;
2) 結構體每個成員相對于結構體首地址的偏移量(offset)都是成員自身大小的整數(shù)倍,如有需要編譯器會在成員之間加上填充字節(jié)(internal adding);
3) 結構體的總大小為結構體最寬基本類型成員大小的整數(shù)倍,如有需要編譯器會在最末一個成員之后加上填充字節(jié)(trailing padding)。
相關文章
C++實現(xiàn)折半插入排序(BinaryInsertSort)
這篇文章主要為大家詳細介紹了C++實現(xiàn)折半插入排序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-04-04C++?opencv利用grabCut算法實現(xiàn)摳圖示例
這篇文章主要為大家介紹了C++?opencv利用grabCut算法實現(xiàn)摳圖的代碼示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-05-05c++ 頭文件<cwchar>中常見函數(shù)的實現(xiàn)代碼
本文記錄了c++ 頭文件<cwchar>中常見函數(shù)的實現(xiàn),本文結合實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2023-12-12