文章目录
提示:以下是本篇文章正文内容,下面案例可供参考
一、静态数组和动态数组
1.静态数组的缺点
1.数组长度必须事先制定,不能为变量,必须为常整数;
2.传统定义的数组,其内存无法被程序员手动释放。在函数运行期间,系统为其分配的内存一直存在,直到函数运行结束,其内存被系统自动释放;
3.数组的长度一定固定,将无法改变。数组的长度无法在函数运行的过程扩大或缩小;
4.传统的定义的数组无法跨函数使用;
2.动态内存分配与动态数组
2.1 动态内存分配
我们知道,C语言中构造一个静态整型数组可以表示为 int a[5];,但如果获得动态整型数组直接写成int a[len]是不对的,那么如何构造动态的长度可以选定的数组?就这需要动态内存分配。
在C 语言中通过库函数malloc分配所需的内存空间,并返回一个指向它的指针。此函数的返回值是一个指针,指向分配空间的第一个字节的地址,所以该函数是一个指针型函数。
malloc声明: void *malloc(size_t size)
代码如下(示例1):
#include <stdlib.h>
malloc(100)//开辟100字节的动态内存,返回第一个字节的地址
2.2 动态数组
上面示例中:malloc(100)返回动态内存的100个字节中的第一个字节的地址即返回的指针指向动态内存的第一个字节。我们想要构造一个整型数组,通常整型数组的元素是4个字节即整型数组名指向4个字节,而malloc的返回的值指向的是1个字节,显然直接使用malloc函数是无法直接构造一个整形数组,那么如何解决?
注意到malloc函数的声明指出其返回的指针的基类型是void,即不指向任何类型的数据,只提供一个纯地址。所以我们可以更改基类型,若要构造动态整型数组,则将基类型更改为int,即(int *)malloc(100),此时malloc 函数的返回值指向4个字节(见示例2);若要构造动态浮点型数组,则将基类型更改为float,即(float *)malloc(100),此时malloc 函数的返回值指向8个字节;
代码如下(示例2):
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int len;
int * pArr;
printf("请输入数组的长度:\n");
scanf("%d",&len);
pArr = (int *)malloc(sizeof(int) * len);
free(pArr);//手动释放程序员手动分配的内存
return 0;
}
//此函数实现了动态数组的构造
//pArr = (int *)malloc(sizeof(int) * len);相当于 int pArr[len];(只是起到等价的作用,这样写C语言中是不支持的)
2.3 内存与堆与栈
静态内存是栈中分配,动态内存是在堆中分配。
二、自定义函数返回数组
1.常见错误
代码如下(示例3):
int * Input(void)
{
int a[10];
return a;
}
该函数为指针型函数。其定义静态数组并返回,由于静态数组(局部变量)在函数运行期间,系统为其分配的内存一直存在,直到函数运行结束,其内存被系统自动释放,所以我们无法接收这个数组.在Xcode中会得到下图的警告,所以我们使用这样的做法接收返回的数组。
2.返回数组的函数
动态开辟内存在堆区,堆区不像中静态数组(局部变量)在栈区存储,系统根据它的生命周期自动收回,而是手动开辟,手动释放,这样就可以完全规避问题,具体实例如下:
代码如下(示例4):
int * Input(void)
{
int *a = NULL;
int *p;
a = (int *)realloc(a,sizeof(int)*10);
for (p=a;p<a+10;p++)
{
scanf("%d",p);
}
return a;
}
需要注意的是:记得用完free掉,防止内存泄露!
三. 总结
C语言中通过堆区动态开辟内存解决函数的返回数组问题:我们通常用malloc来在堆区动态开辟内存,利用堆区“现用现开辟,用完手动收回”特点,实现灵活管理。四. 参考
1.郝斌C语言教程
2.谭浩强《C程序设计》
3.CSDN :C语言自定义函数如何返回数组