关于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、输出结果为什么这样?
...全文
459 14 打赏 收藏 转发到动态 举报
写回复
用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();
}
求助为什么出错了?
内容概要:本文介绍了一个基于MATLAB实现的VMD-SVM联合模型,用于机械设备的故障诊断与分类预测。该方法结合变分模态分解(VMD)和支持向量机(SVM),首先利用VMD对原始振动信号等工业监测数据进行自适应分解,提取具有物理意义的本征模态分量,有效分离噪声与关键故障特征;随后通过时频域特征提取与PCA降维,构建高判别性特征集,并输入优化后的SVM分类器实现多类别、非线性故障的精准识别。项目涵盖完整的模型架构、参数优化策略及应对工程挑战的解决方案,并提供了部分MATLAB代码示例,支持实时预测、可视化展示与系统集成。; 适合人群:具备一定信号处理与机器学习基础,从事工业故障诊断、智能运维、智能制造等相关领域的科研人员、工程技术人员及研究生;熟悉MATLAB编程者更佳; 使用场景及目标:①解决复杂工况下设备故障信号的特征提取与分类难题;②实现旋转机械、电力设备等多类型装备的智能健康监测与预测性维护;③构建高鲁棒性、可扩展的故障诊断系统; 阅读建议:建议结合文中提供的代码示例与完整程序(含GUI设计)进行实践操作,重点关注VMD参数调优、特征构造与SVM多分类实现过程,同时可拓展至迁移学习与边缘部署以提升工程应用价值。
传送带损坏与对象检测数据集 一、基础信息 • 数据集名称:传送带损坏与对象检测数据集 • 图片数量: 训练集:645张图片 验证集:185张图片 测试集:92张图片 总计:922张工业监控图片 • 训练集:645张图片 • 验证集:185张图片 • 测试集:92张图片 • 总计:922张工业监控图片 • 分类类别: Hole(孔洞):传送带表面的孔洞损坏。 Human(人类):工作区域中的人类,用于安全监控。 Other Objects(其他对象):非预期对象,可能引起故障。 Puncture(刺穿):传送带被刺穿的损坏。 Roller(滚筒):传送带滚筒部件。 Tear(撕裂):传送带撕裂损坏。 impact damage(冲击损坏):由于冲击导致的损坏。 patch work(修补工作):已修补的区域。 • Hole(孔洞):传送带表面的孔洞损坏。 • Human(人类):工作区域中的人类,用于安全监控。 • Other Objects(其他对象):非预期对象,可能引起故障。 • Puncture(刺穿):传送带被刺穿的损坏。 • Roller(滚筒):传送带滚筒部件。 • Tear(撕裂):传送带撕裂损坏。 • impact damage(冲击损坏):由于冲击导致的损坏。 • patch work(修补工作):已修补的区域。 • 标注格式:YOLO格式,包含边界框和类别标签,适用于目标检测任务。 • 数据格式:图像数据来源于工业监控系统,适用于计算机视觉分析。 二、适用场景 • 工业自动化检测系统开发:用于构建自动检测传送带损坏和异物的AI模型,实现实时监控和预防性维护,减少停机时间。 • 安全监控应用:识别人类和其他对象,提升工业环境的安全性,避免事故和人员伤害。 • 学术研究与创新:支持计算机视觉在制造业、物流和自动化领域的应用研究,促进AI技术与工业实践的融合。 • 教育与培训:可用于培训AI模型或作为工业工程和自动化教育的案例数据,帮助学习者理解实际应用场景。 三、数据集优势 • 多样化的类别覆盖:包含8个关键类别,涵盖多种损坏类型和对象,确保模型能够处理各种实际工业场景,提升泛化能力。 • 精准的标注质量:采用YOLO格式,边界框标注准确,由专业标注人员完成,保证数据可靠性和模型训练效果。 • 强大的任务适配性:兼容主流深度学习框架(如YOLO、TensorFlow、PyTorch),可直接用于目标检测任务,并支持扩展至其他视觉任务需求。 • 突出的工业价值:专注于工业传送带系统的实际需求,帮助提升生产效率、降低维护成本,并增强工作场所安全,具有较高的实际应用价值。

65,207

社区成员

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

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