在 for 循环测试表达式结果中使用 char 数组进行额外迭代

using char array in for loop test expression result to extra iteration

我试图使用以下代码在我的 PC 上迭代 char 数组元素。

#include <stdio.h>

int main(int argc , char *argv[] , char* env[]){

    char szBuffer[] = {'A' , 'B' , '4' , 'y' , 't' , 'A' , 'B' , '4' , 'y' , 't' }; 

    int i;
    for ( i = 0; szBuffer[i]; i++)
           printf( "i = %d  -------- (int)szBuffer[i] = %d  --------\n", i , (int)szBuffer[i]);
    return 0;
}

但是没有达到预期的效果。我的结果:

i = 0  -------- (int)szBuffer[i] = 65  --------
i = 1  -------- (int)szBuffer[i] = 66  --------
i = 2  -------- (int)szBuffer[i] = 52  --------
i = 3  -------- (int)szBuffer[i] = 121  --------
i = 4  -------- (int)szBuffer[i] = 116  --------
i = 5  -------- (int)szBuffer[i] = 65  --------
i = 6  -------- (int)szBuffer[i] = 66  --------
i = 7  -------- (int)szBuffer[i] = 52  --------
i = 8  -------- (int)szBuffer[i] = 121  --------
i = 9  -------- (int)szBuffer[i] = 116  --------
i = 10  -------- (int)szBuffer[i] = 64  --------

但在线 C 编译器显示了我预期的合理结果。 在线编译器:

i = 0  -------- (int)szBuffer[i] = 65  --------
i = 1  -------- (int)szBuffer[i] = 66  --------
i = 2  -------- (int)szBuffer[i] = 52  --------
i = 3  -------- (int)szBuffer[i] = 121  --------
i = 4  -------- (int)szBuffer[i] = 116  --------
i = 5  -------- (int)szBuffer[i] = 65  --------
i = 6  -------- (int)szBuffer[i] = 66  --------
i = 7  -------- (int)szBuffer[i] = 52  --------
i = 8  -------- (int)szBuffer[i] = 121  --------
i = 9  -------- (int)szBuffer[i] = 116  --------

让我很困惑! 第 10 次迭代如何显示以及为什么总是有 64('@') 值?

我猜这个未定义的行为(UB) 是由堆栈引起的。 您可以在不同的机器和不同的编译器上使用此代码和 运行 它,甚至在编译此代码时使用不同的选项。您可能会得到不同的结果。

#include <stdio.h>

int main(){
    char buf[] = {'A'};
    for(int i = 0; buf[i]; i++){
        printf("i: %d, buf[i]: %c\n", i, buf[i]);
    }
}

buf在栈上。如果0x00存储在buf之后,for循环只会打印一次,但是如果它存储其他有效数字,它将继续打印。当然,不幸的是,如果 i 一直增加,直到到达您没有读取权限的区域,它就会崩溃。

有一些方法可以避免这个 UB:

  1. 以 \0 结尾:char buf[] = {'A', 0};
  2. 增强for-loop:for(unsigned i = 0; i < sizeof(buf)/sizeof(char);i++){...}