这里主要是关于如何查看指针声明的笔记。参考文章为《C和指针》,高级指针,p258-p260。
基本声明
这里我们先看一个最简单的声明和变体
int f;//一个整形变量
int *f;//一个指向整型的指针,这里把*f声明为一个整数,所以f是一个指针,*表示间接访问
在这里或者这样子写
int* f;
所以综上所述,我们要强调*是间接访问符号,而不是指针声明符号
接下来我们看下面这个例子
int* f,g;//在这个声明中f是指针,而g是整数,所以"正确"的写法是
int *f,g;//*只与f进行结合,而不与g进行结合
然后是稍微复杂一点的声明
int *f()//这里*f()是一个整型,所以f()是一个指针,f则是一个函数,()是用于显式说明f的类型。
所以在这里是声明了一个函数,其返回值是int* 就是整型指针。
int* f()//等价
对于这个声明,首先先看小括号(),优先级高于间接访问符号*,因此f首先是一个函数,它的返回值是一个指向整型的指针。在这里是一个推论声明:用于声明变量的表达式和普通表达式在求值时所使用的规则相同。
这里还能总结出一个小技巧,以空格为界,左边是返回值,右边则是具体的表达式,如果返回类型阻碍空格后面马上跟着*,则返回值是 类型*
int (*f)()//空格后面没有马上跟着*,则返回值是int
//都有小括号先看最右边,首先这是一个函数调用符号(习惯上这是第二个括号),说明(*f)是一个函数。较左边(第一个括号)起到聚组的作用,它迫使间接访问在函数调用之前进行。这时候我们再不看间接操作符号,则可以推断出f是一个函数指针,返回值是int
变体
int *(*f)()//在上面的基础上,f是函数指针,指向一个返回值是int*的函数
关于数组符号
int f[]//整型数组,此时不关心数组长度,f是一个数组,数组内容是int
接下来要记住,下标的优先级更高。
int *f[]//f是一个数组,数组里面存的东西是int*
两个非法声明
不要纠结这块,解释有点抽象,尤其第二条
//这里先看f与谁结合就是什么声明
int f()[]//首先f是一个函数,其次返回值是一个数组,然而函数只能返回标量,指针也是个标量,其本质是地址位置
int f[]()//f似乎是一个数组,数组类型是返回值是int的函数,“然而数组元素必须拥有相同的长度,不同的函数显然可能具有不同的长度”,这里我没读懂。
合法声明
前面已经指明了两个非法声明,那么剩下的合法的可以粗暴点用下面的规律查看声明:
首先记住一点,没有出现多个小括号的,和数组混用是不允许的。
其次,看f首先和谁结合,如果跟着[],那首先是个数组,如果前面又跟着间接符号,那么这个具体字母(f or g et,al)是一个指针数组。
int (*f[])()// 我们按照之前的看法,可以先确定第二个()是一个函数操作符号,这个函数返回的是int。
//再来看第一个小括号,*f[],是一个表达式,*表示间接访问,因此f[],这个整体是一个指针
//由于没有指出具体个数,不妨假设就一个长度,当然这只是作为判断的技巧。
//再看f结合的[],说明f是一个元素为某种类型的指针的数组(装着指针的数组)。
//所以f首先是一个数组,数组元素是函数指针,它指向的函数的返回值是整型
//变体
int *(*f[])()//这里唯一变化的其实是函数返回的类型是int*了。因此,这是一个指针数组,指针所指向的类型是返回值为整型指针的函数
现代的声明风格
现在对于声明,尤其是包含函数的,需要明确接受的类型
int (*f)(int,float)//f是函数指针,指向的函数接受值是int,float。返回类型是int
int *(*g[])(int,float)//g首先是一个xx指针数组,后面有()函数操作符号。
//g是一个数组,数组的元素类型是函数指针,它所指向的函数接受int和float两个变量,并返回一个int*
总结
这里是对于指针数组,函数指针,函数指针数组的声明。
int *f[]// 首先f与[]结合,所以是数组,*间接引用,说明f[]装的是指针,所以这是一个指针数组
int (*f)(type,type..)//*f()是一个返回值是int的函数,所以f(type,type..)是一个返回值是指针的函数,因此f是一个函数指针
int *f(type,type..)//返回值是int*的函数,f是一个简单的函数
int (*f[])(type,type..)//f是一个函数指针数组
904

被折叠的 条评论
为什么被折叠?



