1.CC++结构体的初始化

今天看到项目中对自定义结构体初始化方式有点陌生,特在此罗列一下可用的结构体初始化的方式。

对结构体

  1. struct A {

  2. int b;

  3. int c;

  4. }

有几种初始化方式:

第一种:

  1. struct A a = {

  2. .b = 1,

  3. .c = 2

  4. };

第二种:

  1. struct A a={

  2. b:1,

  3. c:2

  4. };

第三种:

struct A a1 = { 1, 2};

Linux内核喜欢用第一种,使用第一种和第二种时,成员初始化顺序可变。

第四种:
因为C++中的struct可以看作class,结构体也可以拥有构造函数,所以我们可以通过结构体的构造函数来初始化结构体对象。

给定带有构造函数的结构体:

  1. struct A {

  2. A(int a,int b){

  3. this->a=a;

  4. this->b=b;

  5. };

  6. int b;

  7. int c;

  8. }

那么结构体对象的初始化可以像类对象的初始化那样,如下形式:

struct A a(1,2);

注意: struct如果定义了构造函数的话,就不能用大括号进行初始化了,即不能再使用前三种初始化的方式了。

2.CC++结构体的赋值

变量的赋值和初始化是不一样的,初始化是在变量定义的时候完成的,是属于变量定义的一部分,赋值是在变量定义完成之后想改变变量值的时候所采取的操作。

还是给定结构体A:

  1. struct A {

  2. int b;

  3. int c;

  4. }

注意:结构体变量的赋值是不能采用大括号的方式进行赋值的,例如下面的赋值是不允许的。

  1. struct A a;

  2. //错误赋值

  3. a={1,2};

下面列出常见结构体变量赋值的方法。

第一种:
使用memset对结构体变量进行置空操作:

  1. //按照编译器默认的方式进行初始化(如果a是全局静态存储区的变量,默认初始化为0,如果是栈上的局部变量,默认初始化为随机值)

  2. struct A a;

  3. memset(&a,0,sizeof(a));

第二种:
依次给每一个结构体成员变量进行赋值:

  1. struct A a;

  2. a.b=1;

  3. a.c=2;

第三种:
使用已有的结构体变量给另一个结构体变量赋值。也就是说结构体变量之间是可以相互赋值的。

  1. struct A a={1,2};

  2. struct A aa;

  3. aa=a; //将已有的结构体变量付给aa

今天同事聊到内核中结构体初始化,

对结构体

struct a {

int b;

int c;

}

有几种初始化方式:

struct a a1 = {
 .b = 1,
 .c = 2
};
或者
struct a a1 = {
 b:1,
 c:2
}
或者
struct a a1 = { 1, 2};

内核喜欢用第一种,使用第一种和第二种时,成员初始化顺序可变。

转一篇文章

http://blog.hjenglish.com/bedford/

在阅读GNU/Linux内核代码时,我们会遇到一种特殊的结构初始化方式。该方式是某些C教材(如谭二版、K&R二版)中没有介绍过的。这种方式称为指定初始化(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;
};
    C99支持结构的指定初始化项目,其语法与数组的指定初始化项目近似。只是,结构的指定初始化项目使用点运算符和成员名(而不是方括号和索引值)来标识具体的元素。例如,只初始化book结构的成员value,可以这样做:
    struct book surprise = { .value = 10.99 };
    可以按照任意的顺序使用指定初始化项目:
    struct book gift = { .value = 25.99,
                                    .author = "James Broadfool",
                                    .title = "Rue for the Toad"};
    正像数组一样,跟在一个指定初始化项目之后的常规初始化项目为跟在指定成员后的成员提供了初始值。另外,对特定成员的最后一次赋值是它实际获得的值。例如,考虑下列声明:
    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。

摘自: http://blog.csdn.net/zhsxcn/archive/2008/02/27/2125211.aspx


5.22 特定的初始化

标准C89需要初始化语句的元素以固定的顺序出现,和被初始化的数组或结构体中的元素顺序一样。

在ISO C99中,你可以按任何顺序给出这些元素,指明它们对应的数组的下标或结构体的成员名,并且GNU C也把这作为C89模式下的一个扩展。这个扩展没有在GNU C++中实现。

为了指定一个数组下标,在元素值的前面写上“[index] =”。比如:

 
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 };

如果其中的值有副作用,这个副作用将只发生一次,而不是范围内的每次初始化一次。

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

在结构体的初始化语句中,在元素值的前面用“.fieldname = ”指定要初始化的成员名。例如,给定下面的结构体,

 
struct point { int x, y; };

和下面的初始化,

 
struct point p = { .y = yvalue, .x = xvalue };

等价于:

 
struct point p = { xvalue, yvalue };

另一有相同含义的语法是“.fieldname:”,不过从GCC 2.5开始废除了,就像这里所示:

 
struct point p = { y: yvalue, x: xvalue };

[index]”或“.fieldname”就是指示符。在初始化共同体时,你也可以使用一个指示符(或不再使用的冒号语法),来指定共同体的哪个元素应该使用。比如:

 
union foo { int i; double d; };union foo f = { .d = 4 };

将会使用第二个元素把4转换成一个double类型来在共同体存放。相反,把4转换成union foo类型将会把它作为整数i存入共同体,既然它是一个整数。(参考5.24节向共同体类型转换。)

你可以把这种命名元素的技术和连续元素的普通C初始化结合起来。每个没有指示符的初始化元素应用于数组或结构体中的下一个连续的元素。比如,

 
int a[6] = { [1] = v1, v2, [4] = v4 };

等价于

 
int a[6] = { 0, v1, v2, 0, v4, 0 };

当下标是字符或者属于enum类型时,标识数组初始化语句的元素特别有用。例如:

 
int whitespace[256]= { [' '] = 1, ['\t'] = 1, ['\h'] = 1,['\f'] = 1, ['\n'] = 1, ['\r'] = 1 };

你也可以在“=”前面写上一系列的“.fieldname”和“[index]”指示符来指定一个要初始化的嵌套的子对象;这个列表是相对于和最近的花括号对一致的子对象。比如,用上面的struct point声明:

 
struct point ptarray[10] = { [2].y = yv2, [2].x = xv2, [0].x = xv0 };

如果同一个成员被初始化多次,它将从最后一次初始化中取值。如果任何这样的覆盖初始化有副作用,副作用发生与否是非指定的。目前,gcc会舍弃它们并产生一个警告。

摘自:  http://www.kerneltravel.net/newbie/gcc_man.html#5.22


10、 结构体的初试化

gcc开始采用ANSI C的struct结构体的初始化形式:

static struct some_structure = {

.field1 = value,

.field2 = value,

..

};

老版本:非标准的初试化形式

static struct some_structure = {

field1: value,

field2: value,

..

};

c/c++ 结构体赋初值的小技巧相关推荐

  1. c语言 给结构体赋初值,c/c++ 结构体赋初值的小技巧

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 转:https://blog.csdn.net/datase/article/details/78988320 1.CC++结构体的初始化 今天看到项目中 ...

  2. C语言中对结构体赋初值

    C 语言中结构体的赋初值,可以对指定元素赋值,不必按照顺序,前提是通过 "." 来操作,在 c-free 5.0版本下验证通过. <pre name="code&q ...

  3. Golang 匿名结构体及测试代码编写技巧

    转自: https://www.jianshu.com/p/901820e17ffb 结构体基础 结构体 (struct) 将多个不同类型的字段集中组成一种复合类型,按声明时的字段顺序初始化. typ ...

  4. C语言结构体详解(结构体定义,使用,结构体大小等)

    c语言结构体详解 1.c语言结构体 1.1 结构体基础知识 1.2 结构体声明 1.3 结构体特殊声明 1.4 结构体的自引用 1.5 结构体的大小的计算 1.5.1了解结构体大小计算规则 1.5.2 ...

  5. C语言:结构体与位段——自定义类型

    目录 1.结构体 1.1结构的基础知识 1.2结构的声明 1.3特殊的声明 1.4结构的自引用 1.5结构体变量的定义和初始化 1.6结构体内存对齐 1.7检验结构体成员偏移量函数--offsetof ...

  6. C语言——自定义类型(结构体,枚举,联合体,位段)

    目录 结构体 结构体的定义 匿名结构体 结构体的自引用 结构体大小计算 位段 枚举 枚举概念 枚举的声明与使用 枚举大小计算 枚举与宏的区别 联合体 联合体的概念 联合体的声明与使用 联合体大小计算 ...

  7. 你还不了解结构体吗?带你深入了解结构体

    什么是结构体? 由多种数据类型共同构成而成的数据类型,他们可以是标量.数组.指针.甚至是其他结构体. 结构体的声明 //例 struct Stu {char name[20];int age;char ...

  8. C语言之结构体(进阶篇)

    目录 1.结构体的内存对齐​ 如何计算呢?​ 掌握结构体的对齐规则: 为什么存在内存对齐呢?​ ​​​​​​​offsetof​ 位段​ 什么是位段?​ 比如: 位段的内存分配​ 举个例子 位段的跨平 ...

  9. 【结构体——枚举——联合】

    文章目录 前言 结构体 结构体类型的声明 结构的自引用 结构体变量的定义和初始化 结构体内存对齐 修改默认对齐数 结构体传参 结构体实现位段(位段的填充&可移植性) 枚举 枚举类型的定义 枚举 ...

最新文章

  1. 在使用stl中的ifstream出错时如何快速排错?
  2. C#如何在Form中嵌入并且操作Excel表格
  3. 在weka中配置自己的算法 zz
  4. mac 下 通过 brew 安装 MariaDB
  5. ORACLE备份中的压缩
  6. 快速pow和sqrt的小技巧 hdu4282
  7. 【JVM】JVM 调优之 -XX 参数
  8. Oracle odi 数据表导出到文件
  9. JSP程序设计第二版--附带实验代码
  10. SmartSVN for Mac(SVN客户端)
  11. 使用135编辑器HTML样式,135编辑器滑动样式全教程!
  12. 服务熔断降级什么意思?
  13. 2006年十二生肖开运大预言
  14. 新视野大学英语(第三版)第二册课后翻译
  15. Android 开放配件协议 1.0
  16. Lustre是开放源代码的集群文件系统
  17. 聊一聊WEB前端安全那些事儿
  18. 用python tkinter组件实现扫雷游戏
  19. 7-10 sdut-求交错序列前N项和分数 10
  20. iNavFlight之RC遥控CRSF协议

热门文章

  1. application中 android:icon 和 android:roundIcon 的区别
  2. 菜鸟程序员如何才能快速提高自己的技术
  3. MySQL将字段数据自增自减
  4. JAVA实现的微信扫描二维码支付
  5. 2022年全球市场男士防脱发和增长产品总体规模、主要生产商、主要地区、产品和应用细分研究报告
  6. 樱桃键盘cherry G80-3000不完全拆解
  7. web前端之——图片上传
  8. 少壮不努力,老大写程序(kobewry) 经典话语啊
  9. java中的Dao类,model类是什么意思
  10. js 日期时间格式化,年月日时分秒