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结构体做了一个拓展。

其实变长数组还常用于网络通信中构造不定长的数据包,使用时,可根据数据的长度动态的开辟数据缓冲区,避免造成不必要的流量浪费。

posted @ 2022-05-31 22:12  知微之见  阅读(784)  评论(0编辑  收藏  举报