IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 柔性数组详解 -> 正文阅读

[C++知识库]柔性数组详解

引言

#define MAXLEN 1024
typedef struct kd_node
{
	struct kd_node *left;
	struct kd_node *right;
	int dim;
	unsigned long long data[MAXLEN];
}kd_node;

在这段代码中,为了存储数据,申请了长度为1024的unsigned long long型数组,若是数据的长度远远小于MAXLEN,这样设计,及其浪费空间。
在C99标准中给出了新的设计方法,通过柔性数组可以解决这个问题。

struct sd_node
{
	int num;
	int size;
	char data[];//char data[0]
};

我们把数组的大小声明为0,或者不给出大小,称之为柔性数组。(全局数组和局部数组不能这样定义)。

概念

柔性数组是一种数组大小待定的数组。
在C语言中我们可以使用结构体产生柔性数组,结构体的最后一个元素可以是大小未知的数组。
在上面的结构体中,data仅仅是一个待使用的标识符,不占用内存空间,因此sizeof(struct sd_node) = 8;
用途:长度为零的数组的主要用途是为了满足长度可变的结构体。
用法:在结构体的最后,声明一个长度为0的数组,就可以使这个结构体是可变长的,对于编译器而言,长度为0的数组并不占用空间,因为数组名本身不占空间,它只是一个偏移量,数组名这个符号本身代表了一个不可修改的地址常量,但对于这个数组的大小,我们可以进行动态分配。
优点:比起结构体中声明一个指针变量、再进行动态分配的办法,这种方法效率更高。
缺点:在结构体中,数组为0的数组必须在最后声明,对设计结构体类型有一定的限制。

int main()
{
	struct sd_node *sp = (struct sd_node*)malloc(sizeof(struct sd_node) + 100);
	sp->num = 0;
	sp->size = 100;
	strcpy(sp->data,"tulunhello");
}

在这里插入图片描述
在这里插入图片描述

简单应用

假设我们在网络通信过程中使用的数据缓冲区,缓冲区包括num,size,data字段,分别标识数据的块号,长度,和传输的数据,我们有以下设计思路:
定长数据包
定长数据缓冲区,设置一个足够大小MAXSIZE的数据缓冲区。

#define MAXSIZE 4096
struct data buffer
{
	int num;
	int size;
	char data[MAXSIZE];
}

然而使用定长数组作为数据缓冲区,为了避免造成缓冲区溢出,数组设置就大开小用了,而实际使用过程中,达到MAXSIZE长度的数据很少。多数情况,缓冲区大部分都浪费了。
指针数据包

struct data buffer *pbuff = (struct data_buffer*)malloc(sizeof(struct data_buffer));
if(NULL == pbuff) exit(1);
pbuff->size = CURSIZE//发送数据的长度
pbuff->data = (char*)malloc(sizeof(char) * CURSIZE);
if(NULL == pbuff) exit(1);

使用指针结果作为缓冲区,多使用了一个指针大小的空间,不需要使用MAXSIZE长度的数组,不会造成空间的大量浪费,但是开辟空间时,需要额外开辟数据域空间。释放的时候也需要显示释放数据域的空间。但是我们在实际使用过程中,往往是在函数中开辟空间,然后返回给使用者指向struct point_buffer的指针,这时候我们并不能假定使用者了解我们开辟的细节,并按照约定的操作释放空间,甚至会造成内存泄漏。
变长数据缓冲区
柔性数组:既不会造成空间的浪费,使用的时候也只需要开辟一次空间。

struct data_buff
{
	int num;
	int size;
	char data[];//char data[0]
};
//使用的时候只需要开辟一次空间即可
int main()
{
	int n = strlen("hello") + 1;//数据长度
	struct data_buff *pbuff = (struct data_buff*)malloc(sizeof(struct data_buffer) + sizeof(char) * n);
	if(NULL == puff) exit(1);
	pbuff->num = 1;
	pbuff->size = n;
	memcpy(pbuff->data,"hello",n);
	free(pbuff);
	return 0;
}

说明

//只计算num大小,不计算柔性数组

struct Node_A
{
	int num;
	int data[];
};

struct Node_B
{
	int num;
	int data[3];
};


int main()
{
	struct Node_A ar = {8,{1,2,3,4,5,6,7,8}};
	struct Node_B br = {3,{1,2,3}};
	int sizea = sizeof(ar);
	int sizeb = sizeof(br);
	printf("%d %d\n",sizeof(ar),sizeof(br));
	printf("%d\n",ar.data[0]);
}

在这里插入图片描述

动态构建二维数组

int main()
{
	int row,col;
	int **ip = NULL;
	printf("input row col size: \n");
	scanf("%d %d",&row,&col);
	ip = (int**)malloc(sizeof(int*) * row);
	if(NULL == ip) exit(1);
	for(int i = 0;i < row;i++)
	{
		ip[i] = (int*)malloc(sizeof(int) * col);
		if(NULL == ip[i])
		{
			exit(1);
		}
	}
	for(int i = 0;i < row;i++)
	{

		for(int j = 0;j < col;j++)
		{
			ip[i][j] = i + j;
		}
	}
	for(int i = 0;i < row;i++)
	{

		for(int j = 0;j < col;j++)
		{
			printf("%5d",ip[i][j]);
		}
		printf("\n");
	}
	printf("\n");
	for(int i = 0;i < row;++i)
	{
		free(ip[i]);
		ip[i] = NULL;
	}
	free(ip);
	ip = NULL;

	return 0;
}

在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-02 16:34:44  更:2021-12-02 16:37:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:28:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码