关于linux内核中结构体初始化的新写法

查看linux源代码,经常会被其中一些程序的写法所迷惑,此种初始化写法并不是什么特殊的代码风格,而是所谓的C语言标记化结构初始化语法(designated initializer),而且还是一个ISO标准,C99

注意:适用于GCC编译器,GCC能完美支持C99,VC2005支持C89,还不支持C99,只有能完美支持C99的编译器才能编译通过。

GCC有扩展标记化结构初始化语法,写法是下面这样的,常用于2.4内核:

struct operators my_op = {

read2 : read2,

  read1 : read1,

  read3 : read3,

};

//常见于2.4内核
static struct file_operations dev_fops = {
	owner:	THIS_MODULE,
	open:	s3c2410_adc_open,
	read:	s3c2410_adc_read,	
	release:	s3c2410_adc_release,
};
//常见于2.6内核
static struct miscdevice misc = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = DEVICE_NAME,
	.fops = &dev_fops,
};

采用 .name = value这种形式,虽然没什么,但带来许多好处。

eg1:

struct student { //结构体名
    char name[20];
    char s;
    int age;
    int score;
};
struct student stu1 ={ //传统初始化
    "x",'m',1,2
};
struct student stu1 ={ //上述标记式初始化
    .score=2,
    .age=1,
    .name="x",
};

eg2:

#include  
#include  
struct operators 
{ 
     void (*read1)(char *); 
     void (*read2)(char *); 
     void (*read3)(char *); 
     int n; 
}; 
 
void read1(char *data) 
{ 
     printf("read1: %s/n",data); 
} 
void read2(char *data) 
{ 
     printf("read2: %s/n",data); 
} 
void read3(char *data) 
{ 
     printf("read3: %s/n",data); 
} 
int main() 
{    //传统的初始化方法 
     //struct operators my_op = {read1, read2, read3, 100};    //所谓的标记化结构初始化语法 
     struct operators my_op = {.read2 = read2, 
                               .read1 = read1, 
                               .read3 = read3, 
                               .n = 100}; 
     my_op.read1("wangyang"); 
     my_op.read2("wangyang"); 
     my_op.read3("wangyang"); 
     return 0; 
}

主要优点

1.标记传参不用理会参数传递的顺序,正如我上面的例子表示的那样,我是先初始化了read2,然后再初始化了read1,程序员不用记忆参数的顺序;

 2.我们可以选择性传参,在传统C语言顺序传参中,如果你只想对第三个变量进行初始化,那么你不得不给第一个, 第二个参数进行初始化,而有时候一个变量并没有很合适的默认值,而使用标记初始化法,你可以相当自由地对你有把握的参数进行初始化;

 3.扩展性更好,如果你要在该结构体中增加一个字段,传统方式下,为了考虑代码修改量,你最好将新添加的字段放在这个结构体的最后面,否则你将要面对大量且无趣的修改!



你可能感兴趣的:(linux基础知识)