C语言的指定初始化



指定初始化

来看看内核用到的指定初始化代码

在看linux内核源码时,在源码中遇到结构体和数组的一种特殊的初始化方法,叫做指定初始化(Designated Initializers),指的是可以对数组中的某些元素或结构体变量中的某些成员以任意的顺序进行选择性的初始化。
如:在linux-3.0.85/arch/arm/mach-s5pv210/mach-smdkv210.c中有这样一段代码,
我刚开始看几乎没看懂,查了查资料,后分一看开看,原来如此。

/*
    struct s3c2410_uartcfg是结构体。
    这儿声明一个结构体数组smdkv210_uartcfgs,并初始化。

    __initdata是内核定义的宏,在 include/linux/init.h
    #define __initdata __attribute__ ((__section__ (".init.data")))
    这个标志符和变量声明放在一起,表示gcc编译器在编译时,需要把这个变量放在.data.init Section中,
    而这个Section 在内核完成初始化之后,会释放掉。

*/
    static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = {
    [0] = {
        .hwport     = 0,
        .flags      = 0,
        .ucon       = SMDKV210_UCON_DEFAULT,
        .ulcon      = SMDKV210_ULCON_DEFAULT,
        .ufcon      = SMDKV210_UFCON_DEFAULT,
    },
    [1] = {
        .hwport     = 1,
        .flags      = 0,
        .ucon       = SMDKV210_UCON_DEFAULT,
        .ulcon      = SMDKV210_ULCON_DEFAULT,
        .ufcon      = SMDKV210_UFCON_DEFAULT,
    },
    [2] = {
        .hwport     = 2,
        .flags      = 0,
        .ucon       = SMDKV210_UCON_DEFAULT,
        .ulcon      = SMDKV210_ULCON_DEFAULT,
        .ufcon      = SMDKV210_UFCON_DEFAULT,
    },
    [3] = {
        .hwport     = 3,
        .flags      = 0,
        .ucon       = SMDKV210_UCON_DEFAULT,
        .ulcon      = SMDKV210_ULCON_DEFAULT,
        .ufcon      = SMDKV210_UFCON_DEFAULT,
    },
};
  
  

数组指定初始化

先来看看数组的指定初始化吧。

#include<stdio.h>
void display(int,int *);

int main()
{
    /*
        传统的初始化方式
        int array[6] = {3,2,0,0,6,0};
        或
        int array[] = {3,2,0,0,6,0};
        或
        int array[6];然后循环赋值
    */

    //数组的指定初始化
    int array1[6] = {[0]=3,[1]=2,[4]=6};
    display(6,array1);//输出: 3  2  0  0  6  0

    int array2[6] = {[0]=3,2,[4]=6};
    display(6,array2);//输出: 3  2  0  0  6  0

    int array3[6] = {[4]=6,[0]=3,2};
    display(6,array3);//输出: 3  2  0  0  6  0

    int array4[] = {[4]=6,0,[0]=3,2};
    display(6,array4);//输出: 3  2  0  0  6  0

    //可以看到以上这几种方式效果一样

    //指定初始化 还可以这样
    int arr5[] = {[0 ... 2]=1,[5]=6};
    display(6,arr5);//输出: 1  1  1  0  0  6
}
void display(int n,int *p)
{
    while( n-- ) printf("%d ",*p++);

    printf("\n");
}
  
  

结构体指定初始化

与传统初始化比,指定初始化,在小结构体、小数组中可能体现不出优势,但如你所见,在linux内核代码中往往结构体比较大,而且绝大多数时候又没有必要一一赋值,那么这个时候,结构体的指定初始化优势就体现出来了。

#include<stdio.h>
typedef unsigned int uint;

struct student
{
    uint id;
    char *sex;
    char *name;
};
void displayStudent(struct student *);
void disStuArray(int,struct student *);

int main()
{
    //结构体的指定初始化
    struct student stu1={
        21,"b","stu1"
    };
    struct student stu2={
        .id = 11,
        .sex = "g"
    };
    struct student stu3={
        .name = "stu3",
        .sex = "g",
        .id = 22
    };
    displayStudent(&stu1);
    displayStudent(&stu2);
    displayStudent(&stu3);
}

void displayStudent(struct student *s)
{
    printf("学号:%-5d 性别:%-10s  姓名:%-10s  \r\n",s->id,s->sex,s->name);
}

把这两种合起来用

在看完这段代码后,再回头看看mach-smdkv210.c中的代码是不是挺简单呢。

#include<stdio.h>
typedef unsigned int uint;

struct student
{
    uint id;
    char *sex;
    char *name;
};
void displayStudent(struct student *);
void disStuArray(int,struct student *);

int main()
{
    //优势在这儿,如果这个结构体有几十个成员,而我有只需赋值中间某几个,
    //当然了可以先给结构分配内存,在用stu.name = "" 或 p->name=""
    //的方式进行赋值,不过这好像麻烦了一点点。

    //所以 那什么 叫指定初始化来着。这就叫指定初始化,
    struct student stus[]={
            [0] = {21,"g","stu4"},
            [3] = {
                .id = 22,
                .name = "stu5",
                .sex = "b"
            }
    };
    disStuArray(4,stus);
}

void displayStudent(struct student *s)
{
    printf("学号:%-5d 性别:%-10s  姓名:%-10s  \r\n",s->id,s->sex,s->name);
}

void disStuArray(int n,struct student *p)
{
    while(n--)
        displayStudent(p++);
}

转自:http://blog.csdn.net/qq_29204995/article/details/46603675
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值