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/)

Linux内核C语言深度解析_第1张图片

语句表达式的值邓玉最后一个表达式的值,所以再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;  \
})

将数据类型作为一个参数传进来。

 

你可能感兴趣的:(linux编程学习)