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