C数组&结构体&联合体快速初始化

C语言数组的初始化表示方法

 

一、C语言一维数组初始化: 

(1)在定义数组时对数组元素赋以初值。如:

static int a[10]={0,1,2,3,4,5,6,7,8,9};

经过上面的定义和初始化后,a[0]=0,a[1]=1,… ,a[9]=9。

 

(2)初始化时可以只对一部分元素赋初值。例如:

static int a[10]={0,1,2,3,4};

定义的数组有10个元素,但只对其中前5个元素赋了初值,后5个元素初值为0。

 

(3)将数组的元素值全部为0,可以用下面的方法:(方法一)

int a[5] = {0};  // 将整型数组a的每个元素都初始化为0

或者也可以用如下方法进行初始化:(方法二) 

int a[5] = {0, 0, 0, 0, 0}; // 初始化效果同上

不能用: static int a[10]={0*10};

如果对static型数组不赋初值,系统会对定义的所有数组元素自动赋以0值。

 

(4)在对全部数组元素赋初值时,可以不指定数组长度。 

int a[]={0,1,2,3,4};

相当于 int a[5]={0,1,2,3,4};

 

二、C语言二维数组初始化: 

声明时给初始值叫初始化。例如:int b[3][4]={1,2,3,4,5,6,7,8,4,4,4,4};
声明后赋值,可以用赋值语句,
b[0][0]=1; b[0][1]=2; b[0][2]=3; b[0][3]=4;
b[1][0]=5; b[1][1]=6; b[1][2]=7; b[1][3]=8;

 

三、C语言结构体初始化: 

1.typedef定义结构体

typedef struct Student {

    agent age;

    char name[10];

} Stu;

 

2.创建结构体变量并初始化

Stu s = {18,"rose"};//可以初始化,设置age为1,s为一个字符串.

Stu s = {18};//初始化个数少于实际个数时,只初始化前面的成员。

Stu s = {.name="rose"};//有选择的初始化成员。

 

3、结构体数组:初始化需用大括号将数组中每一个结构体括起来:

Stu s[10] = {{18,"rose"},{19,"jack"},{18,"tony"},{17,"misa"}};

也可以初始化其中的一个元素:

Stu s[10] = {[2]={19,"jack"}, [3]={18,"tony"}};

Stu s[10] = {[2].age=19, [3].name="tony"};

 

四、C语言数据类型还有共用体和链表,但C语言没有字典这一说。

 

C数组&结构体&联合体快速初始化

 

背景

     C89标准规定初始化语句的元素以固定顺序出现,该顺序即待初始化数组或结构体元素的定义顺序。

     C99标准新增指定初始化(Designated Initializer),即可按照任意顺序对数组某些元素或结构体某些成员进行选择性初始化,只需指明它们所对应的数组下标或结构体成员名。GNU C将其作为C89模式的扩展。

     借助指定初始化特性,可实现数组或结构体元素的快速初始化。

 

数组初始化

     在数组初始化列表中使用“[index常量表达式]=value”形式可对index所指定的某个元素进行初始化。如:

int arr[6] = { [0]=5, [1]=6, [3] =10, [4]=11 }; 或

int arr[6] = { [0]=5, 6, [3] =10, 11 }; 或

int arr[6] = { [3] =10, 11, [0]=5, 6 }; (指定顺序可变)

均等效于:int arr[6] = {5, 6, 0, 10, 11, 0};

     说明:

     1) 若在某个指定初始化项目后跟有不至一个值,如[3]=10,11。则多出的数值用于对后续的数组元素进行初始化,即数值11用来初始化arr[4]。

     2) C数组初始化一个或多个元素后,未初始化的元素将被自动地初始化为0或NULL(针对指针变量)。未经过任何初始化的数组,所有元素的值都是不确定的。

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

int whitespace[256] = {

    [' '] = 1, ['\t'] = 1, ['\h'] = 1,

    ['\f'] = 1, ['\n'] = 1, ['\r'] = 1 };

static const char* gMsgName[] = {

    [MSG_CREATE] = "Create",

    [MSG_DELETE] = "Delete",

    [MSG_SET]    = "Set",

    [MSG_GET]    = "Get",

    [MSG_GET_ALARMS] = "GetAlarms",

    [MSG_SET_TABLE]  = "SetTable"}; //枚举值变化时,数组自动同步更新

     这种初始化方式可实现简化的映射表,不过在下标指示符跨度较大时稍显浪费内存。

 

     GNU C还支持”[first … last]=value”(…两侧有空格)的形式,将该范围内的若干元素初始化为相同值。如:

int arr[]={ [0 ... 3]=1, [4 ... 5]=2, [6 ... 9] =3}; 或

int arr[]={ [0 ... 3]=1, [4 ... 5]=2, [6 ... 8] =3, [9] =3};

均等效于:int arr[10] = {1, 1, 1, 1, 2, 2, 3, 3, 3, 3};

     注意,数组长度为指定的最大下标值加1。

     这种初始化方式比memset高效且用途更广,如:

int arr[]={ [0 ... 127]=-1 };

等效于:memset(arr, 0xFF, sizeof(arr));

int arr[]={ [0 ... 127]=1 };

不等效于:memset(arr, 1, sizeof(arr));

 

结构体初始化

     结构的指定初始化语法与数组类似,只不过使用点运算符和成员名(而不是方括号和索引值)标识具体的元素。例如,对于结构体

     struct Structure{ int a; int b; };或struct Structure{ int a, b; };

     有以下几种初始化方式:

struct Structure tStct = {

    .a = 1,

    .b = 2

};

用“.fieldname=”指定待初始化成员名(成员初始化顺序可变)

struct Structure tStct = {

    a : 1,

    b : 2

};

用“fieldname:”指定待初始化成员名(成员初始化顺序可变)

GCC 2.5已废除,但仍接受

struct Structure tStct = { 1, 2};

     内核结构体多采用第一种初始化方式,如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,

};

     该方式初始化时不必严格按照定义时的顺序,灵活性很高。

    【例】定义如下结构体

struct book{

    char title[MAXTITL];

    char author[MAXAUTL];

    float value;

    int mask[128];

};

     可按照任意顺序使用指定初始化项目:

struct book gift = { .value = 25.99,

                           .author = "James Broadfool",

                           .title = "Rue for the Toad",

                           .mask[0 ... 127] = -1};

     也可只初始化结构体成员value:

struct book surprise = { .value = 10.99 };

     正如数组一样,跟在指定初始化项目后且没有指示符(“[index]”或“fieldname”)的常规初始化项目为跟在指定成员后定义的下个成员提供初始值。此外,若对特定成员初始化多次,则最后一次赋值是它实际获得的值。

     考虑下列声明:

struct book gift = { .value = 18.90,

                           .author = "Philionna pestle",

                            0.25};

     将把值0.25赋给成员value,因为它在结构体定义中紧跟在author成员之后。新值0.25覆盖前值18.90。

     若覆盖初始化有副作用(如类型不兼容),则GNU C可能会产生编译警告。

     利用指定初始化特性,可方便地编写如下的测试例程:

AGENT_PW_PSN tPwPsn = {

    .dwSlotNo = 2,

    .dwPortNo = dwPortNo,

    .dwPsnType = TRANS_MPLS,

    .dwInBndLable = dwInBndLable,

    .dwOutBndLable = dwOutBndLable,

    .dwMplsType = MPLS_SINGLE_LABELLED,

    .dwInBndTunnelLable = 0,

    .dwOutBndTunnelLable = 0,

    .aucDstMac = {0x00,0x15,0xeb,0x72,0x00,0x0e},

    .dwVlanId = 300,

    .dwPriority = 7

};

OmciSetPwPsn(&tPwPsn, sizeof(tPwPsn), aucBufOut, &dwOutLen);

 

联合体初始化

     可用“.fieldname” (或已废弃的“fieldname:”)指示符来指定使用联合体的哪个元素,如:

union UnionT { int i; double d; };

union UnionT tUnion = { .d = 4 };

     使用第二个元素将4转换为double类型存入联合体。相反,将4转换为union UnionT类型则会把它作为整数i存入联合体。

 

结构体数组初始化

     可在“=”前写上一系列的“[index]”和“.fieldname”指示符来指定待初始化的嵌套子对象,如:

struct Structure ptStct[10] = {

     [2].b = 0x2B, [2].a = 0x2A,

     [0].a = 0x0A };

 

5 GCC扩展结构体赋值

     对于上文定义的结构体Structure可整体赋值:

struct Structure tStct1, tStct2;

tStct2 = tStct1;

     结构体也可作为函数返回值对另一个结构体赋值:

struct Structure func1();

struct Structure tStct = func1();

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值