陳皓《深入理解C語言》學習筆記

2021-08-26 10:31:48 字數 1909 閱讀 5307

1. 有關static變數的初始化

#include void f(void)

int main(void)

這個程式會輸出什麼?

說到全域性變數,你知道 靜態全域性變數和一般全域性變數的差別嗎?是的,對於static 的全域性變數,其對鏈結器不可以見,也就是說,這個變數只能在當前檔案中使用。

2.編譯優化開關

#include void foo(void)

void bar(void)

int main(void)

你知道這段**會輸出什麼嗎?a) 乙個隨機值,b) 42。a 和 b都對(在「在函式外訪問區域性變數的乙個比喻」文中的最後給過這個例子),不過,你知道為什麼嗎?

3.編譯順序影響移植性

#include int b(void) 

int c(void)

int main(void)

4. sequence points

示例一

int a=41; a++; printf("%d\n", a);
示例二

int a=41; a++ & printf("%d\n", a);
示例三

int a=41; a++ && printf("%d\n", a);
示例四

int a=41; if (a++ < 42) printf("%d\n", a);
示例五

int a=41; a = a++; printf("%d\n", a);
只有示例一,示例三,示例四輸出42,而示例二和五的行為則是未定義的。關於這種未定義的東西是因為sequence points的影響(sequence points是一種規則,也就是程式執行的序列點,在兩點之間的表示式只能對變數有一次修改),因為這會讓編譯器不知道在乙個表示式順列上如何訪問變數的值。比如a = a++,a + a++,不過,在c中,這樣的情況很少。

5. 位元組對齊

假設int為4位元組,char為1位元組。

#include struct x ;

struct y ;

int main(void)

這個**會輸出什麼?

a) 9,10

b)12, 12

c)12, 16

答案是c,我想,你一定知道位元組對齊,是向4的倍數對齊。

另外,再提一下,上述程式的printf中的%d並不好,因為,在64位下,sizeof的size_t是unsigned long,而32位下是 unsigned int,所以,c99引入了乙個專門給size_t用的%zu。這點需要注意。在64位平台下,c/c++ 的編譯需要注意很多事。你可以參看《64位平台c/c++開發注意事項》

6. 編譯器warning

#include int main(void)

考慮下面兩種編譯**的方式 :

前一種是不會編譯出a未初化的警告資訊的,而只有在-o的情況下,才會有未初始化的警告資訊。這點就是為什麼我們在makefile裡的cflags上總是需要-wall和 -o。

7.指標

#include int main(void)

深入理解C語言 深入理解指標

關於指標,其是c語言的重點,c語言學的好壞,其實就是指標學的好壞。其實指標並不複雜,學習指標,要正確的理解指標。指標也是一種變數,占有記憶體空間,用來儲存記憶體位址 指標就是告訴編譯器,開闢4個位元組的儲存空間 32位系統 無論是幾級指標都是一樣的 p操作記憶體 在指標宣告時,號表示所宣告的變數為指...

深入理解C語言 深入理解指標

關於指標,其是c語言的重點,c語言學的好壞,其實就是指標學的好壞。其實指標並不複雜,學習指標,要正確的理解指標。指標也是一種變數,占有記憶體空間,用來儲存記憶體位址 指標就是告訴編譯器,開闢4個位元組的儲存空間 32位系統 無論是幾級指標都是一樣的 p操作記憶體 在指標宣告時,號表示所宣告的變數為指...

Go語言學習8 深入理解切片slice

slice是個結構體,原始碼如下 runtime slice.go type slice struct slice 共有三個屬性 注意,底層陣列是可以被多個 slice 同時指向的,因此對乙個 slice 的元素進行操作是有可能影響到其他 slice 的。建立 slice 的方式有以下幾種 序號方式...