返回介绍

2. 运算符

发布于 2024-10-12 21:58:08 字数 1767 浏览 0 评论 0 收藏 0

运算符(operator)优先级和关联性。

优先级 指运算顺序; 关联性 指存在多个相同优先级时,操作数分组选择左侧还是右侧。

下表:优先级从高到低。关联性也翻译作结合性。

递增、递减

前置和后置的区别在于:先运算还是先取值。

int x = 0;
int y = ++x + 0x11;
mov    DWORD PTR [rbp-0x8],0x0   // x = 0
add    DWORD PTR [rbp-0x8],0x1   // x += 1		先运算。
mov    eax,DWORD PTR [rbp-0x8]   // ax = x		再取值。
add    eax,0x11                  // ax += 0x11
mov    DWORD PTR [rbp-0x4],eax   // y = ax

后置虽然先取值,但 x++ 的运算优先级依然高于 ? + 0x11 运算。

int x = 0;
int y = x++ + 0x11;
mov    DWORD PTR [rbp-0x8],0x0   // x = 0
mov    eax,DWORD PTR [rbp-0x8]   // ax = x			先取值。
lea    edx,[rax+0x1]             // dx = ax + 1
mov    DWORD PTR [rbp-0x8],edx   // x = dx			再运算。(先完成 x + 1)
add    eax,0x11                  // ax += 0x11      使用的是运算前的取值。
mov    DWORD PTR [rbp-0x4],eax   // y = ax

另外,下面的写法是错误的。

无论先计算哪边,返回的结果都不再是左值。

int x = 0;
++x++;       // error: lvalue required as increment operand

三元运算符

根据条件表达式选择返回。

static_assert((true  ? 11 : 10) == 11);
static_assert((false ? 11 : 10) == 10);
int x = 1;
puts(x ? "a" : "b");

逗号运算符

从左到右顺序处理,返回最右操作数值和类型。

int i = 1;
long long x = (i++, printf("abc"), i += 2, (long long)i);
assert(x == 4);

常见错误

直觉未必准确。适当使用括号提升可阅读性,避免错误。

*p++   // *(p++)
++*p   // ++(*p)
*x.member  // *(x.member)
*d[i]      // *(d[i])
v & m != 0            // v & (m != 0)
c = getchar() != EOF  // c = (getchar() != EOF)
m << 4 + x   // m << (4 + x)
i = 1, 2    // (i = 1), 2

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文