概述
本文深入介绍了与指针和数组相关的运算符优先级,利用代码示例展示了当左结合和右结合运算符同时存在时的结合方式,同时也演示了如何使用()来强制人为指定结合顺序。
指针、数组相关的运算符优先级
下表展示了相关运算符的优先级,有4个级别,同级别内的运算符按照结合性依次调用。这4类也是所有运算符中优先级最高的4档,其它的运算符优先级都比它们低:
优先级 | 运算符 | 描述 | 结合性 |
---|---|---|---|
1 | :: | 作用域解析 | 左结合 |
2 | () [] . -> |
强制运算结合,函数形参列表 数组元素下标访问 类的成员访问 类指针的成员访问 |
右结合 |
3 | (int) * & |
强制转换 指针解引用 变量取地址 |
左结合 |
4 | .* ->* |
类的成员指针 类指针的成员指针 |
左结合 |
容易产生困惑的、需要仔细进行优先级判断的往往是一个左结合加一个右结合,例如:
*ptr[]
(int)a()
&class->data
obj->*fun()
请记住一个重要方法:当我们需要改变运算符的结合顺序(C++默认的优先级不是我们的意愿)时,可以通过添加()来人为强制指定优先顺序,因为()是除了::以外具有最高优先级的一类运算符。
简单例子:以[]和*为例探讨运算符结合规律
下面的p1, p2是数组,p3是指针:
int *p1[2]; // p1是一个数组,元素个数为2,每个元素为(int*)
int *(p2[2]); // 等价于*p2[2],p2是一个数组
int (*p3)[2]; // p3是一个指针,指向一个int数组,这个int数组的元素个数必须是2!
因此只要记住两点即可:
- **[]的优先级高于* **:即
*p1[2]
和*(p1[2])
等价。 - 这个优先级同时适用于定义语句(*为指针定义符)和执行语句(*为解引用符)中:
int *p1[2]; // 定义语句:先看[]:p1是一个数组,元素个数为2,每个元素为(int*)。等价于*(p1[2])
int (*p2)[2]; // 定义语句:先看*: p2是一个指针,指向一个int数组,这个int数组的元素个数必须是2!
cout
完整示例:
#include
using namespace std;
int main(){
// []的优先级高于*,因此下面的p1是数组,p2是指针:
int *p1[2]; // p1是一个数组,元素个数为2,每个元素为(int*)。等价于*(p1[2])
int (*p2)[2]; // p2是一个指针,指向一个int数组,这个int数组的元素个数必须是2!
int a = 1, b = 2;
int c[2] = {4,5};
p1[0] = &a;
p1[1] = &b;
p2 = &c;
cout
输出:
*p1[0] = 1
*p1[1] = 2
*(p1[0]) = 1
*(p1[1]) = 2
(*p2)[0] = 4
(*p2)[1] = 5
复杂例子:探讨当左结合和右结合运算符同时存在时如何界定优先级
下面的例子比较复杂,需要耐心仔细阅读和体会。如果这个例子能搞清楚,那么相信你对运算符优先级的理解将会上升一个档次。
这个例子研究了当左结合和右结合运算符同时存在时的结合顺序,同时也演示了可以使用()强制人为指定结合顺序:
#include
#include
using namespace std;
class Student{
public:
Student(string name, int id):_name(name),_id(id){}
void printInfo(){
cout 和()平级:从左向右
cout printInfo();
// .高于*:先结合.
cout *:先结合()
cout *' to call pointer-to-member function in 'fp (...)'
(s1.*fp)();
(s2.*fp)();
// ps1->*fp(); // error: must use '.*' or '->*' to call pointer-to-member function in 'fp (...)'
(ps1->*fp)();
// (int)高于.*和->*:先结合(int)
cout *fp)(); // 先将ssp强转为Student*,然后调用Student::printInfo(),注意是.*fp而不是.*fp2
// *高于.*和->*:先结合*
cout *fp2)(); // 先*sspp,再->fp2
delete ps1;
return 0;
}
输出:
-----------------1------------------
I am a student. My name is Bob. My id is 101
I am a student. My name is Jack. My id is 102
I am a student. My name is Eric. My id is 103
-----------------2------------------
I am a student. My name is Eric. My id is 103
-----------------3------------------
I am a student. My name is Eric. My id is 103
I am a student. My name is Eric. My id is 103
-----------------4------------------
I am Student2!!!
I am a student. My name is Alice. My id is 999
I am a student. My name is Jason. My id is 998
-----------------5------------------
I am a student. My name is Bob. My id is 101
I am a student. My name is Jack. My id is 102
I am a student. My name is Eric. My id is 103
-----------------6------------------
I am a super Student!!!
I am a student. My name is Alice. My id is 999
I am a student. My name is Jason. My id is 998
-----------------7------------------
I am a super Student!!!
I am a super Student!!!
1.本站内容仅供参考,不作为任何法律依据。用户在使用本站内容时,应自行判断其真实性、准确性和完整性,并承担相应风险。
2.本站部分内容来源于互联网,仅用于交流学习研究知识,若侵犯了您的合法权益,请及时邮件或站内私信与本站联系,我们将尽快予以处理。
3.本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
4.根据《计算机软件保护条例》第十七条规定“为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。”您需知晓本站所有内容资源均来源于网络,仅供用户交流学习与研究使用,版权归属原版权方所有,版权争议与本站无关,用户本人下载后不能用作商业或非法用途,需在24个小时之内从您的电脑中彻底删除上述内容,否则后果均由用户承担责任;如果您访问和下载此文件,表示您同意只将此文件用于参考、学习而非其他用途,否则一切后果请您自行承担,如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
5.本站是非经营性个人站点,所有软件信息均来自网络,所有资源仅供学习参考研究目的,并不贩卖软件,不存在任何商业目的及用途
暂无评论内容