//小放min
}
printf("%5d%5d\n",max,min)。
//输出最大和最小值
}
输出结果:
7224
五、动态存储分配
1.动态存储分配的概念
变量和数组在计算机内存中都有对应的存储空间,该存储空间的分配时机有两种:
一种在编译阶段,或者说在程序运行前;另一种在程序运行之中。
前者称为静态存储分配方式,后者称为动态存储分配方式。
●变量的静态存储分配方式
通过一般的变量定义语句定义的变量,采用的是静态存储分配方式。
如:
intx,y。
//x和y分别对应的4个字节的存储空间是静态分配的
inta[10]。
//数组a所需要的40个字节的存储空间是静态分配的
charb[20],*p=b。
//数组b的20个字节和指针变量p的4字节是静态分配的
doublec[M][N]={{0}}。
//数组c的M*N*8个字节的存储空间是静态分配的
●变量的动态存储分配方式
变量的动态存储分配需要调用在系统头文件stdlib.h中声明的动态存储分配函数来实现,这些函数为malloc()、calloc()和realloc()三种。
2.动态存储分配函数的原型格式和功能
●malloc()函数原型格式
void*malloc(unsignedintk)。
功能:
调用它时能够分配k个字节的存储空间,并把第1个字节的地址返回,该返回值具有void*类型,可以赋给任一具体类型的指针变量。
●calloc()函数原型格式
void*calloc(unsignedintn,unsignedintk)。
功能:
调用它时能够分配n*k个字节的存储空间,并把第1个字节的地址返回,该返回值具有void*类型,可以赋给任一具体类型的指针变量。
通常用n表示数组长度,k表示元素类型的长度。
●realloc()函数原型格式
void*realloc(void*ptr,unsignedintk)。
功能:
调用它时能够分配k个字节的存储空间,接着把ptr已经指向的动态分配的存储空间的内容复制到新分配的存储空间中,最后把新分配的存储空间的第1个字节的地址返回。
由于该返回值具有void*类型,所以能够赋给任一具体类型的指针变量,通常仍赋给ptr所对应的实参指针变量,使得通过该调用后增加或缩小动态存储空间。
3.动态存储分配的调用格式举例
(1)int*pn=malloc(sizeof(int))。
//分配一个整数存储空间由指针变量pn所指向,此动态分配的变量
//为*px,可用它保存一个整数,如:
*px=25。
*px+=30。
//其值为55
(2)double*pa=calloc(10,sizeof(double))。
//分配一个具有10个双精度元素的一维数组空间,由指针变量pa
//所指向,pa也就是该动态数组的数组名(但有区别,它是变不是常),
//通过它可以访问该数组中的任何元素。
如:
*pa=12。
把12赋给
//pa[0]元素;又如:
pa[i](3)pa=realloc(pa,20*sizeof(double))。
//增加pa指针所指向的存储空间的大小,由10个双精度元素变为
//20个双精度元素,同时原有的存储内容被复制过来。
(4)int**top=calloc(M+1,sizeof(int*))。
//top动态数组含有M+1个元素,每个元素能够存储一个整数的地址。
4.动态存储分配的优点
允许在程序运行过程中随时确定待使用的存储空间的大小,不必象静态分配那样需要事先确定。
一般定义一个数组时,必须确切给出数组的每一维的尺寸,如:
inta[10],b[M][N]。
//M和N必须是已经定义的符号常量
动态分配定义一个数组时,所分配的存储空间的大小可以是常量,也可以是变量。
如:
(1)inta=calloc(10,4)。
//两个参数都为常量
(2)inta=calloc(x,4)。
//第1个参数为变量,分配x个整数元素的空间
(3)charb=malloc(n1+n2)。
//n1和n2为变量,分配n1+n2个字节的空间
(4)charc=malloc(sizeof(d))。
//根据另一个对象d的大小分配空间
5.动态存储空间的释放
释放动态存储空间的free()函数的原型格式
voidfree(void*ptr)。
功能:
调用它时能够把指针变量ptr所指向的动态存储空间释放掉,即归还给操作系统。
free()函数原型声明也包含在stdlib.h系统头文件中
当动态存储空间保存的内容不再使用时,可调用该free()函数及时释放掉,若没有调用它,则一直到程序运行结束时该动态存储空间才被自动释放给操作系统。
对于一般静态分配的变量,其占有的存储空间只能由C语言系统在运行时自动释放,其时机为所在的模块(复合语句)刚执行完毕。
下面看一个程序例子
#include//支持调用标准输入和输出操作的函数
#include//支持调用动态存储分配和释放函数
voidmain()
{
int*a=calloc(10,sizeof(int))。
//动态分配得到a[10]数组,
//为40字节的存储空间,同时静态分配得到a指针变量,4字节
inti。
//静态分配得到i整数变量,4字节
for(i=0。
i<10。
i++)a[i]=i*i。
//给a数组中每个元素赋值
for(i=0。
i<10。
i++)printf("%d",a[i])。
//输出a中每个元素值
printf("\n")。
//输出一个换行符
free(a)。
//a[10]数组的40个字节的动态存储空间被交还给操作系统
}//此主函数执行结束时,自动把a和i各占有的4字节交还给操作系统
程序运行结果:
0149162536496481
六、使用指针和动态存储分配的程序举例
例1:
以指针方式访问数组元素的例子
#include
#include
voidmain(){
inta[5]={3,6,9,12,15}。
int*p=a。
//把数组a的首地址赋给指针变量p
inti。
for(i=0。
i<5。
i++)printf("%5d",*p++)。
//指针方式访问数组a
printf("\n")。
//换行
for(p=a+4。
p>=a。
p--)printf("%5d",*p)。
//从后向前访问数组元素
printf("\n")。
//换行
}
输出结果:
3691215
1512963
例2:
进行简单变量动态存储分配的例子
#include
#include
voidmain()
{
intx=23,y=40,z。
int*p1=malloc(sizeof(int))。
//为*p1动态分配4字节存储空间
int*p2=malloc(sizeof(int))。
//为*p2动态分配4字节存储空间
*p1=x。
*p2=y。
//分别把x值23和y值40赋给动态变量*p1和*p2
printf("%d%d\n",*p1,*p2)。
//输出*p1和*p2的值为2340
z=*p1。
*p1=*p2。
*p2=z。
//交换*p1和*p2所保存的值
printf("%d%d\n",*p1,*p2)。
//输出*p1和*p2的值为4023
free(p1)。
free(p2)。
//释放p1和p2各自所指向的动态存储空间
}
程序运行结果:
2340
4023
例3:
动态存储分配任意大小的一维数组的例子
#include
#include
voidmain()
{
intn,i,sum=0。
int*a。
printf("从键盘给n输入一个正整数(1-10):
")。
while
(1){scanf("%d",&n)。
//输入1-10之间的数到n中
if(n>=1&&n<=10)break。
elseprintf("重输:
")。
}
a=calloc(n,sizeof(int))。
//动态分配a[n]数组空间,n是变量
a[0]=0。
a[1]=1。
//给a数组的前2个元素赋值
for(i=2。
ii++)a[i]=a[i-1]+a[i-2]。
//从元素a[2]起,每个元素值等于前2个元素值之和
//0+1=1,1+1=2,1+2=3,2+3=5,…
for(i=0。
ii++){
sum+=a[i]。
//计算出n个元素之和
printf("%5d",a[i])。
//依次输出每个元素值
}
printf("\nsum=%5d\n",sum)。
//输出sum的提示信息和值
free(a)。
}
程序运行结果:
从键盘给n输入一个正整数(1-10):
12
重输:
8
011235813
sum=33
例4:
动态存储分配二维数组的例子。
#include
#include
voidmain()
{
inti,j。
introw,col。
int**ab。
//定义2阶整型指针变量ab,用它指向int*类型的数据
printf("输入一个二维表格数据的行数和列数:
")。
scanf("%d%d",&row,&col)。
//输入行、列数到row和col中
ab=calloc(row,sizeof(int*))。
//得到动态分配的一维指针数组ab[row]
for(i=0。
ii++)//依次使ab[i]指向包含col个元素的一维数组
ab[i]=calloc(col,sizeof(int))。
printf("输入%d行*%d列的二维表格数据:
\n",row,col)。
for(i=0。
ii++)//输入数据进入二维数组ab[row][col]中
for(j=0。
j
j++)
scanf("%d",&ab[i][j])。
//等价表示:
*(ab[i]+j)
printf("\n")。
printf("输出二维表格数据:
\n")。
for(i=0。
ii++){//按row行和col列输出数据
for(j=0。
j
j++)
printf("%5d",ab[i][j])。
printf("\n")。
}
for(
|
|
|