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 的方式有以下幾種 序號方式...