一篇教你轻松解析复杂的指针声明

一、指针运算符及其优先级

指针往往会和一些运算符结合使用,主要包括以下几种:

  • 指针声明:int *。
  • 取址运算符:&。
  • 间接访问运算符:*。
  • 自增自减运算符: ++、--。
  • 成员选择运算符:.、->。
  • 其他运算符: []、()。

这些运算符的优先级按照从高到低的顺序依次为:[]、()、.、->、++、--、*、&。

这里可以分析几个较为简单的指针表达式:

*p++;先间接访问指针p,然后p的值再自增
&p++;指针变量的地址自增运算
&stu.name;结构体成员变量name的地址
int *a[10];

定义一个指针数组,数组元素类型为int *

int (*a)[10];定义一个数组指针,指向数组类型int a[10]
int *f (int);定义一个指针函数,函数返回值为int *
int (*f)(int);定义一个函数指针,指向函数类型为int f(int)
int *(*f)([10];定义一个数组指针,指向数组类型为int *a[10]

二、左右法则

对于复杂的指针声明,我们可以借助“左右法则”来分析。

The right-left rule: Start reading the declaration from the innermost parentheses, go right, and then go left. When you encounter parentheses, the direction should be reserved.Once everything in the parantheses has been parsed, jump out of it. Continue till the whole declaration has been parsed.

翻译成中文就是:首先从最里面的圆括号(未定义标识符)看起,先往右看,再往左看,每当遇到圆括号时,就应该调转阅读方向。一旦解析完圆括号里所有东西,就跳出圆括号。重复这个过程,直到整个声明解析完毕。

这里我们根据左右法则再分析几个较为复杂的指针表达式:

int *(*(*f)(int))[10];

 首先从最里面的圆括号看起,(*f)说明了f是一个指针,也给整个表达式定了性,这个语句声明的是一个指针;再往右看(int)是一个参数列表,说明该指针类型是一个函数指针,函数的形参是(int);再往左看,*说明该指针指向的函数返回值是一个指针;此时圆括号已解析完毕,跳出圆括号,往右看是一个数组,说明返回值是一个指向数组的指针,再往左看是int *,即指针数组中的元素类型为int *。这其实等价于int *(*p)[10];

int (*f(int, int))[10];

 首先这是一个函数指针,指向的函数形参为(int,int),返回值为一个数组。

int (*(*f)(int, int))(int);

首先这是一个函数指针,指向的函数形参为(int,int),即指向函数类型为int *f(int, int),其次函数的返回值为一个函数指针,指向一个形参为(int)且返回int的函数,即指向函数类型为int *f(int)

 int (*f)(int *p, int, int (*fp)(int*, int));

首先这是一个函数指针,指向的函数形参为(int *p, int, int (*fp)(int*, int)),函数的返回值为int

 int (*(*f)[10])(int *p);

 首先这是一个数组指针,指向数组类型为int *a[10],其中的元素为int *p类型。

 剩下一个可以尝试自行分析一下:

(*(void(*)())0) ();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

趣多多代言人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值