本文來源於GitChat體驗課
第01課: C標準發展
C標準的四個階段:
K&R C
ANSI C
C99
C11
K&R C 稱爲傳統C語言,在C語言標準統一前,這個是最權威。
ANSI C:是ANSI(美國國家標準協會), 再K&R C基礎上,統一了各大編譯器廠商的不同標準,並做了一些擴展,也稱作 C89/C90, 至此C標準統一起來。
C99: ANSI 1999年在ANSI C上做了擴展
C11, 2011年發佈的最新的標準。
不同的編譯器在支持C標準的同時,也做了一些其他的擴展。
比如51單片機上, Keil for C51上支持一些關鍵字,如data,code,bit等
GCC編譯器,擴展支持零長度數組,語句表達式等。
個人觀點,如果要開發跨平臺的C語言程序,儘量使用C標準內的語法,而不要使用不常見的擴展語法。
第02課: 內核驅動中的指定初始化
指定初始化數組:
標準C中常見的初始化方法:
int a[10] ={1,2,3,4}; 按照順序初始化,未覆蓋到的元素都擴展賦值爲0
GNU C支持C99標準。(GNU&GCC, GCC全稱是 GNU C Compiler)
C99標準,支持指定初始化,比如100個數組b[100],只初始化b[10] 和b[30]
int b[100] = { [10] = 1, [30] = 2 };
數組範圍初始化,如[10] 到 [30] 賦值爲1, [50]到[60]賦值爲2
int b[100] = { [10 ... 30] = 1, [50 ... 60] = 2 }; ... 前後必須由空格
這種範圍... 在sitch-case 語句中也可以用
switch(i)
{
case 1:
printf("1\n");
break;
case 2 ... 8:
printf("%d\n",i)
break;
defalut:
break;
}
指定初始化結構體:
struct student{
char name[20];
int age;
};
struct student stu1 = {"Ben", 18};
struct student stu2 = // 指定初始化
{
.name = "will",
.age = 28 // 後面沒有逗號
};
指定初始化的好處,當結構體成員順序發生變動,如
那麼第一種stu1 初始化地方就得改, 而第二種方法完全不用改.
linux內核驅動中註冊,經常遇到這種用法。
struct student{
int age;
char name[20];
char number[20];
};
第03課:語句表達式 -- 構造宏定義的好幫手
語句表達式:
GNU C對C標準進行了擴展,允許一個表達式裏內嵌語句,允許表達式內部使用局部變量、for循環和goto跳轉語句。這樣的表達式,我們稱之爲語句表達式。
語句表達式最外面用小括號()括起來,裏面用一對大括號{}包起來的是代碼塊,代碼塊裏允許內嵌各種語句。
語句表達式內使用for循環:
int main()
{
int sum = 0;
sum =
({
int s = 0;
for( int i = 0; i < 10; i++ )
{
s = s + i;
}
s;
});
printf("sum = %d\n",sum);
return 0;
}
編譯方法:gcc -o test test.c -std=gnu99 -Wall
如果不加-std=gnu99 則會報錯。(參考;https://blog.csdn.net/u012075739/article/details/26516007/)
語句表達式的值鄧玉最後一個表達式的值,所以再for循環的後面我們要加一個 s; 如果不加這一句則sum=0。 或者你將這一行改成100; sum的值就是100,這是因爲語句表達式的值總鄧玉最後一個表達式的值。
語句表達式內使用goto語句:
int main()
{
int sum = 0;
sum =
({
int s = 0;
for( int i = 0; i < 10; i++ )
{
s = s + i;
}
goto here;
s;
});
printf("sum = %d\n",sum);
here:
printf("here\n");
printf("sum = %d\n",sum);
return 0;
}
此時,sum=0
寫宏定義,求兩個數的最大值:MAX(a,b)
一般寫法:
#define MAX(a,b) ((a)>(b)?(a):(b))
如果對於自加運算和自減運算就會有問題。
比如 MAX(a++, b++)
進階寫法1:
#define MAX(a,b) ({ \
int _x = a; \
int _y = b; \
_x > _y ? _x : _y; \
})
但是該方法僅能用於int類型,對於其他類型的比較又要重新寫這個宏定義。
進階寫法2:
#define MAX(type,a,b) ({ \
type _x = a; \
type _y = b; \
_x > _y ? _x : _y; \
})
將數據類型作爲一個參數傳進來。