具有增量的三元运算符中的评估顺序
Evaluation order in ternary operator with increments
#define MAX(a,b) ((a)>(b) ? (a) : (b))
int main(void) {
int a=2;
int b=3;
int c = MAX(a++,b++); // c=((a++)>(b++) ? (a++) : (b++));
printf("\na= %d", a);// a=3
printf("\nb= %d", b);//b=5
printf("\nc= %d", c);//c=4
a=3;
b=2;
cc = MAX(a++,b++); // c=((a++)>(b++) ? (a++) : (b++));
printf("\na= %d", a); // a=5
printf("\nb= %d", b); //b=3
printf("\nc= %d", c); //c=4
return 0;
}
我想知道为什么 c
没有评估为 5。
在我看来评估顺序应该是:
- 首先 a 和 be 在
(a++)>(b++)
中递增
- 如果例如第一个更大,则三元运算符在
c=((a++)>(b++) ? (a++) : (b++))
,转到 (a++)
,所以 a
再次递增。
- 三元表达式的结果,它是两倍递增,
应分配给
c
,则 c
应具有较大的值
两次递增,即 5。但是,我得到 4。我怀疑
更大的价值的第二个增量发生在最后,但我不能
解释原因,因为括号似乎表明
作业在最后。
有什么想法吗?
让我们考虑这个声明的例子
int c = MAX(a++,b++);
宏替换后会有
int c = (( a++) >( b++ ) ? (a++) : (b++));
变量a
和b
被初始化为
int a=2;
int b=3;
由于 a
小于 b
,因此第三个表达式 (b++)
将被计算为条件运算符的结果。在第一个表达式中,( a++) >( b++ )
a
和 b
递增。在第一个表达式求值之后有一个序列点。
因此a
将被设置为3
,b
将被设置为4
。
如前所述,条件运算符的值是第三个表达式 (b++)
的值,其中使用了 post 增量。 post-increment 运算符的值是其操作数在递增之前的值。
来自 C 标准(6.5.2.4 后缀递增和递减运算符)
2 The result of the postfix ++ operator is the value of the
operand. As a side effect, the value of the operand object is
incremented (that is, the value 1 of the appropriate type is added to
it).
所以条件运算符的值为4
。该值将分配给变量 c
。但作为副作用,b
的值将增加。
因此在此声明之后 a
将等于 3
,b
将等于 5
并且 c
将等于 4
.
为清楚起见,本声明
int c = (( a++) >( b++ ) ? (a++) : (b++));
实际上可以用逻辑上等价的方式改写。
int result = a > b;
++a;
++b;
int c;
if ( result != 0 )
{
c = a++;
}
else
{
c = b++;
}
后缀 ++
运算符有一个 结果 和一个 副作用 。 a++
的result是自增前a
的值-给定
int a = 1;
int x = a++;
x
的值将是 1
而 a
的值将是 2。请注意将 1
添加到 [=14= 的副作用] 不必在评估后立即应用 - 它只需要在下一个序列点之前应用。
所以,看看
((a++) > (b++)) ? (a++) : (b++)
?:
运算符强制从左到右求值,因此首先发生的是 (a++) > (b++)
被求值 1。因为 a
最初是 2
而 b
最初是 3
,所以表达式的结果是假的 (0
)。 ?
运算符引入了一个序列点,因此应用 对 a
和 b
的副作用 并且 a
现在是 3
和 b
现在是 4
.
由于条件表达式的结果是0
,我们计算b++
。同样,表达式的 结果 是 b
(4
) 的当前值,并且该值被分配给 c
。 b
的副作用在某个时候应用,当一切都完成时,a
是 3
,b
是 5
,c
是 4
。
- 虽然在该表达式中
a++
或 b++
可能首先被评估,因为 >
运算符不强制从左到右评估。
对于 a++ 等同于说
int temp = a;
a = a + 1;
return temp;
所以在 a=2,b=3 的情况下,我们可以转到条件 (a++)>(b++) 并且我们可以重写为
int temp1 = a;
a = a + 1;
return temp1;
和b重写为
int temp2 = b;
b = b + 1;
return temp2;
现在因为它只是一个条件语句,我们实际上只是在增量之前评估 a 和 b 的旧值,即 temp1 = 2 和 temp2 = 3 同时 a 和 b 值改变了 a = 3, b = 4。由于 temp1 < temp2 从旧值开始,我们转到三元运算符 (b++) 的 false 子句并执行与之前相同的操作
int temp3 = b;
b = b + 1;
return temp3;
所以现在 b 是 5,而返回的 temp3 是 b 以前的值,即 4。希望这对您有所帮助!
#define MAX(a,b) ((a)>(b) ? (a) : (b))
int main(void) {
int a=2;
int b=3;
int c = MAX(a++,b++); // c=((a++)>(b++) ? (a++) : (b++));
printf("\na= %d", a);// a=3
printf("\nb= %d", b);//b=5
printf("\nc= %d", c);//c=4
a=3;
b=2;
cc = MAX(a++,b++); // c=((a++)>(b++) ? (a++) : (b++));
printf("\na= %d", a); // a=5
printf("\nb= %d", b); //b=3
printf("\nc= %d", c); //c=4
return 0;
}
我想知道为什么 c
没有评估为 5。
在我看来评估顺序应该是:
- 首先 a 和 be 在
(a++)>(b++)
中递增
- 如果例如第一个更大,则三元运算符在
c=((a++)>(b++) ? (a++) : (b++))
,转到(a++)
,所以a
再次递增。 - 三元表达式的结果,它是两倍递增,
应分配给
c
,则c
应具有较大的值 两次递增,即 5。但是,我得到 4。我怀疑 更大的价值的第二个增量发生在最后,但我不能 解释原因,因为括号似乎表明 作业在最后。
有什么想法吗?
让我们考虑这个声明的例子
int c = MAX(a++,b++);
宏替换后会有
int c = (( a++) >( b++ ) ? (a++) : (b++));
变量a
和b
被初始化为
int a=2;
int b=3;
由于 a
小于 b
,因此第三个表达式 (b++)
将被计算为条件运算符的结果。在第一个表达式中,( a++) >( b++ )
a
和 b
递增。在第一个表达式求值之后有一个序列点。
因此a
将被设置为3
,b
将被设置为4
。
如前所述,条件运算符的值是第三个表达式 (b++)
的值,其中使用了 post 增量。 post-increment 运算符的值是其操作数在递增之前的值。
来自 C 标准(6.5.2.4 后缀递增和递减运算符)
2 The result of the postfix ++ operator is the value of the operand. As a side effect, the value of the operand object is incremented (that is, the value 1 of the appropriate type is added to it).
所以条件运算符的值为4
。该值将分配给变量 c
。但作为副作用,b
的值将增加。
因此在此声明之后 a
将等于 3
,b
将等于 5
并且 c
将等于 4
.
为清楚起见,本声明
int c = (( a++) >( b++ ) ? (a++) : (b++));
实际上可以用逻辑上等价的方式改写。
int result = a > b;
++a;
++b;
int c;
if ( result != 0 )
{
c = a++;
}
else
{
c = b++;
}
后缀 ++
运算符有一个 结果 和一个 副作用 。 a++
的result是自增前a
的值-给定
int a = 1;
int x = a++;
x
的值将是 1
而 a
的值将是 2。请注意将 1
添加到 [=14= 的副作用] 不必在评估后立即应用 - 它只需要在下一个序列点之前应用。
所以,看看
((a++) > (b++)) ? (a++) : (b++)
?:
运算符强制从左到右求值,因此首先发生的是 (a++) > (b++)
被求值 1。因为 a
最初是 2
而 b
最初是 3
,所以表达式的结果是假的 (0
)。 ?
运算符引入了一个序列点,因此应用 对 a
和 b
的副作用 并且 a
现在是 3
和 b
现在是 4
.
由于条件表达式的结果是0
,我们计算b++
。同样,表达式的 结果 是 b
(4
) 的当前值,并且该值被分配给 c
。 b
的副作用在某个时候应用,当一切都完成时,a
是 3
,b
是 5
,c
是 4
。
- 虽然在该表达式中
a++
或b++
可能首先被评估,因为>
运算符不强制从左到右评估。
对于 a++ 等同于说
int temp = a;
a = a + 1;
return temp;
所以在 a=2,b=3 的情况下,我们可以转到条件 (a++)>(b++) 并且我们可以重写为
int temp1 = a;
a = a + 1;
return temp1;
和b重写为
int temp2 = b;
b = b + 1;
return temp2;
现在因为它只是一个条件语句,我们实际上只是在增量之前评估 a 和 b 的旧值,即 temp1 = 2 和 temp2 = 3 同时 a 和 b 值改变了 a = 3, b = 4。由于 temp1 < temp2 从旧值开始,我们转到三元运算符 (b++) 的 false 子句并执行与之前相同的操作
int temp3 = b;
b = b + 1;
return temp3;
所以现在 b 是 5,而返回的 temp3 是 b 以前的值,即 4。希望这对您有所帮助!