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

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

C语言,变长数组的用法的更多相关文章

  1. C语言变长数组 struct中char data[0]的用法

    版权声明:本文为博主原创文章,未经博主允许不得转载. 今天在看一段代码时出现了用结构体实现变长数组的写法,一开始因为忘记了这种技术,所以老觉得作者的源码有误,最后经过我深思之后,终于想起以前看过的用s ...

  2. C语言变长数组data[0]总结

    C语言变长数组data[0] 1.前言 今天在看代码中遇到一个结构中包含char data[0],第一次见到时感觉很奇怪,数组的长度怎么可以为零呢?于是上网搜索一下这样的用法的目的,发现在linux内 ...

  3. C语言变长数组data[0]

    1.前言 在刷题时遇到一个结构中包含char data[0],第一次见到时感觉很奇怪,数组的长度怎么可以为零呢?于是上网搜索一下这样的用法的目的,发现在linux内核中,结构体中经常用到data[0] ...

  4. C语言变长数组data[0]【总结】

    1.前言 今天在看代码中遇到一个结构中包含char data[0],第一次见到时感觉很奇怪,数组的长度怎么可以为零呢?于是上网搜索一下这样的用法的目的,发现在linux内核中,结构体中经常用到data ...

  5. C语言变长数组

    #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Variable ...

  6. c语言,变长数组

    下面这个结构体,可以在malloc的时候指定数据data的长度,这样的形式就是变长数组:typedef struct{ int data_len; char data[0];//或char data[ ...

  7. 《OOC》笔记(3)——C语言变长参数va_list的用法

    <OOC>笔记(3)——C语言变长参数va_list的用法 C语言中赫赫有名的printf函数,能够接受的参数数目不固定,这就是变长参数.C#里也有params这个关键字用来实现变长参数. ...

  8. GCC 中零长数组与变长数组

    前两天看程序,发现在某个函数中有下面这段程序: int n; //define a variable n int array[n]; //define an array with length n 在 ...

  9. C++内存分配及变长数组的动态分配

    //------------------------------------------------------------------------------------------------ 第 ...

  10. PL/SQL 嵌套表变长数组和索引表[转]

    关于PL/SQL中这三种数组的介绍,不想写了.转一篇日志吧…… 链接:http://www.blogjava.net/decode360/archive/2008/08/08/280825.html ...

随机推荐

  1. [转帖]Nginx反向代理中使用proxy_redirect重定向url

    https://www.cnblogs.com/kevingrace/p/8073646.html 在使用Nginx做反向代理功能时,有时会出现重定向的url不是我们想要的url,这时候就可以使用pr ...

  2. [转帖]Linux下strace调试系统应用参数总结(附实例操作讲解)

    文章目录 一.简介 二.常用参数详解 三.实例详解 3.1 跟踪具体进程 3.2 监控具体程序执行过程 四.其他相关知识链接 一.简介 strace命令是一个集诊断.调试.统计与一体的Linux 用户 ...

  3. [转帖]Tail Latency学习

    https://www.cnblogs.com/Rohn/p/15123758.html Latency,中文译作延迟,Tail Latency即尾延迟. 实际生产中的Latency是一种(概率)分布 ...

  4. [转帖]50年来Intel CPU变化有多大?频率从0.75MHz提升到5.2GHz

    https://m.baidu.com/bh/m/detail/ar_9297450181050583423?data_from=lemon 今天(11月15日)是Intel推出4004处理器50周年 ...

  5. 国产CPU制造工艺与部分性能总结

    国产CPU制造工艺与部分性能总结 背景 最近一段时间验证了很多国产CPU的性能. 感觉很多地方与之前的理解有一些偏差. 前几天总结了部分架构和指令集相关的差异 今天想着总结一下制造相关的部分. 希望能 ...

  6. OpenSSH 9.2P1升级以及版本显示的处理过程

    说明 本次维护的时间是 2023-2-9 最新已发布的补丁是 OpenSSH9.2P1版本 其他本本应该是类似处理. 下载介质 在 OpenSSH官网打开相关界面. http://www.openss ...

  7. Nginx的Keepalive的简单学习

    摘要 最近发现某项目的Nginx负载服务器上面有很多Time_wait的TCP连接 可以使用命令 netstat -n |awk '/^tcp/ {++S[$NF]} END{for (a in S) ...

  8. AIGC的隐私安全问题及隐私保护技术

    作者:京东科技 杨博 ChatGPT 才出现两个月,就已经引起了学术界的关注.微软成为ChatGPT母公司OpenAI的合作伙伴,并确认投资百亿美元.同时,微软正计划将 OpenAI 的技术整合到其产 ...

  9. vuex中action中发送数据

    state: { actionData: "", }, mutations: { actioncomAPi: (state, data) => { state.actionD ...

  10. 【JS 逆向百例】网洛者反爬练习平台第五题:控制台反调试

    关注微信公众号:K哥爬虫,持续分享爬虫进阶.JS/安卓逆向等技术干货! 声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后 ...