总结几种结构体初始化的方法(转)

2023-05-16

总结几种结构体初始化的方法


转自:http://www.cnblogs.com/vongang/archive/2011/07/30/2122076.html


结构体能自由组装数据,是一种很常见的数据打包方法。当我们定义一个结构体后,没有初始化就使用,就会使用到垃圾数据,而且这种错误很难发现。对于定义的任何变量,我们最好都先初始化。

 

除了使用memsetZeroMemory之外,有没有更简单的方法初始化呢?因为有时候每定义一个结构体,就使用一次memset,也会觉得很繁琐。

 

我这里总结三种方法,如果大家有什么好的方法,不妨加上去。

 

1、结构体的构造函数中初始化。

 

2、继承模板类初始化

 

3、定义时初始化

在C++中,结构体与类在使用上已没有本质上的区别了,所以可以使用构造函数来初始化。如下代码所示:

  struct Stu
 {
  int  nNum;
  bool bSex;
  char szName[20];
  char szEmail[100];

  //构造函数初始化
  Stu()
  {
   nNum = 0;
   bSex = false;
   memset(szName,0,sizeof(szName));
   memset(szEmail,0,sizeof(szEmail));

  }
 };

你可能已经发现了,如果结构体中有大量成员,一个个赋值,相当麻烦。那么你可以这样写:

 struct Stu
 {
  int  nNum;
  bool bSex;
  char szName[20];
  char szEmail[100];

  //构造函数初始化
  Stu()
  {
    memset(this,0,sizeof(Stu));
    //或者是下面的格式
    //memset(&nNum,0,sizeof(Stu));

  }
 };

如果在结构体中分配了指针,并且指针指向一个堆内存,那么就在析构函数中释放。以上便是在构造函数中初始化。

2、继承模板类初始化

首先定义一个模板基类:
template <typename T>
class ZeroStruct
{
public:
    ZeroStruct()
    {
        memset(this,0,sizeof(T));
    }
};

之后定义的结构体都继承于此模板类。 

    struct Stu:ZeroStruct<Stu>
    {
        int        nNum;
        bool    bSex;
        char    szName[20];
        char    szEmail[100];
    };

这样也能实现初始化。

3、定义时初始化。

    struct Stu
    {
        int        nNum;
        bool    bSex;
        char    szName[20];
        char    szEmail[100];
    }; 

//定义时初始化
Stu stu1 = {0};

在有的结构体中,第一个成员表示结构体的大小,那么就可以这样初始化:

 struct Stu
 {
int nSize; //结构体大小
  int  nNum;
  bool bSex;
  char szName[20];
  char szEmail[100];
 };


 Stu stu1 = {sizeof(Stu),0};

后面的0,可以省略掉,直接写成:Stu stu1 = {sizeof(Stu)};后面自动会用0填充。

总结分析:

以上三种,是据我所知的初始化结构体方法。

前面两种,实际上已经把结构体给类化了,和类的使用差不多。第三种,是纯粹的结构体的写法。

如果用途仅仅限定为结构体,我建议不要加上构造函数,也不要继承于那个模板类,因为这个时候结构体实际上已经是类了。在定义结构体时,将无法使用第三种方式去初始化,当然,此时也不需要初始化了。

看看微软定义的结构体,基本上都没有构造函数和析构函数。因为结构体的意义很明确,它仅仅是对数据的一个包装,如果加上了方法,其意义就变了。



参考文章:

http://blog.csdn.net/adaptiver/article/details/7494081
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会舍弃它们并产生一个警告。



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

总结几种结构体初始化的方法(转) 的相关文章

  • React State 状态

    React State 状态 React 把组件看成是一个状态机 xff08 State Machines xff09 通过与用户的交互 xff0c 实现不同状态 xff0c 然后渲染 UI xff0c 让用户界面和数据保持一致 React
  • C#实现窗体内容随着窗体的缩放而缩放

    private float X private float Y 获取控件的width height left top 字体大小的值 存放在控件的Tag属性中 private void setTag Control cons 遍历窗体中的控件
  • ROS基础 - dynamic_reconfigure 动态参数

    ROS基础 dynamic reconfigure 动态参数使用 实例详解 采用 ROS dynamic reconfigure 的形式 xff0c 可以在程序运行过程中实时更改参数大小 xff0c C 43 43 代码通过回调函数接收数据
  • C_C++变量命名规则

    C C 43 43 变量命名规则 变量命名规则是为了增强代码的可读性和容易维护性 以下为C 43 43 必须遵守的变量命名规则 xff1a 1 变量名只能是字母 xff08 A Z xff0c a z xff09 和数字 xff08 0 9
  • Git 初次提交代码

    Git 初次提交发布代码 首先打开 bash 出现git的命令行 可以在GitHub上新建一个仓库 这是提交了的代码的仓库 xff0c 刚创建的时候只有 README md 和 gitignore 两个文件 xff01 在进入git的命令行
  • MATLAB 快速绘制曲线图的形状,粗细,颜色

    目录 MATLAB 快速绘制曲线图的形状 xff0c 粗细 xff0c 颜色1 通过改变R G B 的值改变线条的颜色 xff1a 2 通过改变c 1 43 的值改变线条的粗细 xff1a 3 线条形状 xff0c 粗细 xff0c 颜色选
  • STM32F103五分钟入门系列(一)跑马灯(库函数+寄存器)+加编程模板+GPIO总结

    摘自 xff1a STM32F103五分钟入门系列 xff08 一 xff09 跑马灯 xff08 库函数 43 寄存器 xff09 43 加编程模板 43 GPIO总结 作者 xff1a 自信且爱笑 发布时间 xff1a 2021 04
  • Git的安装(附安装包)

    目录 使用目的关于Git的历史Git的安装1 运行安装包 xff0c 点击next2 选择安装路径 xff0c 下一步3 点击next4 设置开始菜单 xff0c 默认next5 点击next6 选择git的方式7 剩下所有步骤均默认即可8
  • GPIO输入输出模式原理(八种工作方式附电路图详解)

    这几篇博文讲的不错 xff0c 可参照着理解 xff1a STM32下拉输入模式与振动传感器的使用 上拉电阻与下拉电阻 通俗解读 上 下拉电阻 xff08 定义 强弱上拉 常见作用 吸电流 拉电流 灌电流 xff09 个人总结 xff1a
  • 树莓派接入公网(花生壳)

    参考 xff1a 树莓派接入公网 作者 xff1a 图触靓 发布时间 xff1a 2020 12 22 17 28 19 网址 xff1a https blog csdn net bhbhhyg article details 107994
  • 深入理解STM32内存管理

    参考 xff1a 详解ROM和RAM 作者 xff1a 嵌入式实验楼 网址 xff1a https mp weixin qq com s y2aG7kX 6CTyeMzEJW YHw 内存相关博文 xff1a 1 内存四区 xff08 代码
  • React Props

    state 和 props 主要的区别在于 props 是不可变的 xff0c 而 state 可以根据与用户交互来改变 所以 xff0c 有些容器组件需要定义 state 来更新和修改数据 而子组件只能通过 props 来传递数据 pro
  • Chrome如何下载网页视频

    目录 第一步 xff1a 右键 xff0c 选择 检查 指令 xff0c 进入代码控制面板第二步 xff1a 单击代码面板左上角红色标出来的按钮 xff0c 然后鼠标移到左边视频上第三步 xff1a 双击src后面的代码 xff08 全部展
  • MODBUS通讯协议详解(基于485)

    参考 xff1a 灵育科技Modbus课程总结 作者 xff1a Naunyang 时间 xff1a 2020 11 23 13 51 58 网址 xff1a https blog csdn net Naunyang article det
  • 步进电机、伺服电机、舵机、无刷电机、有刷电机区别

    参考 xff1a 步进电机 伺服电机 舵机的原理和区别 xff1f Vincross的回答 知乎 地址 xff1a https www zhihu com question 37374664 answer 167299936 目录 什么是电
  • 面经——嵌入式常见面试题总结100题(下)

    参考 xff1a 嵌入式常见面试题总结 xff08 1 xff09 作者 xff1a 天泉证道 发布时间 xff1a 2018 11 08 09 33 43 网址 xff1a https guoyanzhang blog csdn net
  • 4种整流电路、5种滤波电路

    目录 基本电路变压电路整流电路半波整流电路全波整流电路桥式整流电路倍压整流电路 滤波电路电容滤波电路电感滤波电路RC滤波电路LC滤波电路有源滤波电路 整流滤波电路总结常用整流电路性能对照常用无源滤波电路性能对照电容滤波电路输出电流大小与滤波
  • 焊接技巧(热风枪/QFP/QFN/SOP/穿孔/烙铁头/助焊膏/连锡/飞线/回流焊)

    https www bilibili com video BV1wJ411B73v p 61 1 amp vd source 61 cc0e43b449de7e8663ca1f89dd5fea7d
  • C语言如何跳出多重循环

    目录 前言一 题目示例二 解决方法1 使用goto语句2 使用状态标志 总结 参考 xff1a https blog csdn net qq 45797595 article details 122278580 ops request mi

随机推荐

  • 第一个hadoop入门程序WordCount

    要导入hadoop文件夹中share下的common文件夹中的几个包和lib下的包 xff0c 以及mapreduce中相应的包 package com yootk mr demo import java io IOException im
  • 4种版本控制工具

    1 Visual Source Safe VSS xff09 VSS是美国微软公司的产品 xff0c 是配置管理的一种很好的入门级的工具 xff08 window系统 xff09 VSS的配置管理的功能比较基本 xff0c 提供文件的版本跟
  • 1. STM32学习 STM32综述

    什么是STM32 STM32是ST公司基于ARM Cortex M内核开发的32位微控制器 MCU 学习使用的是STM32F1系列 xff0c 内核为Cortex M3 STM32功能强大 性能优异 片上资源丰富 功耗低 xff0c 是一款
  • React 列表 & Keys

    列表 amp Keys 列表 React 列表可以使用 JavaScript 的 map 方法来创建 如下 xff1a span class token operator lt span span class token operator
  • [转载]电机 螺旋桨 电池之间的关系(普及版)

    http blog sciencenet cn blog 39356 509001 html 电机KV值 xff1a 电机的转速 xff08 空载 xff09 61 KV值X电压 xff1b 例如KV1000的电机在10V电压下它的转速 x
  • stm32 FreeRTOS 某个任务一直不被运行

    在用FreeRTOS操作系统时 xff0c 发现某一个任务一直不被运行查找后发现问题出在四个点 xff1a xff08 1 xff09 任务资源调用冲突 xff0c 当时在用两个任务去操作同一个串口 xff0c 发现任务在刚刚开始的时候 x
  • FreeRTOS 任务不切换可能的问题

    1 时间片调度没有打开 FreeRTOS h 文件中宏定义 configUSE TIME SLICING 没有定义为1 解决方案 xff1a ifndef configUSE TIME SLICING define configUSE TI
  • 通俗易懂的IMU讲解,这一篇就够了

    IMU技术的出现弥补了GPS定位的不足 xff0c 两者相辅相成 xff0c 可以让自动驾驶汽车获得最准确的定位信息 IMU全称inertial measurement unit xff0c 即惯性测量单元 xff0c 它由三个单轴的加速度
  • ubuntu16.04查看硬盘分区使用情况

    方法一 xff1a xff08 推荐 xff09 1 左上角的dash菜单 xff0c 搜索 gnome system monitor 打开磁盘工具 2 在 文件系统 中可以列出已经挂载打开的分区的使用情况 方法二 xff1a 1 左上角的
  • 【ORB-SLAM2】(三):单目摄像头+ROS+ORB_SLAM2实时测试

    介绍 xff1a 首先启动一个单目摄像头 xff0c 其次发布节点话题 usb cam image raw xff0c 最后ORB SLAM2订阅摄像头数据进行处理 xff08 这里需要修改相应的源文件里的话题类型 xff0c 其默认值为
  • vscode如何更换主题

    1 打开Vscode xff0c 点击 文件 首选项 颜色主题 快捷键 xff1a 先按Ctrl 43 K 再按Ctrl 43 T 2 打开主题设置面板 xff0c 在深色主题中点击 深色 3 这样就可以把主题改为 深色 这样Vscode界
  • CSDN写博客更改代码颜色为白色代码样式

    一 背景 在平时发博客时 xff0c 代码块背景默认是黑色的 xff0c 而注释是黑色的 xff0c 总是看起来很不清楚 直接上图 xff1a 注释看起来很不清晰 xff0c 现在我们修改一下颜色为白色 直接上图 xff1a 下面是具体设置
  • win10安装Ubuntu16.04双系统

    下载Ubuntu16 04 xff1a 下载地址 xff1a 官网 xff1a Ubuntu 16 04 7 LTS Xenial Xerus 阿里云开源镜像站 ubuntu releases 16 04安装包下载 开源镜像站 阿里云 中科
  • SLAM后端--滤波方法和非线性优化方法

    SLAM的后端一般分为两种处理方法 xff0c 一种是以扩展卡尔曼滤波 xff08 EKF xff09 为代表的滤波方法 xff0c 一种是以图优化为代表的非线性优化方法 不过 xff0c 目前SLAM研究的主流热点几乎都是基于图优化的 滤
  • React 组件 API

    常用 React 组件 API xff1a 设置状态 xff1a setState替换状态 xff1a replaceState设置属性 xff1a setProps替换属性 xff1a replaceProps强制更新 xff1a for
  • 浅析SATA Physical Layer物理层OOB信号

    一 SATA物理层概述 说OOB之前 xff0c 首先得了解一下SATA结构以及物理层的含义 SATA主要包括 xff1a 应用层 Application Layer 传输层 Transport Layer xff0c 链路层 Link L
  • CodeBlocks 20.03下载及安装指南 使用自带MinGW进行环境配置

    原本用的好好的CodeBlocks 17 12 xff0c 今天手欠无聊去搜了一下官网发现两年都没更新的cb竟然在这两天更新了 对于一直喜欢用最新版的我 xff0c 一定要更新 xff0c 然后 我还把之前的各项配置都删掉了 好吧 xff0
  • 程序是从main主函数开始运行吗?

    很多人开始学计算机语言 xff0c 编写代码时都会有一个疑问 xff1a 程序真的是从main主函数开始的吗 xff1f 之前什么都不做吗 xff1f main结束后就不能执行其他函数了吗 xff1f 下面本篇文章就为此问题做一个简单的解释
  • C++内存越界(转)

    glibc detected free invalid pointer glibc detected malloc memory corruption glibc detected double free or corruption out
  • 总结几种结构体初始化的方法(转)

    总结几种结构体初始化的方法 转自 xff1a http www cnblogs com vongang archive 2011 07 30 2122076 html 结构体能自由组装数据 xff0c 是一种很常见的数据打包方法 当我们定义