C语言,变长数组的用法
在我的《C语言,结构体成员的地址》文章中,定义了一个demo_node结构体,其中用到变长数组char addr[0]。本文以此为例,对C语言变长数组的基本用法展开介绍。
#pragma pack(1) typedef struct _demo_node_{ struct _demo_node_* pprenode; struct _demo_node_* pnextnode; unsigned long member_num; unsigned short age; char addr[0]; }demo_node; #pragma pack()
1、变长数组的定义
变长数组是指用整型变量或表达式声明或定义的数组,它的长度为0,这个数组本身并不占空间。
printf("sizeof(struct _demo_node_*) = %d ",sizeof(struct _demo_node_*)); printf("sizeof(unsigned long) = %d ",sizeof(unsigned long)); printf("sizeof(unsigned short) = %d ",sizeof(unsigned short)); printf("sizeof(demo_node) = %d ",sizeof(demo_node));
输出结果为
sizeof(struct _demo_node_*) = 8 sizeof(unsigned long) = 4 sizeof(unsigned short) = 2 sizeof(demo_node) = 22
分析可知,addr[0] 占用的空间为:22 - (8+8+4+2) = 0,验证了前面的说法。
2、变长数组的作用
满足需要变长度的结构体,让结构体的拓展变得十分灵活。
3、变长数组的用法
-
放在一个结构体的最后 ,申明一个长度为空的数组 变长数组名仅仅是一个符号,它不会占用任何空间,它在结构体中,只是代表了一个偏移量,是不可修改的地址常量。
下面看示例,可以直观的看出用法。
#include <stdio.h> #include <malloc.h> #include <string.h> #pragma pack(1) typedef struct _demo_node_{ struct _demo_node_* pprenode; struct _demo_node_* pnextnode; unsigned long member_num; unsigned short age; char addr[0]; }demo_node; #pragma pack() typedef struct { char province[8]; char city[8]; }address_info; int main(void) { demo_node* person = NULL; // 为demo_node结构体和address_info结构体分配内存 person = (demo_node*)malloc(sizeof(demo_node)+sizeof(address_info)); if(NULL == person) { printf("malloc demo_node failed "); return -1; } // person->addr是malloc分配的address_info内存的地址 address_info* personA_addr = NULL; personA_addr = (void*)&(person->addr); strcpy(personA_addr->province, "台湾"); strcpy(personA_addr->city, "台北"); address_info* personB_addr = NULL; personB_addr = (void*)&(person->addr); printf("personB的省份:%s ",personB_addr->province); printf("personB的城市:%s ", personB_addr->city); printf("person->addr的地址 = 0x%0x ", &(person->addr)); printf("personB_addr->province的地址 = 0x%0x ", &(personB_addr->province)); printf("personB_addr->city的地址 = 0x%0x ", &(personB_addr->city)); free(person); return 0; }
输出的结果为
personB的省份:台湾 personB的城市:台北 person->addr的地址 = 0x1d6f36 personB_addr->province的地址 = 0x1d6f36 personB_addr->city的地址 = 0x1d6f3e
本文的变长数组 addr[0],指向的是一个固定的结构体,相当于对demo_node结构体做了一个拓展。
其实变长数组还常用于网络通信中构造不定长的数据包,使用时,可根据数据的长度动态的开辟数据缓冲区,避免造成不必要的流量浪费。