C语言中动态分配数组

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

大家好,又见面了,我是你们的朋友全栈君。

很多人在编写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;
}

运行结果为:

C语言中动态分配数组

 

二维数组的创建:

#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;
}

运行结果为:

C语言中动态分配数组

 请输入所要创建的动态数组的第一维长度: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; 
}

运行结果为:

C语言中动态分配数组

请输入所要创建的动态数组的第一维长度: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;
}

运行结果如下:

C语言中动态分配数组

请输入所要创建的动态数组的长度: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;
}

运行结果为:

C语言中动态分配数组

请输入所要创建的动态数组的长度: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()函数的时候要由其注意它的使用规则。

 

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/162990.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • A股管家股票自动交易软件系统,功能完善强大[通俗易懂]

    A股管家股票自动交易软件系统,功能完善强大[通俗易懂]                                    2013年的时候,有个广东的朋友说再用这款A股管家股票自动系统,我当时比较惊讶,以前想过要是有一款股票自动交易软件能偶尔代替我一下就好了,虽然是职业股民,但也经常遇到太忙的时候,实在没时间。然后就在朋友的推荐下,弄了一套试试,印象非常深刻,当天设了600…

  • nginx配置ssl证书实现https访问_ssl证书有效期

    nginx配置ssl证书实现https访问_ssl证书有效期1,登录阿里云,工作台找SSL证书或者安全下找CA证书2,点击创建证书(或购买证书),创建好以后点击证书申请、3,设置配置以及域名信息,仅填写圈住内容,其他默认即可4,随后等待一会,查看状态,是否为 已签发5,为已签发时,点击下载选择下载类型6,下载后解压文件7,上传至服务器,存放位置,先找到nginx所在位置 “/nginx/conf/”找到该位置创建“cert”把刚才解压的两个文件存放至此。8,开始nginx配置内容`server { #SSL 访问端口号为 443 li

  • ScheduledExecutorService 延迟 / 周期执行线程池

    ScheduledExecutorService 延迟 / 周期执行线程池目录Executor结构图ScheduleExecutorService简述对象创建方式方法详解scheduleRunnablescheduleCallablescheduleAtFixedRatescheduleWithFixedDelay本文可参考《线程池理论2》Executor结构图ScheduleExecutorService…

  • java中文乱码_Java中文乱码问题的解决方案[通俗易懂]

    java中文乱码_Java中文乱码问题的解决方案[通俗易懂]只要掌握了中文乱码问题产生的原因,然后对症下药,就可以顺利地解决这些问题。下面我们对容易产生乱码问题的场景进行分析,并提出解决方案。1.以POST方法提交的表单数据中有中文字符由于Web容器默认的编码方式是ISO-8859-1,在Servlet/JSP程序中,通过请求对象的getParameter()方法得到的字符串是以ISO-8859-1转换而来,这是导致乱码产生的原因之一。为了避免容器以ISO…

  • <C++学习笔记>iterator C++

    <C++学习笔记>iterator C++

  • 间隔DP基础 POJ2955——Brackets

    间隔DP基础 POJ2955——Brackets

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号