函数指针
1、
我们先看一个简单的加法:
#include<iostream>
int Add(int a,int b)
{
int c = a + b;
return c;
}
int main()
{
int x = 2, y = 3;
int z = Add(x,y);
printf("Sum = %d\n", z);
}
运行结果:
我们使用指针来改变上的代码:
#include<iostream>
int Add(int *a,int *b)
{
int c = *a + *b;
return c;
}
int main()
{
int x = 2, y = 3;
int z = Add(&x, &y);
printf("Sum = %d\n", z);
}
运行结果:
把返回值,转换成返回地址:
#include<iostream>
int *Add(int* a, int* b)
{
int c = (*a) + (*b);
return &c;
}
int main()
{
int a = 2, b = 3;
int* ptr = Add(&a, &b);
printf("Sum = %d\n", *ptr);
}
运行结果:
注意:
(1)
int *Add(int* a, int* b)
{
int c = (*a) + (*b);
return &c;
}
这里的函数Add()前面加了个 *,代表返回指向整数的指针。
上面的代码运行正确,其实有个逻辑错误。
我们来继续看一个例子,我们在 mian()函数 增加一个打印 " hello world "的函数。
#include<iostream>
void helloworld()
{
printf("hell world!");
}
int *Add(int* a, int* b)
{
int c = (*a) + (*b);
return &c;
}
int main()
{
int a = 2, b = 3;
int* ptr = Add(&a, &b);
helloworld();
printf("Sum = %d\n", *ptr);
}
运行结果:
注意:
" hello world!" 可以打印,但 值 现在不能打印了。为什么? 这是因为内存栈的一个问题。怎么说?
用程序的运行来看内存变化:
首先我们的代码是 在内存栈中建立了main()函数,下面就会有变量a,b,还有*ptr,好了,然后开始调用函数Add()函数,内存的栈的位置又划出新的内存来提供给Add()函数,它有指针变量 *a,*b,还有c,而*a ,*b指向main()函数的a和b的值,然后相加得c,输出c的地址。okay,这时程序又回来main()函数,之前的Add()函数已内存释放,我们开始执行helloworld()函数,内存栈又要给hellworld()函数提供内存,这时内存栈提供的内存的位置是之前Add()函数的内存位置,也就是说ptr目前还是指向c的值,但是helloworld()把Add()之前的内存位置给覆盖了,而这时Add()返回的c的地址已经被清空了。所以导致输出提示错误。
我们需要使用 malloc 来解决这个问题:
#include<iostream>
void helloworld()
{
printf("hell world!\n");
}
int *Add(int* a, int* b)
{
int* c = (int*)malloc(sizeof(int));
*c = (*a) + (*b);
return c;
}
int main()
{
int a = 2, b = 3;
int* ptr = Add(&a, &b);
helloworld();
printf("Sum = %d\n", *ptr);
}
运行结果:
2、
把函数作为地址:
#include<iostream>
int Add(int a,int b)
{
return a+b;
}
int main()
{
int c;
int (*p)(int,int);
p = &Add;
c = (*p)(2,3);
printf("a + b = %d\n", c);
}
运行结果:
非常酷,我们只是使用了一个函数指针来引用一个函数。
注意:
(0)
int (*p)(int,int);
因为我要指向Add(int a, int b)函数,这个函数有两个整型类型,我们这里我们必须和它一致,否则运行出错。
另外 Add(int a, int b) 返回的是一个整型int,所以这里也需要这条语句最前面也需要一个int,否则运行出错。
(1)
int (*p)(int,int);
(*p) 如果去掉括号,就变成了一个指向整型的指针。加上括号那就是函数指针。
(2)
p = &Add;
这句语句,去掉 & 符号,也是可以运行的。
(3)
c = (*p)(2,3);
上面的语句可以用这种含有标识符的来引用,下面这句语句也是可以函数变量来引用:
c = p(2,3);
实现一下:
#include<iostream>
int Add(int a,int b)
{
return a+b;
}
int main()
{
int c;
int (*p)(int,int);
p = Add;
c = p(2,3);
printf("a + b = %d\n", c);
}
运行结果:
算法和数据结构是程序的第一秘诀,缺之算法和数据结构是编程的最大原因。