【 C 】高级指针话题之高级声明的演进
在使用更高级的指针类型之前,我们必须观察它们是如何声明的。
下面通过观察一系列越来越复杂的声明来探讨这个话题:
int f; //一个整型变量
int *f; //一个指向整型的指针
这两个例子十分简单,我们来看下第2个声明是如何工作的,这对后面理解更复杂的声明非常重要。
它把表达式 *f 声明为一个整数。根据这个事实,你肯定能推断出 f 是个指向整型的指针。
C 声明的这种解释方法可以通过下面的声明得到验证。
int * f, g;
它并没有声明两个指针。尽管 * 和 f 之间存在空白,但是 * 是作用于 f 的,只有 f 才是一个指针, g 只是一个普通的整型变量。
下面是另外一个例子:
int f();
它把 f 声明为一个函数,它的返回值是一个整数。 旧式风格的声明就函数的参数并未提供任何信息。 它只是声明 f 的返回值类型。现在,我们将使用这种旧式风格,这样可以使例子看上去简单一些,后面我们在回到完整的原型形式。
下面是一个新例子:
int *f();
要想推断出这个函数原型的含义,你必须确定表达式 *f() 是如何进行求值的。首先执行的是函数调用操作符 (),因为它的优先级高于间接访问操作符。因此 f 是一个函数,它的返回值类型是一个指向整型的指针。
接下来的一个声明更有趣,但也更容易让人疑惑:
int (*f)();
确定括号的含义是分析这个声明的一个重要步骤。这个声明有两个括号,每对的含义各不相同。第2个括号是函数调用操作符,第1个括号只起到聚组的作用。它迫使间接访问在函数调用之前进行,使 f 成为一个函数指针,它所指向的函数返回一个整型值。
何为函数指针?
程序中的每个函数都位于内存中的某个位置,所以存在指向那个位置的指针是完全可能的。后面有博文专门介绍函数指针。
int *(*f)();
这个声明和上一个声明基本相同,只是函数的返回值需要经过间接访问才能得到一个整型值。
下面我们把数组也考虑进去。
int f[];
我们都知道这个声明,表示f是一个整型数组。数组的长度暂时省略,因为我们现在只关心它的类型,而不是它的长度。
需要注意的是,如果数组是作用于函数的参数(作为函数的形参),这个声明也是合法的。
下面这个声明呢?
int *f[];
下标的优先级更高,所以f是一个数组,它的元素类型是指向整型的指针。
说了这么多,大家别以为类型的声明是一个随心所欲的事情,下面就给出几个非法的声明见识见识!
int f()[];
真可怕!
我们来分析下:首先f是一个函数,可是之后呢?解释不通了呀!如果非要解释,它的返回值是一个数组?可是函数只能返回标量啊,不能返回数组。因此这个声明无论怎么说都是非法的。
再给一个:
int f[]();
现在,它似乎是一个数组,它的元素类型是返回值为整型的函数?同上面所说的一样,这样也是非法的。
看了上面的两个例子,简直毛骨悚然!这种奇葩的声明简直让人费神!不过为了锻炼下自己,再看几个合法的:
int ( *f[] )();
强行装一波:先看第一个括号内的内容,可知,f是一个数组,且要对数组进行间接访问操作,可见这个数组的元素是指针。表达式末尾的()是函数调用操作符,那么数组元素的类型是函数指针,且指向的函数的返回值是一个整型值。
最后一个超级变态的声明:
int *(*f[])();
与上面一个声明相比,多了一个间接访问操作符。
强行解释一波吧:这个声明创建了一个指针数组,指针所指向的类型是返回值为整型指针的函数。
和上面的声明的对比,上面声明的含义其实也是一个指针数组,这个指针是一个函数指针,指针指向的的类型是返回值为整型的函数。
结束结束!受不了了了。。。
文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。
原文链接:reborn.blog.csdn.net/article/details/82689086
- 点赞
- 收藏
- 关注作者
评论(0)