在我的《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. SV概述

    System Verilog概述 路科验证视频,B站可看(补充一下知识) 学习SV之前,最好有Verilog基础 SV诞生 SV发展历史 Verilog - 偏向于设计 System Verilog ...

  2. Java - 输出空心菱形

    1. 思路:发现菱形的规律 ,定义三个变量,左边距和右边距,中间的边距 .   具体规律观察上图  . 2.上代码: //输出空心菱形 public class ForToLingXing { pub ...

  3. SpringMVC05——SSM整合

    整合SSM 需求:熟练掌握MySQL数据库,Spring,JavaWeb及MyBatis知识,简单的前端知识 CREATE DATABASE `ssmbuild`; USE `ssmbuild`; D ...

  4. [转帖]CentOS 8已经停止维护,怎么检查CentOS的版本

    https://rumenz.com/rumenbiji/centos-check-version.html CentOS 8 在2021年12月31日停止更新并停止维护(EOL). CentOS 7 ...

  5. [转帖]CentOS-7-x86_64-DVD-2009 rpm包列表(centos7.9)

    https://www.cnblogs.com/hiyang/p/14803391.html 文件数 4071 个,共3.8G 复制389-ds-base-1.3.10.2-6.el7.x86_64. ...

  6. [转帖] Linux命令拾遗-查看系统信息

    https://www.cnblogs.com/codelogs/p/16060714.html 简介# 作为一名程序员,有时需要关注自己的进程运行在什么样的软硬件环境里,比如几核cpu.固态硬盘还是 ...

  7. 【转帖】【笔记】python连接神通数据库

    https://www.cnblogs.com/wyongbo/p/17054924.html python连接国产神州通用数据库. 一.准备 下载whl及dll: 链接: https://pan.b ...

  8. [转帖]Skywalking学习及整合springboot

    目录 1. Skywalking概述 2. Skywalking主要功能 3. Skywalking主要特性 4. Skywalking架构简介 5. Spring Cloud与Skywalking实 ...

  9. iptables 命令学习

    iptables 命令学习 摘要 Linux 早起版本使用netfilter进行数据包过滤. 最新的版本开始改用 ebpf的方式进行内核编程式的包过滤. netfilter 可以理解为内核态的一个处理 ...

  10. 总结: Redis 查看key大小的简单总结

    Redis 查看key大小的简单总结 第一步: 安装rdbtools 吐槽一下 python 非常不熟悉 第一步 安装epel以及python等工具 yum install epel-release ...