C语言指定初始化


C90标准要求初始化的元素以固定顺序出现,与被初始化的数组或结构中的元素的顺序相同。
在ISO C99标准中,可以以任何顺序指定元素的数组索引或结构字段名,而GNU C也允许在C90 标准中将其作为扩展。但是这个扩展没有在GNU C++中实现的。

1、数组指定初始化

要指定数组索引,请在元素值之前写入’ [index] = value ',例如:

int a[6] = { [4] = 29, [2] = 15 };

等价于

int a[6] = { 0, 0, 15, 0, 29, 0 };

需要注意的是,index必须是常量表达式,即使正在初始化的数组是临时变量; 如果是用来初始化全局变量,那么value也要为常量表达式。 另一种语法是在元素值前写’ [index] ‘,不写’ = '。这种语法在GCC 2.5之后就被淘汰了,但是GCC仍然支持。
GNU支持另外一种拓展:‘[first … last] = value’,可以将一组元素初始化为相同的值:

int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };

如果赋值的数据value有副作用,那么副作用只会发生一次,而不是针对所有初始化范围内的每个元素。

    int a =9;
    int test_array_init[ARRAY_NUM] = {
        [0 ... 3] = a++,
        [4 ... ARRAY_NUM-1] = a++
    };
    // test_array_init[10]={9,9,9,9,10,10,10,10,10,10}

测试代码如下:

#include<stdio.h>
#define ARRAY_NUM 10

int test_array_init[ARRAY_NUM] = {
    [0 ... 3] = -1,
    [4 ... ARRAY_NUM-1] = 66
 };

int main(int argc,char *argv[])
{
    int i = 0;
    for (i=0;i<ARRAY_NUM;i++)
    {
        printf("index:%d,%d\r\n",i,test_array_init[i]);
    }
    return 0;
}

指定数组初始化运行结果:
指定数组初始化运行结果

2、结构体指定初始化

在结构初始化中,用‘.fieldname =value’’ 指定要初始化的字段的数值。例如,给定以下结构体:

struct point { int x, y; };
//通过如下方式初始化
struct point p = { .y = yvalue, .x = xvalue };
//等价于
struct point p = { xvalue, yvalue };

另一种语法具有相同的含义,在GCC 2.5之后就过时了,它是’ fieldname: ',如下所示:

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

初始化省略的字段,按照静态变量的方式被隐式初始化(临时变量是否也是这样没有验证)。

‘[index]’ 和 '.fieldname '被称为标识符。在初始化union时,还可以使用标识符(或过时的冒号语法)来指定应该使用联合的哪个元素。例如,

union foo { int i; double d; };
union foo f = { .d = 4 };
//将4转换为双精度值,通过第二个元素将其存储在union。

3、指定初始化综合使用

可以将这种指定初始化的方式与普通C初始化相结合,普通的初始化方式,应用于没有标识符指示的连续元素。例如,

int a[6] = { [1] = v1, v2, [4] = v4 };
//等价于
int a[6] = { 0, v1, v2, 0, v4, 0 };

当索引是字符或属于枚举类型时,标记数组初始化器的元素特别有用。例如:

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

如果同一个字段被多次初始化,或者一个联合的重叠字段被初始化,则使用上一次初始化的值。如果union的字段本身是结构,则使用上一个初始化字段的整个结构。如果之前的初始化有副作用,则不确定该副作用是否会发生。目前,GCC会丢弃产生副作用的初始化表达式并发出警告。

参考: [link](Using the GNU Compiler Collection 6.29).

展开阅读全文
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值