3.指针与函数
指针与函数的关系:
- 指针可以作为函数的参数,实现传递一个变量或函数的地址
- 指针可以指向函数
- 指针作为函数的返回值
3-1指针可以作为函数的参数
函数的参数不仅可以是整型、实型、字符型的变量,还可以是指针类型的变量。它的作用是将一个地址值传送到另一个函数中。同其它类型的变量一样,在指针变量作为函数的参数时,也需要进行相应的类型说明。
3-1-1函数的形参是指针
在函数定义中,如果函数的形参是指针,则函数调用时给出的实参可以是指针,也可以是某变量的地址,即参数传递中的传址方式也就是实参的地址传递给形参。
采用传址方式进行参数传递时,由于作为形参的指针接收了与实参相关的变量的地址,因此在被调函数中利用取内容运算符“*”改变形参所指向的变量的值,实际上就改变了主调函数中与实参相关的变量的值,简单地说,就是形参的变化会影响到实参。
int max(int *p,int *q) { int *t; *t=*p; *p=*q; *q=*t; } 改变值,不换指向 | int max(int *p,int *q) { int *t; t=p; p=q; q=t; } 不改变值,换指向 |
交换的仅是p和 q所指向变量的值,指针p和q的指向没有发生变化,因此主函数 main( )中变量的值发生变化。所以函数调用结束返回主函数后,变量的值改变。 | 交换的仅是形参p和 q的值,即p和 q中存储的地址,使指针p和q的指向发生了变化,但主函数 main( )中变量的值并没有发生任何变化。因此函数调用结束返回主函数后,变量的值保持原值不变。 |
注意:C语言中,在参数传递时,采用传值方式不会因为形参的变化而影响到实参,也就是说不会将被调函数中的形参的变化带到主函数中;采用传址方式时,形参的变化会影响到实参。
3-1-2函数的形参是数组
在函数定义中,如果函数的形参是数组,则函数调用时给出的实参可以是数组,也可以是指向数组的指针。
对于二维数组作为函数的形参,可以省略第一维的长度,但第二维的长度必须明确给出,不能省略。当形参用一维数组“int arr[ ]”的形式时,系统将形参arr 看做是一个指向数组array的列指针,因此,在被调函数arrAdd()中用单循环即可。需指出,此时形参用“int *arr"也是正确的。
3-2指针指向函数
c语言中定义的指针,可以指向整型、实型、字符型等合法的C数据类型的变量,也允许指向一个函数,只要将该函数的入口地址赋值给指针即可。
函数的人口地址是指函数编译后生成的机器指令中的第一条指令的地址。 一个指针中存储了函数的人口地址,这个指针就称为指向函数的指针,简称为函数指针。
简单来说,一个函数在编译时,被分配了一个入口地址,这个地址就称为该函数的指针。可以用一个指针变量指向一个函数,然后通过该指针变量调用此函数。
函数名就是函数的入口地址。
3-2-1函数指针定义
函数指针定义格式如下:
函数类型 (*指针变量)(形参列表);
注意的是:①“*指针变量”外的括号不能缺,否则成了返回指针值的函数。
② 类型说明符是函数指针所指向的函数的返回值类型,指针名和指针说明符“*”必须用圆括号括起来,后面的圆括号中的参数列表是函数指针所指向的函数的形参列表,参数列表中的参数可以有一个或多个,也可以没有,当列表中无参数时圆括号也不能省略。
例如:假设函数fun()已声明:
int fun (int, int);
int (*p)(int, int) ;/*p为指向int类型函数的指针变量*/
p= fun;
/*定义了一个函数指针p,并通过将函数fun()赋值给p,使函数指针p指向了函数fun()。*/
注意:在为函数指针赋值时,等号右侧仅是函数名。例如,“p = fun;”是正确的,而“p= fun( );”是错误的。
3-2-2通过函数指针调用函数
一般形式:
(*指针变量)(实参列表)
或
指针变量(实参列表)
例如:
max(3,9);
(*p)(3,9);
3-3-3函数指针和指向数组的指针区别
指向函数的指针(函数指针): 一个指针中存储了函数的人口地址,是地址
int (*p)(int, int) ;/*p为指向int类型函数的指针变量*/
指向数组的指针:每一个元素都是一个指针变量,是数组
int *p[4];//定义的指针数组名为p,数组p有4个元素,这4个元素都是指向整型的指针变量
3-3指针作为函数的返回值
调用函数可以返回一个int型或float型或char型的值,也可以返回一个指针类型的值,即返回一个地址。
返回指针类型值的函数(简称指针函数)的定义格式如下:
函数类型 *函数名(形参表列)
{
函数体
}
其中,“*”是指针说明符,表明函数的返回值是指针,类型说明符是返回的指针所指向的变量的类型。
例如:
char *seck(char *q, char ch)/*定义返回指针值的函数seck*/
{
while(*q!=10')
if(*q!=ch)
q++;
else
return q;/*返回要查找的字符的地址*/
return NULL;/*若(*q=='0')或没有找到,返回空指针*/
}
3-4main函数的参数
①main函数参数的概念
C程序通过main函数的参数获取命令行参数信息。main函数有两个参数,它的原型如下:
[返回类型] main (int argc, char*argv[]);
人们常用argc、argv作为main函数的两个参数的名字。当然,根据对函数性质的了解,这两个参数完全可以用任何其它名字,但它们的类型是确定的。
②main函数参数的处理
当一个用C编写的程序被装入内存准备执行时,main函数的两个参数被自动给定初值:
argc的值是启动命令行中的命令行参数的个数;
argv是一个字符型指针数组,这个数组里共有argc+1个字符型指针变量,其中的前argc个指针变量分别存储命令行参数的各字符串首地址,最后是一个空指针,表示数组结束。