Linux內核C語言深度解析

本文來源於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;  \
})

將數據類型作爲一個參數傳進來。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章