繁体   English   中英

c中的运算符优先级为%,!=,=和','

[英]Operator precedence in c with %,!=,= and ','

在下面的代码段中

int jo=50;
if( jo =(rand()%100), jo!=50)
{
    printf("!50");
}   
  1. %具有最高优先级,因此rand()%100将首先执行
  2. !=的优先级大于=所以jo!= 50应该执行正确吗?
  3. ,当我首先执行赋值时,仍然具有最少的优先权然后!=然后,。 我得到一个输出!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)和的操作数!=jo50

的操作数,然后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 ,最后将jo50进行比较。

(在if控制表达式的评估之后还有一个序列点,每个语句结束的分号都有一个序列点。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM