在线学习-第八章 指针 8.6.2 指针作为函数的返回值

来源:百度文库 编辑:神马文学网 时间:2024/04/28 03:19:50

第八章 指针
[学习指导][本章练习][知识点][参考文献]
8.6.2 指针作为函数的返回值
1 指针作为函数的返回值
指针值也可以作为函数的返回值。这种情况下函数的返回值类型需要定义成指针变量类型。返回指针值的函数的一般定义格式为:
数据类型 *函数名称(形式参数列表)
例如:
float *Func(float x, float y);
该函数的形式参数是两个float型的变量,返回一个float型变量的指针。下面是一个返回指针值的函数的例子:
long score[10]={1,2,3,4,5,6,7,8,9,10};
long *GetMax();
main()
{
long *p;
p=GetMax();
printf("Max value in array is %d", *p);
}
long *GetMax()
{
long temp;
int i, pos=0;
temp=score[0];
for(i=0;i<10;i++)
if(score[i]>temp)
{
temp=score[i];
pos=i;
}
return &score[pos];
}
程序运行的结果为:
Max value in array is 10
上面的例子中,GetMax函数没有任何形式参数,该函数返回一个指针值。注意long型数组score是一个全局变量,它有10个已经初始化过的元素。
GetMax函数中,我们用临时变量temp比较记录全局数组score里最大的元素,同时用pos记录最大的元素的数组下标号。循环结束后,返回的是数组中值最大的元素的地址值,即该元素的指针值。注意因为数组是全局变量,GetMax函数调用结束后,数组元素在内存中仍然存在,因此GetMax函数返回的指针值是有效的。
main函数中定义了一个指针变量p,调用了GetMax函数,将返回的指针值赋给了指针变量p,现在p指向了数组score里最大的元素,*p对应了score里最大的元素的值。后续的printf打印了*p值。
将指针值作为函数的返回值时,一定要保证该指针值是一个有效的指针。一个常犯的错误是试图返回一个局部变量的指针,下面是错误的例子:
long *GetMax();
main()
{
long *p;
p=GetMax();
printf("Max value in array is %d", *p);
}
long *GetMax()
{
long score[10]={1,2,3,4,5,6,7,8,9,10};
long temp;
int i, pos=0;
temp=score[0];
for(i=0;i<10;i++)
if(score[i]>temp)
{
temp=score[i];
pos=i;
}
return &score[pos];
}
这段程序和前面的例子很相似,好象没有什么问题,编译也可以顺利通过。但运行可能会出现问题。原因是这里的数组score是一个局部变量,函数调用结束后该数组所占用的内存空间将被释放,因此,return &score[pos]虽然返回了数组元素的指针,但该数组元素已经不存在了,这个指针也就是一个无效的指针。这样的代码可能导致程序的异常。
2 malloc函数和free函数
前面的章节曾经讲过,函数的局部变量保存在系统的动态存贮区。但是,C语言提供malloc库函数,使用该函数可以在系统的静态存贮区里分配一定字节数量的内存。函数中可以通过调用malloc函数,返回静态存贮区里一块内存的首地址,然后间接访问该内存单元的值。使用完毕后,可以调用free函数释放该内存块。
malloc函数的原型为:
void *malloc(unsigned int size);
在内存的动态存贮区里分配长度为size的连续空间。函数的返回值是指向被分配内存块首地址的指针,该指针为void *类型。如果函数执行不成功(例如内存空间不足),函数返回空指针NULL。
free函数的原型为:
void free(void *p);
从动态存贮区释放p指向的内存区,p是最近一次调用malloc返回的值。free函数没有返回值。
下面malloc和free配合使用的一个例子:
main()
{
float *p;
p=malloc(sizeof(float));
*p=5.0;
printf("\n*p=%f",*p);
*p=*p+5.0;
printf("\n*p=%f",*p);
free(p);
}
程序运行的结果为:
*p=5.000000
*p=10.000000
说明:
(1)sizeof(float)的值就是float类型所占用的字节数,即4。sizeof是一个操作符,sizeof(数据类型符)的值就是该数据类型所占用的字节数。
(2)malloc(sizeof(float))在系统的静态存贮区里分配了4个字节的内存空间。malloc函数返回一个指针值,该指针就是上述4个字节的首地址。
(3)语句free(p)释放指针p所在的内存块。
(4)malloc函数和free函数应该搭配使用,这是一个比较好的习惯。忘记释放应该释放的内存会导致程序内存泄漏,影响程序的效率。
例 8-9 定义一个动态数组,可以保存多个学生的成绩,并计算平均值。
本题的关键是使用动态数组。可以利用malloc函数,写一个返回指针值的函数int *DefineArray(int n),该函数可以动态分配n*sizeof(int)个字节的内存空间,正好可以存放n的int型变量,相当于一个int型的数组。使用时,p[i]等价于*(p+i),符合数组元素引用的习惯。
同样,可以定义一个函数void FreeArray(int *p),在内部用free函数释放分配的内存。
int *DefineArray(int n);
void FreeArray(int *p);
main()
{
int *p, i, nCount;
float fSum=0;
/*输入学生的个数*/
printf("\nPlease input the count of students: ");
scanf("%d",& nCount);
/*动态定义数组p*/
p= DefineArray(nCount);
/*输入每个学生的成绩*/
printf("Please input the scores of students: ");
for(i=0;i< nCount;i++)
scanf("%d", &p[i]); /*等价于scanf("%d", p+i)*/
/*计算成绩总和*/
for(i=0;i< nCount;i++)
fSum+=p[i]; /* p[i]等价于*(p+i) */
/*打印成绩平均值*/
printf("\nAverage score of the students: %3.1f", fSum/nCount);
/*释放动态数组p*/
FreeArray(p);
}
int *DefineArray(int n)
{
return (int *) malloc(n*sizeof(int));
}
void FreeArray(int *p)
{
free(p);
}
程序运行的结果为:
Please input the count of students: 5
Please input the scores of students: 87 97 77 68 98
Average score of the students: 85.4
程序根据用户输入的学生个数,利用DefineArray函数动态分配数组所需要的内存。程序结束前调用函数FreeArray释放了DefineArray函数所分配的内存。
DefineArray函数的输入参数n是数组的元素个数。函数用malloc分配了数组需要的内存,并将返回的void *类型的指针转换为int *类型。最终DefineArray函数返回一个int型变量或数组的指针。该指针的值就是malloc分配内存的首地址。
main函数中,p是一个指向int型变量或数组的指针变量,p[i]等价于*(p+i),&p[i]等价于p+i,不论是直接引用还是间接引用,结果都是相同的。
[