C中的运算符优先级和结合性(*p++)

优先级和结合性

优先级是用来标识运算符在表达式中的运算顺序的,在求解表达式的值的时候,总是先按运算符的优先次序由高到低进行操作。但是,当一个运算对象两侧的运算符的优先级别相同时,则按运算符的结合性来确定表达式的运算顺序。

结合性是指同一优先级的运算符在表达式中操作的组织方向,即:当一个运算对象两侧的运算符的优先级别相同时,运算对象与运算符的结合顺序。

最容易搞混的莫过于运算符优先级处于第二级别的了,尤其是当 *++ 用在一起时:
C中的运算符优先级和结合性(*p++)_第1张图片

先安插一个知识点:自增(++)与自减(- -)运算符只能作用于变量,不能作用于常量和表达式

*p++ 和 ++*p

#include 
using namespace std;

int main(int argc, char *argv[]) {
    const char *p = "hello";
    cout << *p << endl;
    cout << *p++ << endl;
    cout << *++p << endl;
    //cout << ++*p << endl; // 编译报错,*p 为一个字符,++ 不能作用于常量和表达式

    int a = 6;
    int *pa = &a;
    cout << *pa++ << endl;
    cout << ++*pa << endl;

    return 0;
}

gcc 7.3.0 中的输出结果为:

h
h
l
6
-1268913224

下面一一解读上面的输出结果,首先是第一行输出的 h,这个不用多说,*p 的作用就是取出字符串常量中的第一个字符。

*p++ ,由于 * (取值运算符)和 ++ (自增运算符)同属第二优先级别的运算符,所以当它们同时作用于变量 p 上时,按照从右向左的结合顺序依次进行运算。所以 *p++ 等同于 *(p++)

  • 第一步 :执行 p++,执行完后,p 的值增加 1(此时 p 已经指向第二个字符),并且返回 p 增加前的值。
  • 第二步:执行 *(p++),灰色表示已经执行完了,而表达式 (p++) 的值为原始 p 的值,即还是指向字符串常量第一个字符的地址,所以最终结果为:h

*++p,按照从右向左结合的顺序,等价于 *(++p),先执行 ++p ,执行完后,p 指向第三个字符,即 l,并且表达式 (++p) 返回 p 增加后的值,所以最终结果为 l

类似的,*pa++等价于 *(pa++),执行完的结果是:表达式值为 6(通过这个结果可以证明:* 取值运算符作用的是 (pa++)表达式,而不是作用于变量 pa 本身),pa 值增加1,指向一个未知内存。当执行 ++*pa 时,由于 pa 此时指向的位置未知,所以对其里面的内容进行自增运算的结果也未知,所以最终的结果为一个垃圾数。

参考:
[1] c语言运算符优先级,结合性(左/右结合详解)
[2] C语言运算符的结合性详细分析

你可能感兴趣的:(C/C++)