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