优先级问题
一元运算符*
和&
的优先级比算术运算符
的优先级高,且*
和++
这样的一元运算符遵循从右至左
的结合顺序。例如:
++*ip
等同于(*ip)++
,它们都表示将ip指向的对象的值加1,但其中的圆括号是必须的,否则,该表达式将对ip进行加一运算,而不是对ip指向的对象进行加一运算。
指针与数组
数组名所代表的是该数组最开始的一个元素的地址,如果我们有:
int a[10];
int *pa;
赋值语句pa = &a[0]
也可以写成pa = a
这种形式。但数组名不是变量,a = pa
和a++
形式的语句是非法的。
在函数定义中,指针和数组作为形参是等价的。比如char s[]
和char *s
。
多维数组
二维数组实际上是一种特殊的一维数组,它的每个元素也是一个一维数组。如果将二维数组作为参数
传递给函数
,那么在函数的参数声明中必须指明数组的列数
,而行数
没有太大关系,因为函数调用时传递的是一个指针。所以,函数声明
f(int daytab[2][13]) { ... }
也可以写成
f(int daytab[][13]) { ... }
还可以写成
f(int (*daytab)[13]) { ... }
这种声明形式表明参数是一个指针,它指向具有13个整形元素的一维数组。
复杂声明
来看个例子。
char (*(*x())[])()
中的x
是什么类型?
首先,从最外部开始。因为是形如char f()
的形式,所以(*(*x())[])
是一个函数,这个函数返回类型为char
;
接下来,发现是形如*a[]
的形式,所以我们知道,(*x())
是一个指针数组,数组的每个元素是指向之前函数的指针;
最后,容易知道*x()
是一个返回指针类型的函数,所以x
是函数,返回类型是指向之前数组的指针;
综上,我们得到:我们声明,x是一个函数,它的返回类型是一个指向数组的指针,该数组中的每个元素都是指向返回类型为char
的函数的指针。