[英]Operator precedence in c with %,!=,= and ','
在下面的代码段中
int jo=50;
if( jo =(rand()%100), jo!=50)
{
printf("!50");
}
问题是“序列点”:
http://www.angelikalanger.com/Articles/VSJ/SequencePoints/SequencePoints.html
问题与安全表达
什么是渲染赋值x [i] = i ++ + 1; 一个有问题的,而赋值i = 2; 从某种意义上说,它的结果是明确的,可预测的,是无害的吗? 关键在于表达式x [i] = i ++ + 1; 有两个对变量i的访问,其中一个访问,即i ++,是一个修改访问。 由于未定义序列点之间的评估顺序,因此我们不知道在读取之前是否将对其进行修改,或者在修改之前是否将对其进行读取。 因此,如果访问是一个修改,问题的根源是对序列点之间的变量的多次访问。
这是另一个例子。 如果在执行语句之前i和j的值为1和2,会发生什么?
f(i++, j++, i+j);
哪个值将作为第三个参数传递给函数f? 我们再一次不知道。 它可以是以下任何一种:3,4或5.它取决于函数参数的计算顺序。
这里常见的误解是参数将从左到右进行评估。 或者也许是从右到左? 事实上,语言定义没有任何命令。
优先级不控制执行顺序。 优先级只控制分组-即,优先说什么操作数是每个操作,而不是在每个操作发生。
在这个例子中,由于括号, %
的优先级无关紧要 - 这些表示%
的操作数是rand()
和100
。
的precedece ,
为着低于=
和!=
告诉我们的操作数=
是jo
和(rand()%100)
和的操作数!=
是jo
和50
。
的操作数,
然后jo = (rand() % 100)
和jo != 50
。
的定义,
操作者说,第一个操作数进行评价时,则存在的序列点,然后第二个操作数进行评价。 所以这种情况下, jo = (rand() % 100)
被完全评估,它将rand() % 100
的结果存储到jo
; 然后评估jo != 50
。 整个表达式的值是jo != 50
的值。
好吧,序列点是正确的答案。 但是让我们从教科书中翻译出来。
逗号运算符具有一个特殊属性:它确保首先评估其左侧的内容。 所以,当你到达表达式时
jo =(rand()%100), jo!=50
即使 !=
比','更紧密地绑定 ,所以表达完全括号的表达式
(jo =(rand()%100)),(jo!=50)
首先评估第一部分。
要记住这一点,你可以将逗号运算符代替或读作“然后”,这样
j0=(rand()%100)
“接着”
jo!=50.
将“优先权”视为“先做”是错误的。
请考虑以下代码段:
f() + g() + h()
哪个添加操作具有更高的优先级,即对f()和g()的结果求和的那个,或者对该结果和h()求和的那个?
这是一个棘手的问题,因为根本不需要调用“优先级”。 但是仍然有一个操作顺序,因为C中的函数调用引入了“序列点”,这就是C允许你确定“什么时候发生的事情”的原因。
在您的特定代码中,您有一个逗号运算符 - 这与函数参数中的逗号标点符号完全不同 - 在此部分中:
jo = (rand() % 100), jo != 50
逗号运算符引入了一个序列点(就像对rand
的函数调用一样),因此我们知道rand
运行并产生一个值,然后计算值% 100
并将其分配给jo
,最后将jo
与50
进行比较。
(在if
控制表达式的评估之后还有一个序列点,每个语句结束的分号都有一个序列点。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.