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

今天在看一段代码时出现了用结构体实现变长数组的写法,一开始因为忘记了这种技术,所以老觉得作者的源码有误,最后经过我深思之后,终于想起以前看过的用struct实现变长数组的技术。下面是我在网上找到的一篇讲解很清楚的文章。

在实际的编程中,我们经常需要使用变长数组,但是C语言并不支持变长的数组。此时,我们可以使用结构体的方法实现C语言变长数组。

struct MyData { int nLen; char data[0];};

在结构中,data是一个数组名;但该数组没有元素;该数组的真实地址紧随结构体MyData之后,而这个地址就是结构体后面数据的地址(如果给这个结构体分配的内容大于这个结构体实际大小,后面多余的部分就是这个data的内容);这种声明方法可以巧妙的实现C语言里的数组扩展。

实际用时采取这样:

struct MyData *p = (struct MyData *)malloc(sizeof(struct MyData )+strlen(str)) 

这样就可以通过p->data 来操作这个str。

程序实例:

#include <iostream>
using namespace std;
struct MyData
{
 int nLen;
 char data[0];
};
int main()
{
 int nLen = 10;
 char str[10] = "123456789";
 cout << "Size of MyData: " << sizeof(MyData) << endl;
 MyData *myData = (MyData*)malloc(sizeof(MyData) + 10);
 memcpy(myData->data, str, 10);
 cout << "myData's Data is: " << myData->data << endl;
 free(myData);
 return 0;
}

输出:

Size of MyData: 4

myData"s Data is: 123456789

PS:必须将指针定义在struct的末尾,指针的类型也可以不为char。

以上这篇C语言变长数组 struct中char data[0]的用法详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • C语言中时间的基本用法小结

    前言 在我学的这些编程语言中,总是记不住它们的时间处理方式,每次用到时都要重新看,所以想着在这里记录下来,也方便用到时查找,也方便有需要的朋友们参考. time_t和struct tm 在C语言中用time_t类型表示一个时间,通常它是一个和long一样长的整数,也就是说,在32位环境下,它是4字节,在64位环境下,它是8字节.它保存的就是一个整数值,表示了从1970-01-01 08:00:00到其所表示时间的秒数,它是一个非负整数,所以,time_t无法表示早于1970-01-01 08:0

  • C语言 坐标移动详解及实例代码

    题目描述 开发一个坐标计算工具, A表示向左移动,D表示向右移动,W表示向上移动,S表示向下移动.从(0,0)点开始移动,从输入字符串里面读取一些坐标,并将最终输入结果输出到输出文件里面. 输入: 合法坐标为A(或者D或者W或者S) + 数字(两位以内) 坐标之间以;分隔. 非法坐标点需要进行丢弃.如AA10;  A1A;  $%$;  YAD; 等. 下面是一个简单的例子 如: A10;S20;W10;D30;X;A1A;B10A11;;A10; 处理过程: 起点(0,0) + A10 = (

  • C语言 数据结构之连续存储数组的算法

    数据结构之数组定义及基本操作 数据结构中最基本的一个结构就是线性结构,而线性结构又分为连续存储结构和离散存储结构.所谓的连续存储结构其实就是数组. 数组本质其实也是数据的一种存储方式,既然有了数据的存储,就会涉及到如何对数据进行寻址的问题.首先,先说一下在数组中数据是如何存储的,在内存中,数组中的数据是以一组连续的数据集合的形式存在于内存中.当我们访问存在于内存中的数组时,我们应该找到其在内存中的地址,当我们找到数据的地址后我们就可以找到对应的数据.了解了以上知识后,我们就可以进行数组的设计了(

  • 浅谈Linux C语言动态库及静态库

    假设在math目录下已编辑好add.c sub.c div.c mul.c func_point.c文件,func_point.c为包含main()的源文件! 动态库的制作: 方法一: gcc -c -fPIC add.c sub.c div.c mul.c //-c表示生成.o目标文件,-f后加一些编译选项,PIC表示与位置无关 gcc -shared -o libmymath.so add.o sub.o mul.o div.o//创建共享库mymath,添加add.o,sub.o,mul.

  • C语言 设计模式之访问者模式

    C语言访问者模式 概要: 访问者模式,听上去复杂一些.但是,这种模式用简单的一句话说,就是不同的人对不同的事物有不同的感觉.比如说吧,豆腐可以做成麻辣豆腐,也可以做成臭豆腐.可是,不同的地方的人未必都喜欢这两种豆腐.四川的朋友可能更喜欢辣豆腐,江浙的人就可能对臭豆腐更喜欢一些.那么,这种情况应该怎么用设计模式表达呢? typedef struct _Tofu { int type; void (*eat) (struct _Visitor* pVisitor, struct _Tofu* pTo

  • 详解C语言中的字符串拼接(堆与栈)

    首先来看一个demo: int do_sth(int type) { char *errstr; switch(type) { case 1: errstr = "Error";break case 2: errstr = "Warn";break case 3: errstr = "Info";break case 4: errstr = "Debug";break default: return 0; } if (...)

  • C语言 实现遍历一个文件夹的所有文件

    C语言 实现遍历一个文件夹的所有文件 最近学习C语言基础知识,有一个需求是需要遍历文件夹中的文件,对与这种很好实现,然后自己做了一个遍历所有文件的实现代码,做下记录: 实现代码: #include <stdio.h> #include <io.h> int main (void) { _finddata_t fileDir; long lfDir; if((lfDir = _findfirst(dir,&fileDir))==-1l) printf("No fil

  • C语言动态数组的使用实现代码

    C语言动态数组 从键盘读入n个整数,使用动态数组存储所读入的整数,并计算它们的和与平均值分别输出.要求尽可能使用函数实现程序代码.平均值为小数的只保留其整数部分. 样例输入: 5 3 4 0 0 2 样例输出: 9  1 样例输入: 7 3 2 7 5 2 9 1 样例输出: 29  4 代码如下: #include<stdio.h> int addAll(int a[],int N); int aveFun(int sum,int n); int main(){ int N; int sum

  • C语言基础 原码、反码、补码和移码详解

     原码.反码.补码.移码的作用? 在计算机内,机器数有无符号和带符号数之分.无符号数表示正数,在机器数中没有符号位.位于无符号数,若约定小数点的位置在机器数的最低位之后,则是纯整数:若约定小数点的位置在机器数的最高位之前,则是纯小数.对于带符号数,机器数的最高位是表示正.负的符号位,其余位则表示数值.若约定小数点的位置在机器数的最低数值位之后,则是纯整数:若约定小数点的位置在机器数的最高数值位之前(符号位之后),则是纯小数. 为了便于运算,带符号位的机器数可采用原码.反码和补码等不同的编码方法,

  • C语言 数据结构之中序二叉树实例详解

    C语言数据结构 中序二叉树 前言: 线索二叉树主要是为了解决查找结点的线性前驱与后继不方便的难题.它只增加了两个标志性域,就可以充分利用没有左或右孩子的结点的左右孩子的存储空间来存放该结点的线性前驱结点与线性后继结点.两个标志性域所占用的空间是极少的,所有充分利用了二叉链表中空闲存的储空间. 要实现线索二叉树,就必须定义二叉链表结点数据结构如下(定义请看代码): left leftTag data rightTag right 说明: 1.       leftTag=false时,表示left

随机推荐