关于typedef与函数指针求解

wudichaoren2010 2014-11-30 03:35:51
为复杂的声明定义一个新的简单的别名。

方法是:在原来的声明里逐步用别名替换一部分复杂声明

如此循环,把带变量名的部分留到最后替换,得到的就是原声明的最简化版。

举例:

原声明

void (*b[10]) (void (*)());

1、这个代码怎么理解?
返回值是void
(*b[10])怎么理解,数组b中第十一个元素的指针?
(void (*)())怎么理解,函数指针?


变量名为b,先替换右边部分括号里的,pFunParam为别名一:

typedef void (*pFunParam)();

再替换左边的变量b,pFunx为别名二:

typedef void (*pFunx)(pFunParam);

原声明的最简化版:

pFunx b[10];

2、最后怎么就变成这样了?

原声明

doube(*)() (*e)[9];

3、这代码怎么理解?

变量名为e,先替换左边部分,pFuny为别名一:

typedef double(*pFuny)();

再替换右边的变量e,pFunParamy为别名二

typedef pFuny (*pFunParamy)[9];

原声明的最简化版:


pFunParamy e;


理解复杂声明可用的“右左法则”:从变量名看起,先往右,再往左,碰到一个圆括号

就调转阅读的方向;括号内分析完就跳出括号,还是按先右后左的顺序,如此循环,直

到整个声明分析完。举例:

int (*func)(int *p);

首先找到变量名func,外面有一对圆括号,而且左边是一个*号,这说明func是一个指针

;然后跳出这个圆括号,先看右边,又遇到圆括号,这说明(*func)是一个函数,所以

func是一个指向这类函数的指针,即函数指针,这类函数具有int*类型的形参,返回值

类型是int。

int (*func[5])(int *);

func右边是一个[]运算符,说明func是具有5个元素的数组;func的左边有一个*,说明

func的元素是指针(注意这里的*不是修饰func,而是修饰func[5]的,原因是[]运算符

优先级比*高,func先跟[]结合)。跳出这个括号,看右边,又遇到圆括号,说明func数

组的元素是函数类型的指针,它指向的函数具有int*类型的形参,返回值类型为int。

这种用法是比较复杂的,出现的频率也不少,往往在看到这样的用法却不能理解,相信以上的解释能有所帮助。
——————————————
4、typedef有什么用,没看出来


void (*funcp)();
void FileFunc(),EditFunc();

main()
{
funcp=FileFunc;
(*funcp)();
funcp=EditFunc;
(*funcp)();
}

void FileFunc()
{
printf(FileFunc\n);
}

void EditFunc()
{
printf(EditFunc\n);
}

程序输出为:
FileFunc
EditFunc

5、输出结果为什么这样?
...全文
435 14 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
「已注销」 2014-12-08
  • 打赏
  • 举报
回复
1 void (*b[10]) (void (*)()); ------------------- 首先可以知道,标识符b表示一个数组, 标识符b表示一个数组,数组的元素是指针,指针指向函数,函数返回值类型是void (参数是。。。)
「已注销」 2014-12-08
  • 打赏
  • 举报
回复
引用 9 楼 allenltiverson 的回复:
请原谅我顶着狗蛋说我工作三年了还没用过这些东西。哪怕搞懂了实用价值也不大。这种东西也就大学或者考试或者笔试让出题者显示优越感,让我们拥有挫败感外,真不觉得有什么用
你在健身房里,20分钟就做一个动作,你在实际生活里根本不会这么去做。 这就是基本功,无论多复杂的声明,你也应该跟读母语一样轻松。
xionggch 2014-12-08
  • 打赏
  • 举报
回复
Jinhao 2014-12-08
  • 打赏
  • 举报
回复
引用 8 楼 wudichaoren2010 的回复:
其实我也不想学这么快,但是就是教得这么速度,大学还有其他一堆课,消化都很困难
这是基本功,能往快的学就往快的学
赵4老师 2014-12-08
  • 打赏
  • 举报
回复
此乃无用之用!
allenltiverson 2014-12-07
  • 打赏
  • 举报
回复
请原谅我顶着狗蛋说我工作三年了还没用过这些东西。哪怕搞懂了实用价值也不大。这种东西也就大学或者考试或者笔试让出题者显示优越感,让我们拥有挫败感外,真不觉得有什么用
wudichaoren2010 2014-12-07
  • 打赏
  • 举报
回复
其实我也不想学这么快,但是就是教得这么速度,大学还有其他一堆课,消化都很困难
fztfztfzt 2014-12-01
  • 打赏
  • 举报
回复
先照着书上敲代码吧。。。。。 你这基础都还没学好啊 你前面的问题自己都解答了啊 后面的问题看看指针,看看别人怎么用的
纹枰老妖 2014-12-01
  • 打赏
  • 举报
回复
引用 6 楼 bear234 的回复:
回答你两个问题: void (*b[10]) (void (*)()); 这种东西很吓人但是其实很简单,因为编程都是死的,规律永远是不变的 两个原则: 1)从声明的量开始,逐步挖去已知的,看剩下的是什么 2)明确运算符的优先级 首先看这里声明了谁? 声明了b b是什么? 挖去b 剩下了void (*[10]) (void (*)()); 因此void (*[10]) (void (*)())就是b的类型 想知道这到底是什么类型,就要看与b结合的运算符顺序 b左边是* 右边是[] []的优先级高于* 所以b先和[]结合 因此,b是数组------------到这里,我们明确了这里声明了某种类型的数组 然后,挖去b[] 剩下了void (*) (void (*)()); 被挖去的部分再和左面的*结合,因此成了指针 因此,b是一个数组,其中每个元素都是一个指针 再挖 void () (void (*)()); 可以看到这是一个函数 因此b是一个数组,每个元素都是一个指针,每个指针都指向这样一个函数: 其返回值是void 参数列表是void (*)() 然后再看参数列表:void (*)() 由于是声明,因此省略了形参,故我们先加上形参(这样容易看),变成了void (*a)() 根据上面的两个原则,容易看出a是一个指针,这个指针指向一个函数,这个函数的返回值是void,没有参数 因此,b是一个数组,每个元素都是一个指针,每个指针都指向“返回值是void、参数是一个指向‘返回值是void、没有参数的函数’的指针”的函数 很简单吧~~ 关于typedef,我只说一句话,typedef不是简单的文本替换,具体怎么用自己多练习吧~~
看着都头晕
bear234 2014-12-01
  • 打赏
  • 举报
回复
回答你两个问题: void (*b[10]) (void (*)()); 这种东西很吓人但是其实很简单,因为编程都是死的,规律永远是不变的 两个原则: 1)从声明的量开始,逐步挖去已知的,看剩下的是什么 2)明确运算符的优先级 首先看这里声明了谁? 声明了b b是什么? 挖去b 剩下了void (*[10]) (void (*)()); 因此void (*[10]) (void (*)())就是b的类型 想知道这到底是什么类型,就要看与b结合的运算符顺序 b左边是* 右边是[] []的优先级高于* 所以b先和[]结合 因此,b是数组------------到这里,我们明确了这里声明了某种类型的数组 然后,挖去b[] 剩下了void (*) (void (*)()); 被挖去的部分再和左面的*结合,因此成了指针 因此,b是一个数组,其中每个元素都是一个指针 再挖 void () (void (*)()); 可以看到这是一个函数 因此b是一个数组,每个元素都是一个指针,每个指针都指向这样一个函数: 其返回值是void 参数列表是void (*)() 然后再看参数列表:void (*)() 由于是声明,因此省略了形参,故我们先加上形参(这样容易看),变成了void (*a)() 根据上面的两个原则,容易看出a是一个指针,这个指针指向一个函数,这个函数的返回值是void,没有参数 因此,b是一个数组,每个元素都是一个指针,每个指针都指向“返回值是void、参数是一个指向‘返回值是void、没有参数的函数’的指针”的函数 很简单吧~~ 关于typedef,我只说一句话,typedef不是简单的文本替换,具体怎么用自己多练习吧~~
QIUSQJF 2014-12-01
  • 打赏
  • 举报
回复
可以看看<C专家编程>
ztenv 版主 2014-12-01
  • 打赏
  • 举报
回复
第一个问题:去看看“右左原则”
赵4老师 2014-12-01
  • 打赏
  • 举报
回复
仅供参考
//char (*(*x[3])())[5];//x是什么类型的变量?
//
//分析C语言声明,关键是搞清楚这个变量是个什么东西(函数、指针、数组),
//是函数那么剩下的就是他的参数和返回值,
//是指针那剩下部分是说明他指向什么,
//是数组剩下的部分就是说明数组的成员是什么类型。
//解析C语言声明规则:
//从左侧第一个标识符开始,按照优先级进行结合。*表示是..的指针,const表示只读的,volatile表示可变的,[]表示是数组,()表示是函数。
//
//x和[3]结合说明是一个大小为3的数组,该数组的每个元素为一类指针,该类指针指向一类函数,该类函数无参数,返回一类指针,该类指针指向一个大小为5的char型数组
#include <stdio.h>
#include <typeinfo.h>
char num[5];
char (*x00())[5] {
    return #
}
int main() {
    char (*x000)[5];//返回值
    char (*(x00)())[5];//函数原型,参数为空,返回值为指针
    char (*(*x0)())[5];//数组的元素,是个函数指针
    char (*(*x[3])())[5];//是个数组,大小为3

    x0 = x00;
    x[0] = x0;
    x[1] = x0;
    x[2] = x0;
    printf("typeid(x).name() is %s\n",typeid(x).name());
    return 0;
}
//typeid(x).name() is char (* (__cdecl**)(void))[5]
wudichaoren2010 2014-11-30
  • 打赏
  • 举报
回复

#pragma once
#include <iostream>
using namespace std;
class SimpleCircle
{
	
	double Circle;
public:
	SimpleCircle():Circle(0){cout<<"构造"<<endl;};
	~SimpleCircle(void);
	inline void show(){cout<<Circle<<endl;}
};

#include "SimpleCircle.h"




SimpleCircle::~SimpleCircle(void)
{
}

void main()
{
	SimpleCircle *s=NULL;
	s->show();
}
求助为什么出错了?

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧