理解c和c++的复杂类型声明 (掺杂指针)

首先,让我们看看指针与const结合的声明:
const int *p;      //p是指向常整形的指针
int const *p;     //错误
int * const p;   //p是指向整形的常指针
const int * const p;    //p是指向常整形的常指针
怎么样?希望大家不会搞混吧,下面我会告诉大家如何去理解,但是写到这里,我突然想起const的一些东西,这里先插个小插曲,-_-
相信大家在学习C++时也见到过用const修饰函数的,如:
const int Fun();
int Fun() const;
最后那个表示Fun函数是常成员函数(c++类中),既Fun函数不能修改类中的成员变量和成员函数,这个在大家学习MFC中会经常看到的,举个例子:如HWND GetDlgItem(ID) const;这里就不详细说下去了,大家知道这么个事就行了。

回到主题,要想很清楚的理解声明,
一、我们先从编译器中的声明器(declarator)说起,什么是声明器?简单来说,声明器就是标识符和与它组合一起的任何指针、函数括号、数组下标等(定义请参考《c专家编程》),合法的声明存在以下的限制:
1、函数的返回值不能是个函数或数组,所以fun()()和fun()[]是非法的
2、数组里不能有函数,所以fun[]()是非法的

二、优先级规则
A、声明从它的名字开始读取,然后安装优先级从高到低读取
B、优先级高低顺序:
   B1、声明中被括号括起来部分
   B2、后缀操作符:()表示函数  []表示数组
   B3、前缀操作符:*表示指向...的指针
C、如果const和(或)volatile后面紧跟类型(如int等),则const和(或)volatile修饰类型,否则const和(或)volatile修饰紧跟在他们左边的*指针。

根据上面的优先级规则,我们来进行下面的练习:
char * const * (*p)();
1、根据A规则,从p入手,得到p是...;
2、根据B1规则,(*p),得到p是指针,指向...;
3、根据B2规则,()函数下标优先于*,所以(*p)(),得到p是指针,指向一个函数,该函数返回...
4、根据C规则知道const是修饰它左边的*不是右边,所以右边的*应该是函数的返回值,故得到p是指针,指向一个函数,该函数返回另外一个指针,该指针指向...
5、根据C规则知道指针指向一个类型为char的常指针。
6、综上述,得到p是指针,指向一个函数,该函数返回另外一个指针,而该指针指向一个类型为char的常指针。
大功告成!!!!!

以下给出些练习,巩固下,答案以后给:
1、char * (*array[10]) (int **p)
2、void (*signal(int sig, void(*fun)(int)))(int)

呵呵,相信大家对上面那些声明也非常厌恶,那么我们来找解决办法吧,那就是使用typedef,比如对上面的练习中void (*signal(int sig, void(*fun)(int)))(int),用typedef来使用就是:typedef void (*ptr_to_fun)(int)
            ptr_to_fun signal(int, ptr_to_fun)
这样估计就清楚了吧!
说到这,有些朋友会说:能不能用#define来解决呢??很好,是可以的啦,但是不好,为什么?很多朋友可能都知道了,因为#define只是简单的符号替换,不进行类型检查,另外一些如##define max ((x)>(y)?(x)y))这些会带来种种不好,这里就不多说了,反正我除了为常量使用#define外,我都不用#define。

好了,大家看完后,可以休息,也可以看下上面练习的答案,检查下,有疑问的请跟帖提出:
1、array是个数组,该数组的元素是指针,该指针指向一个函数,这个函数的参数是指向指针的指针p,函数返回另外一个指针,而这个指针又指向char类型。
2、fun是个函数指针,函数的参数是int,返回值是void,signal是个函数,其中一个参数是int,另外一个参数是fun,返回另一个指向函数的指针,该函数参数为int,返回void(其实就是fun)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值