C语言柔性数组讲解
#include<stdio.h>
typedef struct _SoftArray{
int len;
int array[];
}SoftArray; int main()
{
int len = ; printf("The struct's size is %d\n",sizeof(SoftArray));
}

我们可以看出,_SoftArray结构体的大小是4,显然,在32位操作系统下一个int型变量大小刚好为4,也就说结构体中的数组没有占用内存。为什么会没有占用内
存,我们平时用数组时不时都要明确指明数组大小的吗?但这里却可以编译通过呢?这就是我们常说的动态数组,也就是柔性数组。
先不要乱,让我们再看一段代码
#include<stdio.h>
#include<malloc.h> typedef struct _SoftArray{
int len;
int array[];
}SoftArray; int main()
{
int len = ; SoftArray *p=(SoftArray*)malloc(sizeof(SoftArray) + sizeof(int)*len);
printf("After the malloc function the struct's size is %d\n”,sizeof(SoftArray)); return ;
}

是不是有点奇怪,为什么申请了内存后结构体大小还是4呢?原因是动态申请的内存只是申请给数组拓展所用,从上个程序我们可以看出结构体的大小在创建时已经
确定了,array明确来说不算是结构体成员,只是挂羊头卖狗肉而已。
下面我们来看看关于柔性数组的资料:
1、什么是柔性数组?
柔性数组既数组大小待定的数组, C语言中结构体的最后一个元素可以是大小未知的数组,也就是所谓的0长度,所以我们可以用结构体来创建柔性数组。
2、柔性数组有什么用途 ?
它的主要用途是为了满足需要变长度的结构体,为了解决使用数组时内存的冗余和数组的越界问题。
3、用法 :在一个结构体的最后 ,申明一个长度为空的数组,就可以使得这个结构体是可变长的。对于编译器来说,此时长度为0的数组并不占用空间,因为数组名
本身不占空间,它只是一个偏移量, 数组名这个符号本身代 表了一个不可修改的地址常量 (注意:数组名永远都不会是指针! ),但对于这个数组的大小,我们
可以进行动态分配,对于编译器而言,数组名仅仅是一个符号,它不会占用任何空间,它在结构体中,只是代表了一个偏移量,代表一个不可修改的地址常量!
对于柔性数组的这个特点,很容易构造出变成结构体,如缓冲区,数据包等等:
typedef struct _SoftArray
{
Int len;
int array[];
}SoftArray;
这样的变长数组常用于网络通信中构造不定长数据包,不会浪费空间浪费网络流量,比如我要发送1024字节的数据,如果用定长包,假设定长包的长度为2048,就
会浪费1024个字节的空间,也会造成不必要的流量浪费。
4、举个简单是实例
#include<stdio.h>
#include<malloc.h>
typedef struct _SoftArray{
int len;
int array[];
}SoftArray;
int main()
{
int len=,i=; SoftArray *p=(SoftArray*)malloc(sizeof(SoftArray)+sizeof(int)*len);
p->len=len; for(i=;i<p->len;i++)
{
p->array[i]=i+;
}
for(i=;i<p->len;i++)
{
printf("%d\n",p->array[i]);
} free(p); return ;
}

这代码的作用是用柔性数组动态创建数组并输出数组内容,这里我就直接解释解释这两句代码
SoftArray* p = (SoftArray*)malloc(sizeof(SoftArray) + sizeof(int) *10);
p->len = 10;
第一句,主要是根据你要定义的数组长度和数据类型以及柔性数组本身的大小来开辟一块内存空间给柔性数组,第二个是定义len的长度,便于确定循环打印输出
是循环的次数。
5、运行错误的解决
#include<stdio.h>
#include<malloc.h>
typedef struct _SoftArray{
int len;
int array[];
}SoftArray;
int main()
{
int len=,i=; SoftArray *p=(SoftArray*)malloc(sizeof(SoftArray)+sizeof(int)*len);
p->len=len; for(i=;i<;i++)
{
p->array[i]=i+;
}
for(i=;i<;i++)
{
printf("%d\n",p->array[i]);
} free(p); return ;
}
我当时不知道是什么问题,我也蒙了~---~
但我又做出了一个伟大的决定,我把free(p)注释掉了,结果11成功打印出来了。我当时真是One Face mengbi。

6、注意说明
在定义这个结构体的时候,模子的大小就C89不支持这种东西,C99把它作为一种特例加入了标准。
但是,C99所支持的是 incomplete type,而不是 zero array,形同 int item[0];这种形式是非法的,C99支持的形式是形同 int item[];只不过有些编译器把 int item[0];作
为非标准扩展来支持,而且在C99发布之前已经有了这种非标准扩展了,C99发布之后,有些编译器把两者合而为一了。当然,上面既然用 malloc函数分配了内存,
肯定就需要用 free函数来释放内存:free(p);这两个函数是一对CP,就好像fopen()和fclose();记住不要乱拆CP,拆CP是有风险的哦。
最后再送大家一个代码玩玩:
#include<stdio.h>
#include<malloc.h>
typedef struct _SoftArray{
int len;
int array[];
}SoftArray; //打印输出斐波那契数列
void printfln(SoftArray *p,int len)
{
int i; for(i=;i<len;i++) //循环进行打印输出
{
printf("%d\n",p->array[i]);
}
} //动态生成斐波那契数列
void create(int len)
{
int i; SoftArray * p=(SoftArray*)malloc(sizeof(SoftArray)+sizeof(int)*len); //声明结构体指针p,动态申请内存,大小为结构体大小+10个int型大小 for(i=;i<len;i++) //循环进行数组赋值
{
if( i <= )
{
p->array[i] = ;
}else if( i >= )
{
p->array[i] = p->array[i-] + p->array[i-];
}else
{
printf("DAMAGE: before Normal block or after Normal block");
return (-);
} }
printfln(p,len); free(p);
} //主函数
int main()
{
int i=;
int len; printf("请输入生成斐波那契数列的行数:");
scanf("%d",&len); create(len); return ;
}
C语言柔性数组讲解的更多相关文章
- C语言柔性数组
结构中最后一个元素允许是未知大小的数组,这个数组就是柔性数组.但结构中的柔性数组前面必须至少一个其他成员,柔性数组成员允许结构中包含一个大小可变的数组,sizeof返回的这种结构大小不包括柔性数组的内 ...
- C语言柔性数组和动态数组
[前言]经常看到C语言里的两个数组,总结一下. 一.柔性数组 参考:https://www.cnblogs.com/veis/p/7073076.html #include<stdio.h> ...
- (四)C语言柔性数组、指针赋值
一.柔性数组 今天看了公司的代码,发现一个很奇怪的问题,后来自己写了类似代码,我先把代码贴出来吧. #include<stdio.h> #include<string.h> # ...
- 第二十三节:Java语言基础-详细讲解函数与数组
函数 函数在Java中称为方法,在其他语言中可能称为函数,函数,方法就是定义在类中具有特定功能的程序.函数,在Java中可称为方法. 函数的格式: 修饰符 返回值类型 函数名(参数类型 参数1, 参数 ...
- C语言的柔性数组的实现及应用
c编程的时候数组长度一般都是固定好的,实际上c还能实现变长数组.其实c99中确实是有变长数组的说法,C99中通过允许结构体中的最后一个成员是长度未知的数组实现变长数组,其定义格式如下: typedef ...
- C语言0长度数组(柔性数组)
0长度数组,又称为柔性数组(flexible array).通经常使用来实现变长数组.常见于TLV(type-length-value)的数据结构中. 在标准 C 和 C++ 中,不同意用 0 长度数 ...
- 深入浅出C语言中的柔性数组
在日常的编程中,有时候需要在结构体中存放一个长度动态的字符串,一般的做法,是在结构体中定义一个指针成员,这个指针成员指向该字符串所在的动态内存空间,例如: typedef struct test { ...
- C语言字符数组超细讲解
看到标题,有不少朋友会想:字符数组不也是数组吗?为什么要单独拿出来讲哩?莫非它是朵奇葩? 哈哈,确实,一起来认识一下这朵数组界的奇葩吧! 一.字符数组的定义.引用.初始化 大家好!我是字符数组,看我的 ...
- C柔性数组
柔性数组成员 柔性数组 .允许结构中包含一个大小可变的数组,sizeof返回的这种结构大小不包括柔性数组的内存. .包含柔性数组成员的结构要使用malloc()函数进行内存的动态分配.分配的内存大于结 ...
随机推荐
- 查看文件状态与跟踪新文件(git status/add)
查看当前文件状态 使用git status查看文件状态,如果是空仓库,执行结果如下 $ git status On branch master No commits yet nothing to co ...
- parallels desktop for mac安装虚拟机 之parallelsdesktop密钥 以及 parallels desktop安装win10的办公推荐可以提高办公效率
大家好我是一个老程序员了. 用惯了 mac , 平时工作都是在 mac安装虚拟机,之后就是mac 安装 win10. 因为很多办公软件 mac 都不好用,主要是跟同事沟通不方便,当然mac 的软件还 ...
- 20175306 MyCP博客总结
课后必做题:MyCP总结 cp命令了解: · 作用:cp指令用于复制文件或目录,如同时指定两个以上的文件或目录,且最后的目的地是一个已经存在的目录,则它会把前面指定的所有文件或目录复制到此目录中.若同 ...
- LeetCode第十六题-找出数组中三数之和最接近目标值的答案
3Sum Closest 问题简介: 给定n个整数的数组nums和整数目标,在nums中找到三个整数,使得总和最接近目标,返回三个整数的总和,可以假设每个输入都只有一个解决方案 举例: 给定数组:nu ...
- git本机服务器配置(二):TortoiseGit的安装
1. 下载TortoiseGit https://tortoisegit.org/ 1.1 下载安装包 下载对应安装包,如果不知道自己该下载哪个,那就下载32位的. 1.2 下载语言包 下载和安装包相 ...
- Hutool工具里,POST方法,body中传参的几种调用方法
接口说明: POSTMAN测试: JAVA代码: package com.provy.guard.api; import java.util.HashMap; import java.util.Map ...
- 题解 P3246 【[HNOI2016]序列】
很久之前做过这道题,但是跑得贼慢,现在用了可以被卡成 n m 的笛卡尔树做法,发现跑得贼快[雾 noteskey 介绍一种复杂度错误然鹅在随机数据下跑得贼快的算法: 笛卡尔树 方法就是 \(O~ n\ ...
- 51nod1236 序列求和 V3
这题炒鸡简单,只要第一步想对了后面顺风顺水QWQ(然鹅我没想到) 前置芝士: 斐波那契数列通项公式 等比数列求和公式 二项式定理 这题要求的就是 \(\sum_{i=1}^n Fib(i)^k\) , ...
- ftp和mysql数据库结合使用
问题描述: 看下 1.1.1.1 的ftp为什么连不上 报错的信息: 'ftpServer' => '1.1.1.1', // FTP服务器地址 ', 'ftpUsername' => ' ...
- Linux 用户组
文件权限 r w x 文件时的权限介绍 r 可读 可以使用 cat.less等命令 w 可写 可以编辑,删除此文件 x 可执行 可以命令行模式下提交给内核运行此命令 当时目录时 r 可以使用ls列出 ...