结构体struct初始化多出的点号“.”

在阅读GNU/Linux内核代码时,我们会遇到一种特殊的结构初始化方式,该方式是书中并没有介绍过的。 这种方式称为指定初始化(designated initializer)。

下面我们看一个例子:Linux-2.6.x/drivers/usb/storage/usb.c中有这样一个结构体初始化项目:

static struct usb_driver usb_storage_driver = {
 .owner = THIS_MODULE,
 .name = "usb-storage",
 .probe = storage_probe,
 .disconnect = storage_disconnect,
 .id_table = storage_usb_ids,

};
乍一看,这与我们之前学过的结构体初始化差距甚远。其实这就是前面所说的指定初始化在Linux设备驱动程序中的一个应用,它源自ISO C99标准。

以下我摘录了C Primer Plus第五版中相关章节的内容,从而就可以很好的理解2.6版内核采用这种方式的优势就在于由此初始化不必严格按照定义时的顺序。

已知一个结构,定义如下
struct book {
  char title[MAXTITL];
  char author[MAXAUTL];
  float value;

};

1)C99支持结构的指定初始化项目,其语法与数组的指定初始化项目近似。只是结构的指定初始化项目使用点运算符和成员名(而不是方括号和索引值)来标识具体的元素。

例如,只初始化book结构的成员value,可以这样做:

struct book surprise = { .value = 10.99 };

2)可以按照任意的顺序使用指定初始化项目:

struct book gift = { .value = 25.99, .author = "James Broadfool", .title = "Rue for the Toad"};

正像数组一样,跟在一个指定初始化项目之后的常规初始化项目为跟在指定成员后的成员提供了初始值。

3)对特定成员的最后一次赋值是它实际获得的值。

例如,考虑下列声明:

struct book gift = { .value = 18.90, .author = "Philionna pestle", 0.25};

这将把值0.25赋给成员value,因为它在结构声明中紧跟在author成员之后。新的值0.25代替了早先的赋值18.90。 有关designated initializer的进一步信息可以参考c99标准的6.7.8节Ininialization。

4)特定的初始化
  标准C89需要初始化语句的元素以固定的顺序出现,和被初始化的数组或结构体中的元素顺序一样。在ISO C99中,你可以按任何顺序给出这些元素,指明它们对应的数组的下标或结构体的成员名,并且GNU C也把这作为C89模式下的一个扩展(这个扩展没有在GNU C++中实现)。为了指定一个数组下标,在元素值的前面写上“[index] = xx”。

比如: int a[6] = { [4] = 29, [2] = 15 };相当于:int a[6] = { 0, 0, 15, 0, 29, 0 };

  下标值必须是常量表达式,即使被初始化的数组是自动的。一个可替代这的语法是在元素值前面写上“.[index]”,没有“=”,但从GCC 2.5开始就不再被使用,但GCC仍然接受。 为了把一系列的元素初始化为相同的值,写为“[first ... last] = value”。这是一个GNU扩展。

比如: int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };
  如果其中的值有副作用,这个副作用将只发生一次,而不是范围内的每次初始化一次。

注意,数组的长度是指定的最大值加一。

以上转载自http://zhouyang340.blog.163.com/blog/static/3024095920123495051607/

数组初始化多出的逗号“,”

在u-boot 2008.10  drivers/net定义的一个结构体如下的初始化

static struct {const char *name;u8 version;      /* depend on RTL8169 docs */u32 RxConfigMask;   /* should clear the bits supported by this chip */
} rtl_chip_info[] = {{"RTL-8169", 0x00, 0xff7e1880,},{"RTL-8169", 0x04, 0xff7e1880,},{"RTL-8169", 0x00, 0xff7e1880,},{"RTL-8169s/8110s",   0x02, 0xff7e1880,},{"RTL-8169s/8110s",    0x04, 0xff7e1880,},{"RTL-8169sb/8110sb",  0x10, 0xff7e1880,},{"RTL-8169sc/8110sc",  0x18, 0xff7e1880,},{"RTL-8168b/8111sb",   0x30, 0xff7e1880,},{"RTL-8168b/8111sb",   0x38, 0xff7e1880,},{"RTL-8101e",      0x34, 0xff7e1880,},{"RTL-8100e",      0x32, 0xff7e1880,},
};

在定义的结构体后面直接进行初始化,关键最后面还多出一个”,“,按理说只有3个成员,why??

先不要着急,请看下面的定义也是在u-boot 2008 10 driver/usb/usbdcore.c

char *usbd_device_states[] = {"STATE_INIT","STATE_CREATED","STATE_ATTACHED","STATE_POWERED","STATE_DEFAULT","STATE_ADDRESSED","STATE_CONFIGURED","STATE_UNKNOWN",
};

看到数组最后也多了个“,” 论坛中也探讨了这个问题

http://bbs.csdn.net/topics/330052999

谈结构体struct 初始化多出的点号“.”,数组[]初始化多出的逗号“,”相关推荐

  1. Golang 入门 : 结构体(struct)

    Go 通过类型别名(alias types)和结构体的形式支持用户自定义类型,或者叫定制类型.试图表示一个现实世界中的实体. 结构体由一系列命名的元素组成,这些元素又被称为字段,每个字段都有一个名称和 ...

  2. C 结构体 struct 详解

    数组(Array),它是一组具有相同类型的数据的集合.但在实际的编程过程中,我们往往还需要一组类型不同的数据,例如对于学生信息登记表,姓名为字符串,学号为整数,年龄为整数,所在的学习小组为字符,成绩为 ...

  3. [ C语言 ]指针---结构体(struct)---分支语句(1)---初识C语言末尾

    文章目录 前言 一,指针 二,结构体(struct) 三,分支语句(选择结构) 总结​​​​ 前言 本篇文章主要记录指针末尾,结构体,和分支语句(选择结构) --------------------- ...

  4. C语言结构体struct详解与实例

    目录 1.定义 2.应用 2.1初始化 2.2使用 3.结构体对齐规则与存储 1.定义 C语言中结构体(struct关键字定义)是一种自定义数据类型.通过结构体的定义可以将多种不同类型数据形成一个组合 ...

  5. c语言结构体定义蚂蚁,C语言结构体(struct)常见使用方法

    C语言结构体(struct)常见使用方法 C语言结构体(struct)常见使用方法 基本定义:结构体,通俗讲就像是打包封装,把一些有共同特征(比如同属于某一类事物的属性,往往是某种业务相关属性的聚合) ...

  6. C语言怎么存储结构体,C语言结构体Struct怎么使用?

    在C语言中,可以使用结构体(Struct)来存放一组不同类型的数据.结构体的定义形式为:struct结构体名{结构体所包含的变量或数组};结构体是一种集合,它里面包含了多个变量或数组,它们的类型可以相 ...

  7. linux 结构体 struct addrinfo 简介

    目录 定义 相关方法 1. getaddrinfo(const char, const char, const struct addrinfo, struct addrinfo*) 2. freead ...

  8. linux sock结构体,struct socket结构体详解

    在内核中为什么要有struct socket结构体呢? struct socket结构体的作用是什么? 下面这个图,我觉得可以回答以上两个问题.  由这个图可知,内核中的进程可以通过使用struct ...

  9. C/C++结构体struct 与结构体数组和枚举型enum的结合使用

    C/C++结构体struct 与结构体数组和枚举型enum的结合使用 #include "stdafx.h" #include <string> #include &l ...

最新文章

  1. sharepoint中一些gridview的使用方法
  2. Linux关于文件的权限笔记
  3. 学习 sentry 源码整体架构,打造属于自己的前端异常监控SDK
  4. C语言试题四十九之只删除字符串前导和尾部的*号,串中字母之间的*号都不删除。 n 给出了字符串的长度,h字符串中前导*号的个数,e给出了字符串中最后的*个数
  5. python搭建https代理服务器_使用NGINX作为HTTPS正向代理服务器
  6. Java实验8 T2.编程包含一个文本框和一个文本区域
  7. Halcon例程学习:print_check.hev(光学字符检测)
  8. 怎样开始买基金---我的基金购买体验[转]
  9. 学前端好还是后端好?
  10. win10c语言乱码修复方法,大神详解win10系统记事本中文变乱码的处理方案
  11. 建造者模式(Builder和Director)
  12. java群面自我介绍,群面的一分钟自我介绍
  13. 编译UE4出现C1076错误的解决方法
  14. SDN交换机在云计算网络中的应用场景
  15. 唯美雪景雪花飘落代码,附效果演示
  16. python中对象的赋值、浅拷贝和深拷贝
  17. (四)UPF之常用低功耗单元(Isolation、Level Shifter、Power Switch、State Retention、Always on cell)
  18. PS2021 编辑PDF文件,修改文字
  19. CL-200A串口通信
  20. TailwindCSS为前端开发者带来了什么?

热门文章

  1. ArcBlock ⑩ 月报 | ABT 节点承载运行所有 ArcBlock 产品与服务
  2. 智能网联汽车 — 自动/辅助驾驶技术
  3. 以数组作为函数参数的函数调用
  4. MATLAB给目标音频文件设计滤波器去除所添加的噪声
  5. 基于盛科芯片的PTP功能总结
  6. 龙兵瑜伽健身排课约课v1.10.14 约课 瑜伽/健身约课 课程排课
  7. Adversary在计算机安全领域的含义
  8. 阅读小结:A-Fast-RCNN: Hard Positive Generation via Adversary for Object Detection
  9. 使用Hydra破解弱密码
  10. 一个上海程序员的一天工作日志