例解GNU C之指定初始化项目

    前言:计算机语言是编译器和程序员交流的依据和规范,GNU C是GCC特有的功能,在Linux内核中被广泛应用。

    帮助文档:http://gcc.gnu.org/onlinedocs/gcc-4.6.2/gcc/C-Extensions.html#C-Extensions

 

    指定初始化项目(Designated Initializers):指的是可以对数组中的某些元素或结构体变量中的某些成员以任意的顺序进行选择性的初始化。

    1、在数组中的应用

    在数组的初始化列表中使用“[index]= value”这样的形式即可实现对指定(通过index指定)的某个元素进行初始化。

    举例,如清单1: 

#include <stdio.h>

int main(void)
{
    int i;
    int arr[6] = { [3] = 29, 18, [0] = 12, 33}; //等价于int arr[6] = { [3] = 29, [4] = 18, [0] = 12, [1] = 33};
    						//也就是等价于int arr[6] = {12, 33, 0, 29, 18, 0};

    for (i = 0; i < 6; i++)
	printf("arr[%d]: %d\n", i, arr[i]);

    return 0;
}

    例子输出结果: 

arr[0]: 12
arr[1]: 33
arr[2]: 0
arr[3]: 29
arr[4]: 18
arr[5]: 0

    如例子中的第6行,通过[3] = 29把arr[3]初始化为29,通过[0] = 12把arr[0]初始化为12。

    说明(1):如果在一个指定初始化项目后跟有不止一个值,如例子中的[3] =29, 18,则这些多余的数值将用来对后续的数组元素进行初始化,即数值18用来初始化arr[4]。

    提醒:对C语言数组来说,在初始化一个或多个元素后,其中未经初始化的元素都将被自动地初始化为0或者NULL(针对指针变量而言)。未经过任何初始化的数组,其所有元素的值都将是不确定的(针对局部变量而言)。

    同一元素被多次初始化的例子,如清单2: 

#include <stdio.h>

int main(void)
{
    int i;
    int arr[5] = {23, 3, 45, [1] = 34, 8};

    for (i = 0; i < 5; i++)
	printf("arr[%d]: %d\n", i, arr[i]);

    return 0;
}

    例子输出结果: 

arr[0]: 23
arr[1]: 34
arr[2]: 8
arr[3]: 0
arr[4]: 0

    如例子中的第6行,元素arr[1]和arr[2]先被分别初始化为3和45,后又通过指定初始化项目[1] = 34, 8把arr[1]和arr[2]的值改变为34和8。

    说明(2):如果多次对同一个元素进行初始化,则最后一次初始化的值有效。这也很好理解,因为数组的每个元素都是一个变量,不断对同一变量赋不同值,当然这个变量的最终值为最后赋的值。

    指定初始化项目的特性在ISO C99中已经被支持。

    GNU C还支持“[first … last] = value”的形式,即一个范围内的几个元素被初始化为同一值,举例,如清单3: 

#include <stdio.h>

int main(void)
{
    int i;
    int arr[] = { [0 ... 3] = 1, [4 ... 5] = 2, [6 ... 9] = 3};

    for (i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
	printf("arr[%d]: %d\n", i, arr[i]);

    return 0;
}

    例子输出结果: 

arr[0]: 1
arr[1]: 1
arr[2]: 1
arr[3]: 1
arr[4]: 2
arr[5]: 2
arr[6]: 3
arr[7]: 3
arr[8]: 3
arr[9]: 3

    2、在结构体变量中的应用

    在结构体变量的初始化列表中通过点运算符(.)和成员名的形式(.fieldname= value)来指定初始化其中的某些成员。

    举例,如清单4: 

#include <stdio.h>

struct mystruct {
    int num;
    char ch;
    float fl;
};

int main(void)
{
    struct mystruct mystruct = { .ch ='M' };

    printf(" num = %d\n ch = %c\n fl = %f\n", 
	    mystruct.num, mystruct.ch, mystruct.fl);

    return 0;
}

    例子输出结果: 

 num = 0
 ch = M
 fl = 0.000000

    前面两个说明中的特点同样适用于结构体变量。

    注意:旧式的GCC 2.5编译器还使用过以下的形式(成员名加冒号)来初始化指定的结构体成员: 

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

    在联合体(共用体)中也可以使用指定初始化项目的特性,如: 

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
__attribute__是一个编译属性,用于向编译器描述特殊的标识、错误检查或高级优化。它是GNU C的一个特性,可以用于设置函数属性、变量属性和类型属性等。在给函数、变量或类型添加属性时,可以使用__attribute__来指定属性列表。例如,可以使用__attribute__((constructor))来在main函数执行之前执行某个函数,使用__attribute__((destructor))来在main函数执行之后执行某个函数。\[1\]这些属性可以用于实现一些特殊的功能或行为,比如在程序运行前后执行一些初始化或清理操作。在给函数、变量或类型添加属性时,需要按照特定的格式来设置,比如使用__attribute__((attr_list))的形式来指定属性列表。\[2\]\[3\] #### 引用[.reference_title] - *1* *3* [C语言的attribute机制](https://blog.csdn.net/weixin_37867857/article/details/102940773)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [C语言再学习 -- __attribute__详解](https://blog.csdn.net/qq_29350001/article/details/129390465)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tanglinux

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值