OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6365|回复: 17

其实这是一个C语言函数指针相关的问题,这个问题在我脑子里一直盘旋了很久,恳请大神解答我心中的疑惑~

[复制链接]

119

主题

439

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1185
金钱
1185
注册时间
2015-9-18
在线时间
422 小时
发表于 2015-10-14 14:15:38 | 显示全部楼层 |阅读模式
5金钱

例如我现在看的原子哥的内存管理实验(探索者开发板)
其中有如下的一个结构体

1>这是该实验中的一个结构体

[mw_shl_code=c,true]struct _m_malloc_dev { void (*init)(u8); /* 就以这个来说明吧 */ u8 (*perused)(u8); u8 *membase[SRAMBANK]; u16 *memmap[SRAMBANK]; u8 memdry[SRAMBANK]; };[/mw_shl_code]


2>以其中第一个成员为例,我们对这个函数指针进行初始化, 初始化结构体指针为my_mem_init

3>于是:我们就需要定义如下一个函数
void my_mem_init(u8 memx)
{
}
请问大神:按照前面的函数指针定义:我觉的这个函数应该采用如下形式
void (*my_mem_init)(u8 memx)
{
}
是我哪里理解错了,恳请大神指教


最佳答案

查看完整内容[请看2#楼]

回复【7楼】小温: --------------------------------- 感谢这位大神的细心指导~
电子爱好者
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

119

主题

439

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1185
金钱
1185
注册时间
2015-9-18
在线时间
422 小时
 楼主| 发表于 2015-10-14 14:15:39 | 显示全部楼层
回复【7楼】小温:
---------------------------------
感谢这位大神的细心指导~
电子爱好者
回复

使用道具 举报

19

主题

702

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3339
金钱
3339
注册时间
2013-7-30
在线时间
708 小时
发表于 2015-10-14 14:29:59 | 显示全部楼层
struct   _m_malloc_dev   malloc_dev;

void my_mem_init(u8 memx)
{
}

malloc_dev.init = my_mem_init;

函数名可以直接赋值给函数指针变量
思想很重要,无论做人还是编程!
我的技术公众号【微联智控工作室】
回复

使用道具 举报

119

主题

439

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1185
金钱
1185
注册时间
2015-9-18
在线时间
422 小时
 楼主| 发表于 2015-10-14 14:47:13 | 显示全部楼层
回复【2楼】小温:
---------------------------------
是啊,函数名可以直接赋值给函数指针变量,
那么如上的void  (*init)(u8) 函数直接将init换成my_mem_init,不就变成了 void (*my_mem_init)(u8)了嘛
电子爱好者
回复

使用道具 举报

70

主题

6758

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
12995
金钱
12995
注册时间
2012-11-26
在线时间
3790 小时
发表于 2015-10-14 14:55:28 | 显示全部楼层
回复【3楼】liuchang:
---------------------------------
结构体里  表明 此处是指针类型

函数名即是指针  

剩下的自己想吧
学无止境
回复

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2015-10-14 14:55:33 | 显示全部楼层
自己对指针也不是很熟悉,以下仅是当前认识,自己也不十分确认,欢迎讨论

void perused(u8);  //一般函数定义,perused为函数名(已固定)
void *perused(u8);  //返回(void *)指针函数,perused为函数名(已固定)
void (*perused)(u8);  //一般函数定义,perused为指向函数的指针,可被重新赋值

而函数名本身就是一个指针
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2015-10-14 14:57:19 | 显示全部楼层
int *p;p是int型指针,那么p指向的就是int型变量。定义这种变量时就是这样:int  a;

同理,
void  (*init)(u8);init指向的就是void  XX(u8)型的函数。定义这种函数时就是这样:void f(u8 a);
小小蜗牛
回复

使用道具 举报

19

主题

702

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3339
金钱
3339
注册时间
2013-7-30
在线时间
708 小时
发表于 2015-10-14 14:58:23 | 显示全部楼层
回复【3楼】liuchang:
---------------------------------
结构体里面的成员变量只是用作声明,你没有定义一个结构体变量的话,编译器是不会为每个成员分配内存空间的,也就是你不能直接在结构体里面对其成员进行初始化,如果你要进行  “void  (*init)(u8) 函数直接将init换成my_mem_init,不就变成了 void (*my_mem_init)(u8)”   这项操作,那么“my_mem_init” 也只是一个指针变量,到后面,你还要对这个指针进行赋值
思想很重要,无论做人还是编程!
我的技术公众号【微联智控工作室】
回复

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2015-10-14 15:59:29 | 显示全部楼层
回复【6楼】jiutianshenjian:
---------------------------------
如果直接void  init(u8);和void  (*init)(u8);有什么区别呢?直接void  init(u8);时init是什么含义,进行void f(u8 a);类函数赋值是否可以?
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复

使用道具 举报

119

主题

439

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1185
金钱
1185
注册时间
2015-9-18
在线时间
422 小时
 楼主| 发表于 2015-10-14 17:12:37 | 显示全部楼层
回复【9楼】龙之谷:
---------------------------------
按照我现在的理解:例如我们定义指针p,是采用如下方式 
int *p,
而我们在使用这个指针的时候,却不用加修饰,a=p(而不是写成a=(int *)p
这也就是为什么我们使用void my_mem_init(u8)(而不是(*my_mem_init)(u8)的原因了吧)
电子爱好者
回复

使用道具 举报

119

主题

439

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1185
金钱
1185
注册时间
2015-9-18
在线时间
422 小时
 楼主| 发表于 2015-10-14 17:13:38 | 显示全部楼层
还请各位大神看看小弟理解的是不是有问题~
电子爱好者
回复

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2015-10-14 17:21:26 | 显示全部楼层
回复【10楼】liuchang:
---------------------------------
类比int a;

int *p;即(int *)p;
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2015-10-15 15:15:42 | 显示全部楼层
回复【9楼】龙之谷:
---------------------------------
函数名是函数的地址是个常量。
函数指针是变量,可以被赋值。
小小蜗牛
回复

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2015-10-15 15:37:00 | 显示全部楼层
回复【13楼】jiutianshenjian:
---------------------------------
多谢指导,我概念有些混淆了,还需要补充一下C了

--------------------------------------------------------------

搜了一下函数名,留个函数名与函数指针的链接备用:http://www.cnblogs.com/CBDoctor/archive/2012/10/15/2725219.html
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2015-10-15 15:42:13 | 显示全部楼层
回复【10楼】liuchang:
---------------------------------
a=(int *)p 是强制转换,跟本贴关系不大。

你的例子用变量来说是这样:
有个指针int *p1;你想给这个p1赋值(或是你说的初始化)。
你又int *p2;然后你使p1=p2;这就叫赋值了?
p1,p2都是未被初始化的指针,你怎么能拿p2去初始化p1?

你应该这样做:
int a;
int *p = &a;

这样p就被初始化了,有了具体的指向。

函数指针同理:
你想初始化void  (*init)(u8);
你就得定义一个void  abc(u8 c);
然后可以使init = &abc;
由于函数名本身就是函数的地址,所以就写成init = abc;就可以了.
小小蜗牛
回复

使用道具 举报

119

主题

439

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1185
金钱
1185
注册时间
2015-9-18
在线时间
422 小时
 楼主| 发表于 2015-10-15 15:54:11 | 显示全部楼层
回复【15楼】jiutianshenjian:
---------------------------------
首先感谢大神指导~
如大神所说:函数名本身就是地址
那不应该使用init= abc嘛
那init=&abc,不就是地址的地址嘛,那不应该是二级指针的概念了吗
小弟就是对这个没有办法理解~(其实我一开始提问的问题也就是这个问题)
电子爱好者
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2015-10-15 16:18:33 | 显示全部楼层
回复【16楼】liuchang:
---------------------------------
这个你可以参考楼上给的资料。我理解这里就是这么规定的。
数组名本身也是地址,加&符号也是同一个地址,只不过范围大了。
小小蜗牛
回复

使用道具 举报

16

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
140
金钱
140
注册时间
2015-2-12
在线时间
10 小时
发表于 2016-8-2 14:53:11 | 显示全部楼层
不错。。。。。
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-27 23:11

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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