【问题标题】:Conditional operator " ? : "条件运算符“?:”
【发布时间】:2017-12-03 12:56:27
【问题描述】:

我昨天完成了 C 语言的编程考试。有一个问题我无法回答,即使我今天研究了我也想不出一个解决方案。

所以我们有这个:

int A= -1 , B= -2, C= -3, X=1;
X = B != C ? A=(~C) - A-- : ++C + (~A);
printf("A= %d  B= %d  C =%d  X=%d \n", A,B,C,X);

如果X = B != C 为真,我知道这个运算符的功能,然后A=(~C) - A-- 被执行。如果为假,则执行++C + (~A)

谁能告诉我并解释一下printf中的A、B、C和X的值是什么?

这包含在一个要求对整个程序进行“跟踪”的问题中:

     #include <stdio.h>
            void main(){
            int A= -1 , B= -2, C= -3, X=1;

        X = B != C ? A=(~C) - A-- : ++C + (~A);
        printf("A= %d  B= %d  C =%d  X=%d \n", A,B,C,X);

if(~A){
        printf("\n out1\n");
        C= A | B
        printf("A= %d  B= %d  C =%d  X=%d \n", A,B,C,X);
        C= C <<1;}

if(A^B){
         printf("\n out2\n");
        C= B & A
        B += 2
        X= X>>1
        printf("A= %d  B= %d  C =%d  X=%d \n", A,B,C,X);

顺便说一句,谁能告诉我这些if 条件是什么意思?

【问题讨论】:

  • 这是一道可怕的考试题,顺便说一句。但还有什么是新的。
  • @David Ameixa 该语句具有未定义的行为。
  • 我敢打赌 UB 不是可能的答案之一;)
  • 考试的“正确”答案是什么?
  • 您能否告诉我们提供此类考试的机构名称,以便我们促进禁止它教授编程?\

标签: c conditional-operator


【解决方案1】:

声明

X = B != C ? A=(~C) - A-- : ++C + (~A);

等价于

if(B != C)
    X = (A = (~C) - (A--));
else 
    X = ++C + (~A);

因此,表达式A = (~C) - (A--) 调用未定义的行为。在这种情况下,不会有任何好处。

也就是说,这是一个错误的问题,不应该在考试中提出。或者,只要有一个选项说明代码将调用未定义的行为,就可以用多项选择的答案来询问它。

【讨论】:

  • 对于B= -2, C= -3if(B != C) 肯定是正确的,并且执行到了坏男孩X = (A = (~C) - (A--));。然而我有信心,即使代码是if(B == C) 并且没有采用X = (A = (~C) - (A--)); 路径,整个代码仍然是UB。我确信某处有一个帖子。
  • @chux:未评估的代码不是 UB,即使如果执行它必然是 UB。该标准为example 提供2 || 1 / 0 是一个值为1 的有效整数常量表达式,而1 / 0 部分不会使其成为UB。
  • @user2357112 嗯-同意2 || 1 / 0。我得花点时间才能找到那个帖子。
【解决方案2】:

这个问题永远不应该出现在考试中,因为它包含未定义的行为。

具体来说,这个赋值A = (~C) - A-- 修改了A 两次——在-- 复合赋值和赋值本身中。由于两者之间没有sequence point,因此行为未定义。

注意:这并不意味着程序不会打印任何内容。它肯定会在大多数平台上产生一些输出。然而,这些都不重要,因为 C 程序在整体上是无效的:它可以产生任何它选择的输出,不产生输出,甚至崩溃。

【讨论】:

  • @DeiDei 就像其他人告诉 UB 一样——通过检查代码,并根据 C 语言标准检查它。
  • 顺便问一句,A=A=5; 也是 UB 吗? A 被分配了两次。 (虽然值相同)
  • @AjayBrahmakshatriya 是的,它是 UB,因为 C99 标准将写入相同的值视为修改:“修改”包括存储的新值与先前值相同的情况(第 3.1 节,第 3 部分)。
【解决方案3】:

为什么不对正在发生的事情进行非常详细的解释,让您的老师感到惊讶;)

    ...
    mov     eax, dword ptr [rbp - 16]       ; get C
    xor     eax, -1                         ; negate C
    mov     ecx, dword ptr [rbp - 8]        ; get A
    mov     edx, ecx                        ; put A into edx
    add     edx, -1                         ; add -1 to edx => A--
    mov     dword ptr [rbp - 8], edx        ; store result inside A
    sub     eax, ecx                        ; substract from ~C what was the result of A--
    mov     dword ptr [rbp - 8], eax        ; store it inside variable A
    ...

【讨论】:

    猜你喜欢
    • 2013-03-22
    • 1970-01-01
    • 2014-01-11
    • 2013-06-03
    • 2017-08-25
    • 2011-03-21
    • 2021-10-22
    相关资源
    最近更新 更多