printf无法解释的行为

时间:2014-10-17 18:23:46

标签: c

最近我自己开始学习 C ,所以可能会有点新手问题。 我编译了以下命令:

#include <stdio.h>

int main()
{
  int arr[5]={0};
  int arr2[5]={0};
  printf("%d\n",arr[5]); //here output: 2130567168
  printf("%d\n",arr2[5]); //here output: 0
  return 0;
}

任何人都可以解释不同产出的原因吗?

5 个答案:

答案 0 :(得分:3)

两个printf都会产生未定义的行为,因为它们正在访问超过相应数组末尾的元素。 C数组索引的有效范围是length-1为零,因此程序中的两个数组都是0..4(含)。

在索引5处访问元素超出了数组的末尾,因此不同的编译器可以产生不同的行为,从打印垃圾到崩溃。

答案 1 :(得分:2)

您正在访问超出声明范围的数据。已声明为arr[5]的数组的索引范围为0 ... 4,但您要访问arr [5],既未定义也未分配。因此,您可以根据内存的值来获得随机答案&#34; cell&#34;你想访问,在这种情况下是0和另一个号码。

答案 2 :(得分:2)

这是未定义的行为。 C不对数组执行bound checking

答案 3 :(得分:2)

将来,请在编译器上启用警告。例如,对于GCC,这将是-Wall

main.cpp:7:29: warning: array subscript is above array bounds [-Warray-bounds]
         printf("%d\n",arr[5]); //here output: 2130567168
                             ^
main.cpp:8:30: warning: array subscript is above array bounds [-Warray-bounds]
         printf("%d\n",arr2[5]); //here output: 0

请注意,C标准表明这是未定义的行为:

§J.2

  

1在以下情况下,行为未定义:

     

- 数组下标超出范围,即使某个对象显然也是如此   可以使用给定的下标访问(如左值表达式)   a [1] [7]给出a [4] [5])(6.5.6)中的声明。

接受关于undefined behavior的常规讲座。

答案 4 :(得分:0)

C中此代码的行为在C规范(Online draft for c specs)的6.7.8.21节中描述:对于没有指定值的元素,编译器将指针初始化为NULL和算术类型为零(并递归地将其应用于聚合)。

请参考以上文件了解。我也不是直接在这里发布答案因为你是新手,因为我不想用勺子喂你。快乐学习。 。