【问题标题】:printf() function in loop #3 gives unexpected result [duplicate]循环#3中的printf()函数给出了意外的结果[重复]
【发布时间】:2018-12-31 10:19:26
【问题描述】:

有 3 个循环,最后一个循环的行为与预期不同。 循环 #2 和循环 #3 是错误的代码样式。他们来这里只是为了演示。问题是为什么循环#3 中的 printf() 给出了意外的输出,而循环#2 中的 printf() 给出了预期的结果?这个错误是因为编译器还是因为 printf 函数?是否有任何文件可以解释编译器或某些函数在某些情况下的行为,以便我寻找未来的问题。

int main(void) {

int mat1[3][4] = {4,5,0,3,0,0,1,2,0,0,0,6};

//****************** Output 1 ***********************************************

    for(int i=0; i<3;i++)
        for(int j=0;j<4;j++){
            printf("%d, ", mat1[i][j]);
            if(j==3)printf("\n");
        }


    /*   Expected output 1:

        4 5 0 3 
        0 0 1 2 
        0 0 0 6
    */

    printf("\n\n");

//******************* Output 2 ************************************************ 

    for(int i=0; i<3;i++)
        for(int j=0;j<4;j+=4)

            printf("\n%d, %d, %d, %d", mat1[i][j+0],mat1[i][j+1],mat1[i][j+2],mat1[i][j+3]);



    /*  Expected output 2:

        4 5 0 3 
        0 0 1 2 
        0 0 0 6
    */

    printf("\n\n");

//********************* Output 3 **********************************************

    for(int i=0; i<3;i++)
        for(int j=0;j<4;j)

            printf("\n%d, %d, %d, %d", mat1[i][j++],mat1[i][j++],mat1[i][j++],mat1[i][j++]);


    /*  Unexpected output 3:

        3 0 5 4 
        2 1 0 0 
        6 0 0 0
    */

}

【问题讨论】:

  • 在同一个函数调用的多个参数中使用 j++ 会产生未定义的行为。
  • #2 中的内部 for 循环有什么意义?它只会执行一次,因为j += 4 立即到达末尾。
  • 哪个printf 给出了意想不到的结果?
  • 循环 #2 的点仅用于演示。即使是床代码练习,它也可以正常工作。循环 #3 令人困惑。

标签: c c99 c11


【解决方案1】:
    printf("\n%d, %d, %d, %d", mat1[i][j++],mat1[i][j++],mat1[i][j++],mat1[i][j++]);

这是一种非常糟糕的编码风格,但是 printf 在打印出来之前正在从右到左评估 j。所以这就是为什么在第一个 mat1[i][j++] j 将是 3,在第二个 2 等等,直到最后一个 mat1[i][j++] 将有一个 j 这将是 0。

【讨论】:

  • 未定义参数的评估顺序,这是导致未定义行为的原因。
  • 你是对的,它不是。但在这种情况下,大多数情况下都会发生这种情况。
  • 我的意思是他们不应该指望任何特定的顺序,从左到右或从右到左。
  • Loop#2 和 loop#3 是不好的编码风格,这里只是为了演示。我理解循环#3 中发生了什么,但不知道为什么。为什么循环#2 比给出好的结果。为什么循环#2 中的 printf 是从左到右计算的,而循环#3 中的 printf 是从右到左计算的。??
  • 就像 Barmar 在 loop3 上所说的那样,这是未定义的行为,但在你的情况下,我解释了正在发生的事情。另一方面,在 loop2 上有一个主要区别:j+1 和 j++ 不一样。 j+1 对变量没有任何作用,j 保持不变,所以函数执行评估的顺序无关紧要,另一方面 j++ 实际上是 j=j+1,所以 j 会改变它的值。跨度>
猜你喜欢
  • 2020-12-05
  • 2015-11-09
  • 2012-04-09
  • 2017-10-26
  • 1970-01-01
  • 1970-01-01
  • 2019-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多