1.資料型別的本質
說到資料型別,許多學過c語言的程式設計師都不陌生,總的概括為四種型別,見下圖。
提乙個問題,資料型別和記憶體有關係嗎?
答案很明顯,有關係,這裡又要問了,有什麼關係呢?
用一句話概括:資料型別是固定記憶體大小的別名,這就是資料型別的本質。
站在c編譯器的角度去看這句話,很快就能明白。
在程式設計時,我們宣告了乙個int變數,就相當於告訴c編譯器要給該變數分配四個位元組的記憶體。宣告其他型別的變數也是一樣。
我們可以通過執行下面這段**來加深理解。
#includeint main(void)
執行結果:
array:334096816,array+1:334096820
&array:334096816,&array+1:334096856
這時你會發現,array和&array的輸出結果一樣,但是array+1和&array+1的輸出結果卻不一樣。這是為什麼?難道編譯器出錯了?在這裡我可以明確的告訴你,編譯器沒有出錯。
下面我們來分析一下:array是陣列首元素的位址,&array代表的是整個陣列的位址,這兩者是有區別的,它們所代表的資料型別不一樣,因此array+1就是在原來的位址往下挪了乙個位元組的長度(在原位址上+4),指向了下乙個陣列元素的位址,也可以理解為array[1]的位址,而&array+1則是在原來的位址往下挪了10個位元組的長度(在原位址上+40),如果把陣列當做一條街,那麼&array+1就指向了下一條街。
2.資料型別的大小
接下來我們順帶來求一下資料型別的大小,一般用sizeof關鍵字。就以上面兩個變數來做例子:
printf("var:%d\n",sizeof(var)); //4
printf("array:%d\n",sizeof(array)); //40
3.資料型別別名既然資料型別可以理解為固定記憶體塊的別名,那麼可以給資料型別起別名嗎?
這是可以的,用typedef關鍵字就可以了,這種做法很常見。例如:
#includetypedef unsigned int u8; //給unsigned int起別名u8
int main(void)
4.資料型別的封裝(void型別)
1.void的字面意思是「無型別」,void *則為「無型別指標」,可以指向任何型別的資料。
2.用法1 資料型別的封裝,如int inithardevent(void **handle);
典型的如記憶體操作函式memcpy和memset。
3.用法2 void修飾函式返回值和引數,僅表示無。
如果函式沒有返回值,那麼應該將其宣告為void型,如void func(int *array);
如果函式沒有引數,應宣告其引數為void,如int function(void);
4.void指標的意義
c語言規定只有相同型別的指標才可以相互賦值。
void *指標作為左值用於接收任意型別的指標。
void *指標作為右值賦值給其他指標時需要強制型別轉換。
int *p1 = null;
char *p2 = (char *)malloc(sizeof(char)*20);
5.不存在void型別的變數。
深入理解C語言型別轉換
c語言型別轉換分為兩種 也許你曾經遇到過乙個負數經過型別轉換後可能變成乙個很大的整數之類的現象,卻不知道實質上是因為什麼,只是淺顯地了解到型別轉換會向著更大精度的方向轉化。尤其是對於計算機基礎知識不紮實或者很多半路出家 比如我 的人來說不是很了解背後的原因。希望下面的解釋能夠解決這個疑惑。本文以c語...
深入理解C語言 深入理解指標
關於指標,其是c語言的重點,c語言學的好壞,其實就是指標學的好壞。其實指標並不複雜,學習指標,要正確的理解指標。指標也是一種變數,占有記憶體空間,用來儲存記憶體位址 指標就是告訴編譯器,開闢4個位元組的儲存空間 32位系統 無論是幾級指標都是一樣的 p操作記憶體 在指標宣告時,號表示所宣告的變數為指...
深入理解C語言 深入理解指標
關於指標,其是c語言的重點,c語言學的好壞,其實就是指標學的好壞。其實指標並不複雜,學習指標,要正確的理解指標。指標也是一種變數,占有記憶體空間,用來儲存記憶體位址 指標就是告訴編譯器,開闢4個位元組的儲存空間 32位系統 無論是幾級指標都是一樣的 p操作記憶體 在指標宣告時,號表示所宣告的變數為指...