C条件语句

C条件语句,c,C,我遇到了下面的代码 int main() { int i=1,j=2; int a=i--?printf("%d",i):j--; printf(" %d %d %d",i,j, a); return 0; } 输出为0 0 2 1 我理解除前0之外的其余输出 请帮忙 谢谢。第一个0是i的值,它被初始化为1,然后在第二行中递减 更明确地说: i = 1 (i--) - evaluates as True, then sets i to 0 printf("%d ", i) =

我遇到了下面的代码

int main()
{
  int i=1,j=2;
  int a=i--?printf("%d",i):j--;
  printf(" %d %d %d",i,j, a);
  return 0;
}
输出为0 0 2 1

我理解除前0之外的其余输出

请帮忙


谢谢。

第一个
0
i
的值,它被初始化为
1
,然后在第二行中递减

更明确地说:

i = 1
(i--) - evaluates as True, then sets i to 0
printf("%d ", i) = prints '0'
j--   - skipped
printf("%d %d %d", i, j, a)
print i: 0
print j: 2 (unchanged)
print a: return value of first `printf` : character count (1)
正如@tristopia在评论中指出的,这里有两个密切相关的概念:

  • 后修复运算符:表达式中使用的值是增量发生之前的值
  • 序列点:代码中的一个点,“先前评估的所有副作用都将被执行”——换句话说,“需要发生的一切都将在我们通过该点之前发生”。例如,当您传递序列点时,任何在修复后递增的变量都保证递增(并存储)
  • 这里的关键是三元运算符的
    就是这样一个序列点-因此,您可以确定
    i
    在进入
    printf
    语句之前已经递减

    将此代码与以下代码进行对比:

    i = 1;
    a = 5 * i++ + (i = 2 * i--);
    

    这会导致未定义的行为-C标准中没有任何内容可以明确告诉您在上述操作之后,
    a
    i
    的值是多少。什么时候应将
    i++
    的值存储回
    i
    ?在减量操作之前?我们将结果分配给
    i
    ,这一事实如何?这是发生在其他“隐式存储”操作之前还是之后?大多数编译器在遇到这样一行时都会警告您-如果您有特定的操作顺序,您应该通过重写代码来“强制序列点”。

    第一行
    0
    i
    的值,它被初始化为
    1
    ,然后在第二行中递减

    更明确地说:

    i = 1
    (i--) - evaluates as True, then sets i to 0
    printf("%d ", i) = prints '0'
    j--   - skipped
    printf("%d %d %d", i, j, a)
    print i: 0
    print j: 2 (unchanged)
    print a: return value of first `printf` : character count (1)
    
    正如@tristopia在评论中指出的,这里有两个密切相关的概念:

  • 后修复运算符:表达式中使用的值是增量发生之前的值
  • 序列点:代码中的一个点,“先前评估的所有副作用都将被执行”——换句话说,“需要发生的一切都将在我们通过该点之前发生”。例如,当您传递序列点时,任何在修复后递增的变量都保证递增(并存储)
  • 这里的关键是三元运算符的
    就是这样一个序列点-因此,您可以确定
    i
    在进入
    printf
    语句之前已经递减

    将此代码与以下代码进行对比:

    i = 1;
    a = 5 * i++ + (i = 2 * i--);
    

    这会导致未定义的行为-C标准中没有任何内容可以明确告诉您在上述操作之后,
    a
    i
    的值是多少。什么时候应将
    i++
    的值存储回
    i
    ?在减量操作之前?我们将结果分配给
    i
    ,这一事实如何?这是发生在其他“隐式存储”操作之前还是之后?大多数编译器在遇到这种情况时都会发出警告-如果您考虑了特定的操作顺序,您应该通过重写代码来“强制序列点”。

    您调用了
    printf()
    两次。条件运算符中的第一个将打印
    i
    (0)的值。创建变量
    a
    时,它的默认值为0,
    i
    在使用
    i--
    递减后变为0,因此条件通过


    然后是第二个
    printf()
    ,它将与其他两个值一起再次打印
    i

    那么您将调用
    printf()
    两次。条件运算符中的第一个将打印
    i
    (0)的值。创建变量
    a
    时,它的默认值为0,
    i
    在使用
    i--
    递减后变为0,因此条件通过



    然后是第二个
    printf()
    ,它将与其他两个值一起再次打印
    i

    在对i进行条件检查之前,i的值不会递减(由于后缀递减)。当i为1时,测试的计算结果为true,从而执行printf。但正如i的测试结束一样,它会被递减,这就是printf在屏幕上打印的内容。

    在对i进行条件检查之前,i的值不会递减(由于后缀递减)。当i为1时,测试的计算结果为true,从而执行printf。但是,当i的测试结束时,它被递减,这就是printf在屏幕上打印的内容。

    你的问题是什么?它被
    i--
    从1变为0。哦,明白了。谢谢:)你的问题是什么?它被
    i--
    从1改为0。哦,明白了。谢谢:)我知道我会变小。但由于他们使用了后缀运算符,我感到困惑。因此,如果我是对的,则对语句求值,然后递减,然后打印。?即使这段代码很难看,我在这里也看不到任何导致未定义行为的东西。@MichaelWalz-你是对的,我看得更仔细了。相应地更新。至少应该提到序列点的概念。三元运算符在布尔表达式和结果值之间有一个。这就是为什么OP的表达不是“未定义的行为”的原因。@tristopia-很好。考虑到这一点,我修改了我的答案。我知道我会被递减。但由于他们使用了后缀运算符,我感到困惑。因此,如果我是对的,则对语句求值,然后递减,然后打印。?即使这段代码很难看,我在这里也看不到任何导致未定义行为的东西。@MichaelWalz-你是对的,我看得更仔细了。相应地更新。至少应该提到con