鱼C论坛

 找回密码
 立即注册
查看: 2021|回复: 14

[已解决]C指针函数和函数指针

[复制链接]
发表于 2018-8-6 16:55:36 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
哪位大神能解释一下这句话
最佳答案
2018-8-6 18:41:07
select(a, b) 这个函数有两个参数,但是返回一个函数的指针 c 。这个函数也有两个参数 fun(d, e),返回的是整形 f。

指向函数的指针就是函数本身,所以 select(a, b) 会返回 f
webwxgetmsgimg.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-8-6 17:11:23 | 显示全部楼层
首先有一个函数指针,该函数指针指向一个函数,该函数有两个参数,并且其返回值为整型
然后,另外有一个函数,函数有两个参数,并且返回值就是上述类型的函数指针。
这样说的话,不知道能否理解?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-6 18:41:07 From FishC Mobile | 显示全部楼层    本楼为最佳答案   
select(a, b) 这个函数有两个参数,但是返回一个函数的指针 c 。这个函数也有两个参数 fun(d, e),返回的是整形 f。

指向函数的指针就是函数本身,所以 select(a, b) 会返回 f
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-9 15:06:00 | 显示全部楼层
typedef int (*FUNC)(int x, int y) //定义函数指针
FUNC *pfnc = select(a, b);    //select(a, b) 这个函数有两个参数,但是返回一个函数的指针pfnc
int sum = pfnc(x, y);            //函数指针也有两个参数 pfnc(x, y),返回的是整形 sum
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2018-8-17 10:50:39 | 显示全部楼层
楼主,如果问题得以解决,请记得采纳最佳答案哦~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-17 20:03:08 | 显示全部楼层
claws0n 发表于 2018-8-17 10:50
楼主,如果问题得以解决,请记得采纳最佳答案哦~

说白点就是这个 select 函数的返回值是一个函数指针( 指向函数的指针, 只要有了这种指针之后,就可以通过指针来调用函数, 而不用通过函数名) , 然而问题就来了,这个返回的指针指向的函数是个什么样的函数呢?
所以定义时得说清楚(说清楚这是个什么函数),是吧?
最后这个select的定义就变得复杂点了, 它不仅本身要有参数,它返回的指针指向的函数也得有参数(不然就不知道要指向什么阿猫阿狗函数了)
能理解吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-17 20:04:02 | 显示全部楼层
说白点就是这个 select 函数的返回值是一个函数指针( 指向函数的指针, 只要有了这种指针之后,就可以通过指针来调用函数, 而不用通过函数名) , 然而问题就来了,这个返回的指针指向的函数是个什么样的函数呢?
所以定义时得说清楚(说清楚这是个什么函数),是吧?
最后这个select的定义就变得复杂点了, 它不仅本身要有参数,它返回的指针指向的函数也得有参数(不然就不知道要指向什么阿猫阿狗函数了)
能理解吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-17 23:18:30 | 显示全部楼层
微末非末 发表于 2018-8-17 20:03
说白点就是这个 select 函数的返回值是一个函数指针( 指向函数的指针, 只要有了这种指针之后,就可以通 ...

不是的,建议复习一下
数组、字符串的变量名等同于所存储的首元素的地址
函数名等同于指向该函数的指针

你这个是一个概念题。当 select 返回函数的指针时,等同于调用了函数。消化一下 3 楼~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-18 00:38:49 | 显示全部楼层
claws0n 发表于 2018-8-17 23:18
不是的,建议复习一下
数组、字符串的变量名等同于所存储的首元素的地址
函数名等同于指向该函数的指针 ...

我没懂你意思我那就话错了?
”可以通过指针来调用函数,而不用通过函数名“ 这句话?

函数名就是个地址,但是它是个 r-value (不可以改变了)
指向该函数的指针,这个指针变量它的值是函数地址,但它却是 l-value (可以改变的,有特定的存储位置)
也就是当我赋值之后(把函数名赋给指针之后)    只是它们恰好指向了同一个地址。因为定义的时候已经定义好了这个指针是指向什么类型的函数,指针的尺寸就有了, 所以就可以通过指针来调用函数了。


总结:  函数名就是个地址, 而指针却是指向某个地址的。当对指针变量名进行引用时,它的值就是它指向的地址。

不知道我这样理解,对不对
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-18 01:00:30 | 显示全部楼层
微末非末 发表于 2018-8-18 00:38
我没懂你意思我那就话错了?
”可以通过指针来调用函数,而不用通过函数名“ 这句话?

上面的部分你想复杂了吧??

r-value 可以当成 right-value 右值,但实际上叫 register-value 注册值(自己翻译的,看明白就好)
l-value 可以当成 left-value 左值,但实际上叫 location-value 地址值
地址 (l-value) 没有透过指针是改不了的,值 (r-value) 可以透过赋值运算符 (=) 修改

也就是当我赋值之后(把函数名赋给指针之后)    只是它们恰好指向了同一个地址。因为定义的时候已经定义好了这个指针是指向什么类型的函数,指针的尺寸就有了, 所以就可以通过指针来调用函数了。
定义的操作是可以分开的,应该是指针被定义为指向整型的指针,恰好该函数的返回值也是整型的。

函数名就是个地址,而指针却是指向某个变量的地址。当对指针变量名进行引用时,它的值就是它指向的地址
就会得到它本身所指向的地址的值。它本身所存储的值是它所指向的地址
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-18 17:35:01 | 显示全部楼层
本帖最后由 微末非末 于 2018-8-18 17:38 编辑
claws0n 发表于 2018-8-18 01:00
上面的部分你想复杂了吧??

r-value 可以当成 right-value 右值,但实际上叫 register-value 注册值[ ...


没复杂啊

地址 (l-value) 没有透过指针是改不了的,值 (r-value) 可以透过赋值运算符 (=) 修改
这句话,我就得你就理解得有问题。我举个例子

     int a = 520;    (这里假设 a 这个变量所表示的内存位置是 0x100)

在这里  a 是  l-value (也就是向系统要了 sizeof(int) 个字节的空间 ,我对这块空间取名为 a ,这是一块有特定位置的空间)
而 等于号右边520它是 r -value (这个520也肯定会存在内存的某个位置,如果没有这个内存位置,那编译器要上哪找这个520?但是它存在哪里我们是不知道的,系统将它保护起来了,所以这样写 &520 , 或者 520 = 1314,这样肯定会报错,要是常量r-value都被改变了,那岂不是乱套了?)

还要有一点: l-value 是可以被当作 r-value 使用的,也就是说它出现在等于号左边和右边,所代表的意义是不同的,当在左边的时候,我们就可以对它进行赋值(它表示的是0x100这个地址空间) ;当在右边的时候,我们就可以对它的值进行引用 (它就表示520这个值)。这个在小甲鱼的视频里有说到过,还有《c和指针》里也有说到过


这句  “地址 (l-value) 没有透过指针是改不了的”,  地址是r-value, 相当于上面那个520,你不可能可以修改它的。我们能修改的就只有指针变量,指针变量里边放的什么值。比如说 int *p = &a , 然后我想让它指向另一个地址了,p = &b 。我修改的是p 这个变量的值,而不是地址。

我记得有的书上是有这么一句话: 为了方便描述我们把指针变量简写为指针....
指针是地址,而指针变量是放地址的变量

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-18 21:37:05 | 显示全部楼层
本帖最后由 无符号整形 于 2018-8-18 21:44 编辑
claws0n 发表于 2018-8-18 01:00
上面的部分你想复杂了吧??

r-value 可以当成 right-value 右值,但实际上叫 register-value 注册值[ ...


其实楼上说的这个520是没有被分配地址的,它是立即数,是写死到指令里面的。但是确实无法修改。
合法的l-value分为变量、指针和引用(C++),其中变量可以修改,指针可以通过解引用来修改内存地址,引用同理。


合法的r-value分为变量、拥有常量声明的变量、立即数。其中变量可以直接修改,拥有常量声明的变量可以通过指针修改,立即数无法修改(其实可以通过动态改写代码来做到)。

点评

不过r-value要当成l-value来用时才能被修改  发表于 2018-8-18 21:38
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-22 13:27:54 | 显示全部楼层
claws0n 发表于 2018-8-17 10:50
楼主,如果问题得以解决,请记得采纳最佳答案哦~

好的 ,不好意思哈  因为一直没有想明白,所以一直没有采纳
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-22 13:37:46 | 显示全部楼层
竟无语凝噎 发表于 2018-8-22 13:27
好的 ,不好意思哈  因为一直没有想明白,所以一直没有采纳

全部都不明白??

换一个情况,先不要管数据类型:有一个函数 f ,有两个参数 x, y。返回 z
比如
int fun(int x, int y)
{
    int z = x + y;
    return z;
}
可以理解?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-30 07:44

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表