C语言中的指针类型——从简单幼稚到变态疯狂

说实话,接触C已经很多年了,但是我对C里面的指针类型依然缺乏一个系统的概念,最近翻阅了一些资料,把这个东西好好再研究了一次,现在就来总结一下。

C语言中的指针类型——从简单幼稚到变态疯狂


关于上面表中的定义式,不知你看明白没有?

其中 :

        int (*f[])(); 和  int **(*f[])(); 还有 int **(*(*f[])())[10], 都存在未定义长度的数组表达形式,这在两种情况下是合法的,即:用extern标识链接属性和作为函数参数时,如果直接在代码内定义未加extern,那么需要填充长度(即使是一个之前声明过的整数变量),例如:int **(*(*f[5])())[10]; or int n = 2; int **(*(*f[n])())[10];

        倒数第三个例子, int *(*(*f)())[10](),其实是错误的,对于编译器是非法的。虽然编译器能够分析它的逻辑含义,但是无法产生对应的代码。你会见到诸如:error: declaration of ‘f’ as array of functions 这样的编译错误信息。在这里,编译器认为这段代码中 最后部分的 [10]()定义了一个关于函数的数组,又因为这一段代码是关于f的定义,所以它会理解成你试图在定义f为关于函数的数组,这里它直接将f与函数的数组两个概念连接起来,而不同的函数可能具有不同的长度,数组的元素必然是具有一致的长度,所以它报出了错误。编译器就是这种尿性,你只能顺从。 而如果将它稍微改一改,成为诸如 int (*(*(*f)())[10])(); 或者 int (*(*(*f)()))(); 这样的形式,又是合法的(有没有兴趣解析一下其意义?)。 

      刚接触上面这些不同种类的指针或者数组时,我的内心也是崩溃的,写程序很多年了,早已在实际编码中了解到几乎没有可能接触到后面的几种类型。够用就好,这就是对待写代码的知识的实用法则,这次我主要把它们作为一种训练。

      其实还有更更变态的指针相关的类型存在,而且就在一些高人写的外星代码里面。这些代码放在那里,不需要经常维护,所以也就不存在很多常见的麻烦。多级间接指针是相当消耗性能的,比如帮助C++实现多态的虚函数表vtable,它的性能就要差些,如果实际编码中确实要用到多级指针,建议不要用在多次执行的迭代和循环中,一次或者整个程序运行期间只会少量运行的场合,比如模块初始化,是可以用的,前提是你知道自己在干什么,并且不太影响后期理解和维护。

本文参考(帮助非常大,墙裂推举):

         1 .  《Pointer On C》 --Kenneth A.Reek 1998

         2.  《让你不再害怕指针——C指针详解(经典,非常详细)》,原出处没有搜到,我是看的这里的转载。