C语言中动态分配数组

article/2025/10/3 14:33:51

很多人在编写C语言代码的时候很少使用动态数组,不管什么情况下通通使用静态数组的方法来解决,在当初学习C语言的时候我就是一个典型的例子,但是现在发现这是一个相当不好的习惯,甚至可能导致编写的程序出现一些致命的错误。尤其对于搞嵌入式的人来所,嵌入式系统的内存是宝贵的,内存是否高效率的使用往往意味着嵌入式设备是否高质量和高性能,所以高效的使用内存对我们来说是很重要的。那么我们在自己编写C语言代码的时候就应该学会使用动态数组,这也就是我这篇博客要给大家讲的,我尽我所能的用一些简单的代码来讲解动态数组,希望我所讲的对你有所帮助。

那么我们首先来看看什么是动态数组,动态数组是相对于静态数组而言,从“动”字我们也可以看出它的灵活性,静态数组的长度是预先定义好的,在整个程序中,一旦给定大小后就无法改变。而动态数组则不然,它可以随程序需要而重新指定大小。动态数组的内存空间是从堆动态分配的。是通过执行代码而为其分配存储空间。当程序执行到我们编写的分配语句时,才为其分配。对于静态数组,其创建非常方便,使用完也无需释放,要引用也简单,但是创建后无法改变其大小是其致命弱点!对于动态数组,其创建麻烦,使用完必须由程序员自己释放,否则将会引起内存泄露。但其使用非常灵活,能根据程序需要动态分配大小。所以相对于静态数组的来说我们对于使用动态数组有很大的自由度。

在创建动态数组的过程中我们要遵循一个原则,那就是在创建的时候从外层往里层,逐层创建;而释放的时候从里层往外层,逐层释放。这个话你读了可能理解并不深刻,不过不要急,接下来我们看看两段代码。

一维动态数组的创建:

#include <stdio.h>
#include <stdlib.h>
int main()
{
int n1,i;
int *array;
printf("请输入所要创建的一维动态数组的长度:");
scanf("%d",&n1);
array=(int*)calloc(n1,sizeof(int));
for(i=0;i<n1;i++)
{printf("%d\t",array[i]);
}
printf("\n");
for(i=0;i<n1;i++)
{array[i]=i+1;printf("%d\t",array[i]);
}free(array);//释放第一维指针 
return 0;
}

运行结果为:

 

二维数组的创建:

#include <iostream>
#include <stdlib.h>
using namespace std;int main(){int num1,num2;cout<<"请输入动态二维数组的第一个维度:";cin>>num1;cout<<"请输入动态二维数组的第二个维度:";cin>>num2;int **array = (int **)calloc(num1,sizeof(int));for(int i=0;i<num1;i++) {array[i] = (int*)calloc(num2,sizeof(int));}for(int i=0;i<num1;i++){for(int j=0;j<num2;j++){array[i][j] =i*num2+j+1;printf("%d\t",array[i][j]);}cout<<endl;}for(int i=0;i<num1;i++)	free(array[i]);free(array);return 0;
}

运行结果为:

 请输入所要创建的动态数组的第一维长度:3
请输入所要创建的动态数组的第二维长度:3
1       2       3
4       5       6
7       8       9
Press any key to continue

有了上面的代码我们再来说动态数组的建立就简单了,以二维为例,先说创建,还记得我们上面说的创建的原则嘛:从外层往里层,逐层创建。

array=(int**)malloc(n1*sizeof(int*)); //第一维

以上是我们创建二维动态数组的最外层,创建好了最外层那么我们接下来就是要创建次外层了。这里使用了二级指针。

array[i]=(int*)malloc(n2* sizeof(int));//第二维

在创建次外层的过程中我们使用了一个for语句,千万别忘了使用for循环语句,这是绝大多数人的一个易错点。

创建好了接下来我们该讲到释放了,而释放的时候从里层往外层,逐层释放。刚刚与我们上面的创建相反,在以上代码中我们首先使用了下面一个for循环来释放里层。

for(i=0;i<n1;i++) 

free(array[i]);//释放第二维指针 
}

在通过以下语句来释放外层。
free(array);//释放第一维指针

如果出现多维的情况怎么做呢,我们接下来再来看看一个三维动态数组的创建和释放,以加深下读者的印象。代码如下:

#include <stdlib.h> 
#include <stdio.h> 
int main() 
{ 
int n1,n2,n3; 
int ***array; 
int i,j,k; 
printf("请输入所要创建的动态数组的第一维长度:");
scanf("%d",&n1); 
printf("请输入所要创建的动态数组的第二维长度:");
scanf("%d",&n2); 
printf("请输入所要创建的动态数组的第三维长度:");
scanf("%d",&n3); 
array=(int***)malloc(n1*sizeof(int**));//第一维 
for(i=0; i<n1; i++) 
{ 
array[i]=(int**)malloc(n2*sizeof(int*)); //第二维 
for(j=0;j<n2;j++) 
{ 
array[i][j]=(int*)malloc(n3*sizeof(int)); //第三维 
} 
} 
for(i=0;i<n1;i++)
{
for(j=0;j<n2;j++)
{
for(k=0;k<n3;k++) 
{ 
array[i][j][k]=i+j+k+1; 
printf("%d\t",array[i][j][k]); 
} 
printf("\n");
}
printf("\n");
}
for(i=0;i<n1;i++) 
{ 
for(j=0;j<n2;j++) 
{ 
free(array[i][j]);//释放第三维指针 
} 
} 
for(i=0;i<n1;i++) 
{ 
free(array[i]);//释放第二维指针 
} 
free(array);//释放第一维指针 
return 0; 
}

运行结果为:

请输入所要创建的动态数组的第一维长度:3
请输入所要创建的动态数组的第二维长度:3
请输入所要创建的动态数组的第三维长度:3
1       2       3
2       3       4
3       4       5

2       3       4
3       4       5
4       5       6

3       4       5
4       5       6
5       6       7

Press any key to continue

看了以上三维动态数组的创建和释放代码以后,我想读者这个时候已经可以自己编写任意维的动态数组了。但是细心的读者可能发现了一个问题,那就是我们所讲的动态数组都是一次性创建好的,如果接下来在使用的过程中我们使用的数组需要扩展或者删减一些不再使用元素该怎么办呢?!接下来我们先看一段关于动态数组扩展的代码,在此以一维动态数组的扩展为例,其它的以此类推。

#include <stdio.h>
#include <stdlib.h>
int main()
{
int*n,*p;
int i,n1,n2;
printf("请输入所要创建的动态数组的长度:");
scanf("%d",&n1); 
n=(int*)calloc(n1,sizeof(int));
printf("请输入所要扩展的动态数组的长度:");
scanf("%d",&n2); 
p=(int*)realloc(n,(n2)*sizeof(int));//动态扩充数组
for(i=0;i<n2;i++)
{
p[i]=i+1;
if(i%5==0)
printf("\n");
printf("%d\t",p[i]);
}
free(p);
return 0;
}

运行结果如下:

请输入所要创建的动态数组的长度:6
请输入所要扩展的动态数组的长度:25

1       2       3       4       5
6       7       8       9       10
11      12      13      14      15
16      17      18      19      20
21      22      23      24      25      Press any key to continue

 

接下来如何缩小动态数组。

#include <stdio.h>
#include <stdlib.h>
int main()
{
int*n,*p;
int i,n1,n2;
printf("请输入所要创建的动态数组的长度:");
scanf("%d",&n1); 
n=(int*)calloc(n1,sizeof(int));
for(i=0;i<n1;i++)
{
n[i]=i+1;
if(i%5==0)
printf("\n");
printf("%d\t",n[i]);
}
printf("\n请输入所要缩小的动态数组的长度:");
scanf("%d",&n2); 
p=(int*)realloc(n,(n2)*sizeof(int));
for(i=0;i<n2;i++)
{
if(i%5==0)
printf("\n");
printf("%d\t",p[i]);
}
printf("\n");
free(p);
return 0;
}

运行结果为:

请输入所要创建的动态数组的长度:25

1       2       3       4       5
6       7       8       9       10
11      12      13      14      15
16      17      18      19      20
21      22      23      24      25
请输入所要缩小的动态数组的长度:15

1       2       3       4       5
6       7       8       9       10
11      12      13      14      15
Press any key to continue

在这里值得注意的一点就是在缩减动态数组的时候,它是删除了后面的元素,而前面的元素保持不变。在使用realloc()函数的时候要由其注意它的使用规则。

 

讲到这儿就到了该说结束的时候了,由于本人水平有限,博客中的不妥或错误之处在所难免,殷切希望读者批评指正。同时也欢迎读者共同探讨相关的内容,如果乐意交流的话请留下你宝贵的意见。


http://chatgpt.dhexx.cn/article/sbhAyVuK.shtml

相关文章

C语言学习笔记:动态数组

动态数组 数组是C语言中的很重要的一种构造类型&#xff0c;最初我们学习的都是静态数组&#xff0c;但是&#xff0c;静态数组有着自己难以改变的缺点——数组长度固定。 一般在静态数组定义后&#xff0c;系统就会为其分配对应长度的连续的专有内存空间&#xff0c;可是&am…

C语言如何实现动态数组?

提出问题 请问在c语言里如何实现动态大小的数组啊&#xff0c;比如说int a[N];&#xff0c;这里N的值可以在程序中定&#xff0c;或者有什么方法可以实现类似的功能&#xff1f;总之只要在编译时不用制定数组大小就行。 分析问题 嵌入式系统的内存是宝贵的&#xff0c;内存是否…

C的动态数组的详细知识(网上收集到的大量详细知识以及个人理解的汇总)

动态数组是指在声明时没有确定数组大小的数组&#xff0c;即忽略圆括号中的下标&#xff1b;当要用它时&#xff0c;可随时用ReDim语句重新指出数组的大小。使用动态数组的优点是可以根据用户需要&#xff0c;有效利用存储空间。 可以了解动态数组的详细定义 一.C版本动态数组…

动态数组C语言实现详解

目录 0、前言 一、动态数组数据结构 二、动态数组增删改查函数声明 三、数组创建 1、头部动态创建 2、头部静态创建 四、元素添加 五、元素删除 1、根据元素值删除 2、根据元素位置删除 六、元素修改 七、元素查找 八、数组清空 九、数组销毁 十、验证程序 0、前…

C语言实现 动态数组 处理任意类型数据

引言&#xff1a;动态数组在C/C、Java、Python等语言中应用广泛&#xff0c;高级语言一般通过调用类或接口等可以快捷使用&#xff0c;C语言实现动态数组需要手动构造&#xff0c;以下为实现过程。 1 结构体构造动态数组 typedef struct Array {void **p; //维护在堆区…

C语言创建动态数组

C语言创建动态数组 1.编写步骤 1. 添加所需头文件 stdlib.h 该头文件下包含的与分配存储区相关的函数如下&#xff1a; void* malloc (size_t size);//从堆中分配size字节的存储空间 void* calloc (size_t num, size_t size);//分配数组并将数组零初始化。为 num 个元素的数…

在OpenCV里实现开运算

前面学习腐蚀和膨胀算法,并且深刻地认识到它们的特性以及作用。如果由这两种组合出来的运算又有什么样的不同呢?比如一个图像先腐蚀后膨胀的操作,会有什么结果呢?因为腐蚀是把图片白色变小,膨胀又是把图片白色变大,是否会保持原图不变呢?带着这些问题来研究一下先腐蚀后…

OpenCV python 形态学 圆形开运算

处理流程 # -*- coding: utf-8 -*- # note : 形态学 开运算 圆形内核 处理 # --------------------------------import cv2 as cv import numpy as npdef opening_circle(img_bin, kernel_size10):# 形态学kernel np.zeros((kernel_size, kernel_size), np.uint8)center_…

腐蚀、膨胀、开运算、闭运算

一、腐蚀、膨胀、开运算、闭运算 腐蚀&#xff1a;图像中的高亮部分进行膨胀 膨胀&#xff1a;原图中的高亮部分被腐蚀&#xff0c;类似于领域被蚕食 开运算&#xff1a;先腐蚀再膨胀&#xff0c;可以去掉目标外孤立的点 闭运算&#xff1a;先膨胀再腐蚀&#xff0c;可以去掉目…

【youcans 的 OpenCV 例程200篇】137. 灰度开运算和灰度闭运算原理

欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列&#xff0c;持续更新中 欢迎关注 『youcans 的 OpenCV学习课』 系列&#xff0c;持续更新中 【youcans 的 OpenCV 例程200篇】137. 灰度开运算和灰度闭运算 5. 灰度级形态学 灰度级形态学将形态学操作从二值图像扩展到灰度图…

开闭运算

开运算和闭运算是将腐蚀和膨胀按照一定的次序进行处理。但这两者并不是可逆的&#xff0c;即先开后闭并不能得到原来的图像。 开运算 开运算是先腐蚀后膨胀&#xff0c;其作用是&#xff1a;分离物体&#xff0c;消除小区域。特点&#xff1a;消除噪点&#xff0c;去除小的干扰…

图像的形态学开操作(开运算)和闭操作(闭运算)的概念和作用,并用OpenCV的函数morphologyEx()实现对图像的开闭操作

大家看这篇博文前可以先看一看下面这篇博文&#xff0c;下面这篇博文是这篇博文的基础&#xff1a; 详解图像形态学操作之图形的腐蚀和膨胀的概念和运算过程,并利用OpenCV的函数erode()和函数dilate()对图像进行腐蚀和膨胀操作 图像形态学腐蚀可以将细小的噪声区域去除&#x…

OpenCV-Python图像运算变换处理:开运算和闭运算以及不同核矩阵的影响分析

☞ ░ 前往老猿Python博客 https://blog.csdn.net/LaoYuanPython ░ 一、引言 在《OpenCV-Python图像处理&#xff1a;腐蚀和膨胀原理及erode、dilate函数介绍 https://blog.csdn.net/LaoYuanPython/article/details/109441709》等系列博文中老猿详细介绍了腐蚀和膨胀的原理、…

灰度级形态学 - 灰度开运算和灰度闭运算

目录 1. 介绍 2. code 1. 介绍 灰度级的开运算和闭运算和二值图像的处理一样&#xff0c;只不过一个作用于灰度图&#xff0c;一个作用于二值图像 灰度级的开运算公式为&#xff1a; 先对图像做腐蚀&#xff0c;然后对腐蚀的结果做膨胀运算 灰度级的闭运算公式为&#xff…

OpenCV(七)形态学操作2--开运算与闭运算

目录 概述&#xff1a; morphologyEX()函数 一、开运算&#xff08;分开&#xff09; 1、基础理论 1、作用&#xff1a; 2、代码 3、效果 二、闭运算&#xff08;封闭&#xff09; 1、基础理论 1、作用 2、过程 2、代码 3、效果 总代码 参考资料&#xff1a; 概述…

开运算—闭运算

转载&#xff1a;https://blog.csdn.net/hanshanbuleng/article/details/80657148 如果不了解腐蚀与膨胀原理的同学那请看我前一期博客哦&#xff01;&#xff09; 1.开运算 开运算 先腐蚀运算&#xff0c;再膨胀运算&#xff08;看上去把细微连在一起的两块目标分开了&…

Halcon形态学处理-腐蚀、膨胀、开运算、闭运算、顶帽运算和底帽运算

提示&#xff1a;文章参考了网络上其他作者的文章&#xff0c;以及相关书籍&#xff0c;如有侵权&#xff0c;请联系作者。 文章目录 前言一、腐蚀和膨胀1.腐蚀2.膨胀 二、开运算和闭运算1.开运算2.闭运算 三、顶帽运算和底帽运算1.顶帽运算2.底帽运算 总结参考文献 前言 图像的…

Opencv中的开运算和闭运算操作讲解(python实现)

文章目录 1.首先了解腐蚀和膨胀原理2.开运算&#xff08;1&#xff09;为什么开运算可以去白噪点呢&#xff1f;&#xff08;2&#xff09;.函数讲解&#xff08;3&#xff09;代码实战 3.闭运算&#xff08;1&#xff09;函数讲解&#xff08;2&#xff09;代码实战 1.首先了解…

膨胀 腐蚀 开运算 闭运算 matlab,11. 形态学膨胀、腐蚀、开运算、闭运算

1. 膨胀:对边界点进行扩充,填充空洞,使边界向外部扩张的过程。 2. 腐蚀:消除物体边界点,使边界向内部收缩的过程,把小于结构元素的物体去除掉。 3. 开运算: 先腐蚀后膨胀的过程称为开运算,作用:去除孤立的小点,毛刺,消除小物体,平滑较大物体边界,同时不改变其面积。 4. 闭…

开运算、闭运算及其所用

1.开运算 开运算 先腐蚀运算&#xff0c;再膨胀运算&#xff08;看上去把细微连在一起的两块目标分开了&#xff09; 开运算的效果图如下图所示&#xff1a; 开运算总结&#xff1a; &#xff08;&#xff11;&#xff09;开运算能够除去孤立的小点&#xff0c;毛刺和小桥&…