一、函数的参数可以是变量、变量指针和变量引用:
void funcA(int8_t x)
{
x=x+1;
}
代码说明:该函数的参数属于值传递,在调用该函数时,仅仅只是把实参的值拷贝了一份赋值给了形参x,之后的任何操作都不会影响到实参的值。
int8_t funcB(int8_t* x)
{
(*x)+=1;
return (*x);
}
代码说明:该函数的参数属于指针传递,在调用该函数的时候,虽然也是把实参的值拷贝一份给了形参x,但是形参x是个地址,它与实参一样,共同指向了同一片区域,因此如果之后通过*来操作x,必定会影响到该指针指向的区域。
int8_t funcC(int8_t &x)
{
x=x+1;
return x;
}
代码说明:该函数的参数属于引用传递,在调用该函数的时候,这个形式参数其实是实际参数的另外一个名字而已,言外之意,两者是同一个对象,所以操作x就意味着操作了实际参数。
int main(void)
{
int8_t score=5;
funcA(score);
printf("%d\n",score);
score=funcB(&score);
printf("%d\n",score);
score=funcC(score);
printf("%d\n",score);
}
打印结果是:
5
6
7
【总结】值传递为单向传递,利用值传递可以实现函数对某个状态的监视;指针传递和引用传递为双向传递,可以利用指针传递和引用传递来实现函数之间的通信。
二、函数的参数可以是函数指针,当函数的参数时函数指针的时候,顾名思义,这个函数是想通过函数指针来调用别的函数。
既然变量指针作为函数参数,函数就可以操作该指针指向的变量,那么同理,函数指针作为函数参数,函数就可以操作该指针指向的函数,毕竟无论是变量指针还是函数指针,本质上都是指向了内存的一个区域,无非是变量区域小些,函数区域大一些。下面举例说明:
//先定义一个函数指针
typedef void(*FP)(int x,int y);
//然后设计一个以
void func(FP fp,int n,int m )
{
int sum;
sum=fp(n,m)>6?fp(n,m):6;
}
//设计与函数指针FP匹配的函数原型
void Add(int x,int y)
{
return (x+y);
}
//在主函数中调用函数func
int main(void)
{
func(Add,1,3);
}
【总结】
1、一般情况下,调用函数的形式是:函数名(参数1,参数2,,,,),函数名其实是一个指针,一个指向该函数所存放的这个区域的指针,因此既然上面fp是函数指针,所以func(Add,1,3);就等同于Add(1,3);
2、理论上函数func可以以Add(1,3)的形式光明正大的调用它,但是却选择了以指针的形式调用,这是有妙用的。
3、要想声明一个函数指针,只需要把函数名用*加指针名替换,然后最前面加上typedef即可。
好了,很晚了,先写到这里为止。