{
pa=0; break; } }
哦!参数pa与参数search的传递并没 有什么不同,都是值传递嘛(小语:地址传递其实就是地址值传递嘛)!所以对形参变量pa值(当然值 是一个地址值)的修改并不会改变实参变量p值,因此p的值并没有改变(即p的指向并没有被改变)。
(如果还有疑问,再看一看《第五篇:函数参数的传递》了。)
修正:
void find2(char [] array, char search, char ** ppa) {
int i;
for (i=0;*(array+i)!=0;i++) {
if (*(array+i)==search) {
*ppa=array+i break; }
else if (*(array+i)==0) {
*ppa=0; break; } } }
主函数的调用处改如下:
find2(str,a, &p); //调用函数以实现所要操作。
再分析:
这样调用函数时的整个操作变成如 下:
array=str; search=a;
ppa=&p; //请注意:以上三句是调用 时隐含的动作。
int i;
for (i=0;*(array+i)!=0;i++) {
if (*(array+i) ==search) {
*ppa=array+i break; }
else if (*(array+i)==0) {
*ppa=0; break; } }
看明白了吗?
ppa指向指针p的地址 。
对*ppa的修改就是对p值的修改。
你自行去调试。
经过修改后的程序就可以完 成所要的功能了。
看懂了这个例子,也就达到了本篇所要求的目的。
函数名与函数指针
一 数调用
一个通常的函数调用的例子:
//自行包含 头文件 void MyFun(int x); //此处的申明也可写成:void MyFun( int ); int main(int argc, char* argv[]) {
MyFun(10); //这里是调用MyFun(10);函数 return 0; }
void MyFun(int x) //这里定义一个MyFun函数 {
printf (“%dn”,x); }
这个MyFun函数是一个无返回值的函数,它并不完成什 么事情。这种调用函数的格式你应该是很熟悉的吧!看主函数中调用MyFun函数的书写格式:
MyFun(10);
我们一开始只是从功能上或者说从数学意义上理解MyFun这个函数,知道 MyFun函数名代表的是一个功能(或是说一段代码)。
直到——
学习到函数指 针概念时。我才不得不在思考:函数名到底又是什么东西呢?
(不要以为这是没有什么意义的事 噢!呵呵,继续往下看你就知道了。)
二 函数指针变量的申明
就象某一数据变量的内存 地址可以存储在相应的指针变量中一样,函数的首地址也以存储在某个函数指针变量里的。这样,我就 可以通过这个函数指针变量来调用所指向的函数了。
在C系列语言中,任何一个变量,总是要先 申明,之后才能使用的。那么,函数指针变量也应该要先申明吧?那又是如何来申明呢?以上面的例子 为例,我来申明一个可以指向MyFun函数的函数指针变量FunP.下面就是申明FunP变量的方法:
void (*FunP)(int) ; //也可写成void (*FunP)(int x);
你看,整个函 数指针变量的申明格式如同函数MyFun的申明处一样,只不过——我们把MyFun改成(*FunP) 而已,这样就有了一个能指向MyFun函数的指针FunP了。(当然,这个FunP指针变量也可以指向所有其它 具有相同参数及返回值的函数了。)
三 通过函数指针变量调用函数
有了FunP指针变量后 ,我们就可以对它赋值指向MyFun,然后通过FunP来调用MyFun函数了。看我如何通过FunP指针变量来调 用MyFun函数的:
//自行包含头文件
void MyFun(int x); //这个申明也可写 成:void MyFun( int ); void (*FunP)(int ); //也可申明成void(*FunP)(int x),但习惯
上一般不这样。
int main(int argc, char* argv[]) {
MyFun(10); //这是 直接调用MyFun函数 FunP=&MyFun; //将MyFun函数的地址赋给FunP变量
(*FunP)(20); //这是通过函数指针变量FunP来调用MyFun函数的。 }
void MyFun(int x) //这里 定义一个MyFun函数 {
printf(“%dn”,x); }
请看黑体字部 分的代码及注释。
运行看看。嗯,不错,程序运行得很好。 哦,我的感觉是:MyFun与 FunP的类型关系类似于int 与int *的关系。函数MyFun好像是一个如int的变量(或常量),而FunP则像 一个如int *一样的指针变量。
int i,*pi;
pi=&i; //与FunP=&MyFun 比较。
(你的感觉呢?)
呵呵,其实不然——
四 调用函数的其它书 写格式
函数指针也可如下使用,来完成同样的事情:
//自行包含头文件 void MyFun(int x);
void (*FunP)(int ); //申明一个用以指向同样参数,返回值函数 的指针变量。
int main(int argc, char* argv[]) {
MyFun(10); //这里是 调用MyFun(10);函数 FunP=MyFun; //将MyFun函数的地址赋给FunP变量
FunP(20); //这是通过函数指针变量来调用MyFun函数的。 return 0; }
void MyFun(int x) // 这里定义一个MyFun函数 {
printf(“%dn”,x); }
我改了黑 体字部分(请自行与之前的代码比较一下)。
运行试试,啊!一样地成功。
咦?
FunP=MyFun;
可以这样将MyFun值同赋值给FunP,难道MyFun与FunP是同一数据类型(即 如同的int 与int的关系),而不是如同int 与int*的关系了?(有没有一点点的糊涂了?)
看 来与之前的代码有点矛盾了,是吧!所以我说嘛!
请容许我暂不给你解释,继续看以下几种情况 (这些可都是可以正确运行的代码哟!):
代码之三:
int main(int argc, char* argv[]) {
MyFun(10); //这里是调用MyFun(10);函数 FunP=&MyFun; //将MyFun函数的地址赋给FunP变量
FunP(20); //这是通过函数指 针变量来调用MyFun函数的。 return 0; }
代码之四:
int main(int argc, char* argv[]) {
MyFun(10); //这里是调用MyFun(10);函数 FunP=MyFun; //将MyFun函数的地址赋给FunP变量
(*FunP)(20); //这是通过函数指针 变量来调用MyFun函数的。 return 0; }
真的是可以这样的噢!
(哇 !真是要晕倒了!)