凡亿教育-香老板
凡事用心,一起进步
打开APP
公司名片
凡亿专栏 | 嵌入式 C 语言特性,指定初始化器
嵌入式 C 语言特性,指定初始化器

我是老温,一名热爱学习的嵌入式工程师
关注我,一起变得更加优秀!在嵌入式 C 语言的 C89/C90 标准里面,要求程序员在初始化程序中的各个变量元素时,要以固定的顺序进行,并且要与被初始化的数组和结构体的元素顺序相同。

在后来的新标准 C99/C11 里面,新增加了一个灵活且好用的特性:指定初始化器(Designated Initialize),这个新特性可以允许程序员在初始化数组或结构体时,可以指定特定的元素初始值,而不需要按照固定的顺序。
一、应用示例
指定初始化器,一般可以应用于数组、结构体、联合体,等成员变量的初始化,以下举例说明一下。
(1)数组:
对于普通数组在定义时的元素初始化,比如初始化最后一个元素为9527,使用传统的 C89 语法和C99语法,它们两者之间的差异,如以下代码所示。


int arr_1[5] = {0, 0, 0, 0, 9527};    //使用传统的C89语法
int arr_2[5] = {[4] = 9527};    //使用C99特性,指定初始化器
以上的使用方法比较好理解,对于未被使用的元素都初始化为0,在旧的C89语法里面,需要按数组元素的顺序进行初始化,而使用了C99语法的指定初始化器,可以指定具体的元素索引进行初始化。

我们再来看一种比较复杂的使用场景:


#include 
int main(void){    int i;    int num[8] = {11, 22, [4] = 55, 66, 77, [1] = 99};
   for (i = 0; i < 8; i  )        printf("index = -, num = %d ", i, num[i]);
   return 0;}
程序运行后,具体输出如下:


index = 0, num = 11index = 1, num = 99index = 2, num = 00index = 3, num = 00index = 4, num = 55index = 5, num = 66index = 6, num = 77index = 7, num = 00
从以上的程序运行输出可以看出,使用指定初始化器对数组进行初始化的时候,如果指定的元素后面有更多的值,那么这些值将被用于初始化指定元素后面的元素,num[4]被初始化为55后,num[5] 和 num[6] 会被初始化为 66 和 77。(需要注意定长数组的溢出问题)

再看一下上面的程序,一开始num[1] 被初始化为22,但后面又被重新指定初始化为[1] = 99,前面的初始值22就会被新的指定的初始值99替代。
(2)结构体与联合体
除了数组,C99 特性还为结构体和联合体提供了指定初始化器,在语法上,结构体或联合体在使用指定初始化器的时候,通常使用“点运算符和成员名”来标识特定的元素。


typedef struct student{    char name[20];    int age;    char school[20];    int class;}student_t;
student_t stu_1 = {    .age = 10,    .name = "John",    .school = "lanxiang",    .class = 3,};
从以上的代码可以看出,学生 John 的年龄是10岁,在lanxiang学校就读三年级。结构体的成员可以按照任意数量任意顺序进行初始化。
与数组类似的是,对成员最后一次赋值才是该成员的实际初始化值,如下代码所示,class的值由最后的 5 取代了前面 3,(因为class成员在school后面)。


student_t stu_1 = {    .class = 3,    .school = "lanxiang",    5,};

c36a8215a2be2dbeb2a3c2a9d56d24.jpg

二、优点和缺点


优点:

1、提高代码可读性:指定初始化器可以直观地看到元素被初始化了特定的值,而不需要按照成员顺序来赋值。
2、减少错误:在初始化大型数组或结构体时,指定初始化器可以减少因顺序错误导致的初始化错误。
3、提高效率:在某些情况下,使用指定初始化器可以减少代码量,提高编码效率。
4、灵活性:可以为数组或结构体中的特定元素赋值,而不必关心其他元素的初始化顺序。

5、易于维护:当需要修改特定元素的初始值时,只需修改对应的初始化表达式,而不需要重新排列整个初始化列表。
缺点:
1、兼容性问题:指定初始化器是C99标准新引入的特性,旧版本的编译器可能无法识别这种初始化方式。
2、易引起混淆:对于不熟悉指定初始化器的程序员来说,当初始化列表很长时,这种初始化方式容易引起混淆。
3、限制性:在使用指定初始化器时,不能跳过未初始化的元素。例如,不能在数组的第0个元素和第2个元素之间直接初始化第1个元素。
4、性能影响:在某些情况下,编译器可能需要额外的工作来处理指定初始化器,这可能会对编译时间或运行时性能产生轻微影响。
三、注意事项
在使用指定初始化器的时候,需要遵循以下注意事项:
1、确保编译器支持:在使用指定初始化器之前,确保你的编译器支持C99或更新的标准。
2、遵循初始化顺序:在使用指定初始化器时,不能跳过未初始化的元素。例如,不能直接初始化数组的第2个元素而忽略第1个元素。
3、注意全局和静态变量:全局和静态变量在程序开始执行前就已经初始化完成,使用指定初始化器可以确保这些变量具有正确的初始值。
4、避免过度使用:指定初始化器虽然提供了灵活性,但过度使用可能会使代码难以理解和维护。应该在适当的情况下使用它,以保持代码的清晰和简洁。
5、注意内存对齐:在使用指定初始化器初始化结构体时,注意内存对齐问题,确保结构体的布局符合预期。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表凡亿课堂立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。
相关阅读
进入分区查看更多精彩内容>
精彩评论

暂无评论