おたくのスタジオ

C和指针

优先级问题

一元运算符*&的优先级比算术运算符的优先级高,且*++这样的一元运算符遵循从右至左的结合顺序。例如:

++*ip等同于(*ip)++,它们都表示将ip指向的对象的值加1,但其中的圆括号是必须的,否则,该表达式将对ip进行加一运算,而不是对ip指向的对象进行加一运算。

指针与数组

数组名所代表的是该数组最开始的一个元素的地址,如果我们有:

int a[10];
int *pa;

赋值语句pa = &a[0]也可以写成pa = a这种形式。但数组名不是变量,a = paa++形式的语句是非法的。

在函数定义中,指针和数组作为形参是等价的。比如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的函数的指针。