03
指针函数与函数指针本质上的区别是,指针函数是一个带指针的函数,总的来说还是一个函数,如图就是一个带*name指针的函数
04
函数指针是指向函数的指针变量,本质上还是一个指针,其格式如下,可以看到和指针函数的格式非常像,所以一定要用心留意 。
C语言 指针函数 函数指针 什么区别联系?最好有例子?一定采纳没觉得指针函数这个概念有什么大的意义 。。。。可能其最大的意义就是拿过来和函数指针一起混淆初学者的视听吧 。
指针函数指的是返回一个指针的函数 , 比如我们常见的gets(),strcpy() , strcat() , malloc()等等 。如果单独把它当成一个新概念真的没有什么意义 。这些函数除了返回一个指针之外没有任何共性 , 但是返回的指针又天差地远 。
下面说说函数指针 。
指针分为三种类型:对象指针,函数指针和void指针 。
函数指针的声明形式是T (*p)(...),其中*p使用括号括起来的原因是函数类型解析的优先级高于指针的解析,故使用括号防止解析成上面的指针函数(其实这两个之间就相差了一对括号) 。
函数指针可以绑定到与其返回值和参数类型都相同的函数上 。比如:
int foo(int, double); // 函数声明
int (*bar)(int, double) = foo; // 函数指针
在上面的初始化中,写成foo也是可以的 。
函数指针的最大特点就在于,其不能做一元+-运算(当然也不能做+= -= ++ --等),且对其做一元*运算的结果还是其本身 。例如:(接着上面的例子)
bar(1,1.0);
(*bar)(1,1.0); // 两种情况等价
甚至你还可以这样:
(**************bar)(1,1.0);
依然是对的 。
所以实际应用中一般采取类似函数调用的方式 , 这样更加自然 。
刚刚去测试了一下,还有一个更加隐蔽的问题:
C中的函数可以采用使用原型或者不使用两种方式 。(不使用原型被视为过时)
原型即在函数头中将参数类型及个数都声明,而不使用就是很简单的一对括号 。例如:
int foo(); // 非原型
int bar(void); // 原型
int foo1(int); // 原型
这有什么影响呢?看一看下面的一段代码:
int foo(int i){return i;} // 原型
int foo1(double c){return (int)c;} // 原型
int bar(){return 1;} // 非原型
int main(void)
{
int (*foobar)(int); // 原型
int (*barfoo)(); // 非原型
foobar = foo;
foobar = foo;
foobar = bar;
foobar = foo1; // this
barfoo = foo;
barfoo = bar;
barfoo = foo1;
foobar(1);
(*foobar)(1);
(*************foobar)(1);
return 0;
}
我的编译器对this指的一行进行了警告,提醒指针类型不匹配 。
我们可以看到,非原型的函数指针可绑定到任意的函数上,而带有原型的函数指针在绑定时可以起到更严格的类型限制 。
容易忽略的一点是,不接受任何参数的函数(带原型)的声明方式是int foo(void);,不应该省略void,特别是在使用对应类型的函数指针时 , 如果省略void,那么错误的绑定也不会被警告 。
我还注意到了一个现象:
int foo(char);
int (*bar)() = foo;
这段代码同样也给了警告 。为什么呢?
因为在不使用原型的情况下,char,short,float等会被隐式提升到与其对应的更高级类型 。
而在这个绑定中,bar是非原型,这时可能会进行整型提升,而foo带有原型,调用时不需要进行提升 。这样就有可能引发错误 。
以上就是函数指针使用过程中需要注意的一点 。不过提醒LZ,函数指针使用过程中最好还是使用带有原型的函数指针 。
推荐阅读
- oracle查询换行符,oracle replace换行符
- 手机什么型号换系统好些,手机什么系统好用好用
- 虚拟空间什么,虚拟空间运行
- 直播运营助理跟运营的区别,直播助理和运营助理
- php数据库类型 php的数据库在哪个目录下
- postgresql密码访问的简单介绍
- 区块链区块是怎么产生的,区块链区块是如何产生的
- 治愈游戏恋爱养成,治愈系恋爱游戏
- vb.net移动窗体 vb窗体移动