同一个数组在一个地方给出垃圾值,在另一个地方给出不相关的值
Same array giving garbage value at one place and an unrelated value at the other place
在下面的代码中:
#include<iostream>
using namespace std;
int main()
{
int A[5] = {10,20,30,40,50};
// Let us try to print A[5] which does NOT exist but still
cout <<"First A[5] = "<< A[5] << endl<<endl;
//Now let us print A[5] inside the for loop
for(int i=0; i<=5; i++)
{
cout<<"Second A["<<i<<"]"<<" = "<<A[i]<<endl;
}
}
输出:
第一个 A[5] 给出了不同的输出(是否称为垃圾值?),第二个 A[5] 在 for 循环中给出了不同的输出(在这种情况下,A[i] 给出的输出为 i)。谁能解释一下为什么?
同样在 for 循环中,如果我声明一个像 int sax = 100; 这样的随机变量,那么 A[5] 将取值 100 而我一点也不知道为什么会这样。
我在 Windows、CodeBlocks、GNUGCC 编译器
在你的程序中,我认为“没有任何语法问题”,因为当我在我的编译器中执行相同的代码时。那就没有任何问题喜欢你了。
它在直接和循环中给出相同的垃圾值。
enter image description here
好吧,你调用了未定义的行为,所以行为是错误的... 未定义 任何事情都可能发生,包括你在这里的表演。
在常见的实现中,数组末尾之后的数据可能会被不同的元素使用,只有编译器中的实现细节才能判断是哪一个。
此处您的实现已将下一个变量 (i
) 放置在数组之后,因此 A[5]
是 i
.
的(无效)访问器
但是请不要依赖那个。不同的编译器或不同的编译选项可能会给出不同的结果。由于编译器可以自由假设您的代码不应调用 UB,因此优化编译器可以优化您的所有代码,只有您应该受到指责。
TL/DR:永远不要尝试试验 UB:从一致的行为到通过各种不一致的输出传递的立即崩溃,任何事情都可能发生。而且你看到的不会在不同的上下文中重现(这里的上下文甚至可以只是相同代码的不同运行)
问题是当你写的时候:
cout <<"First A[5] = "<< A[5] << endl<<endl;//this is Undefined behavior
在上面的语句中你越界。这是因为数组索引从 0
开始,而不是 1
.
因为你的数组大小是5
。这意味着您可以安全地访问 A[0]
、A[1]
、A[2]
、A[3]
和 A[4]
.
另一方面,您不能访问A[5]
。如果您尝试这样做,您将得到 未定义的行为。
Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior.
所以您看到的输出是未定义行为的结果。正如我所说,不要依赖具有 UB 的程序的输出。
因此,使程序正确的第一步是删除 UB。 然后并且只有那时你可以开始对程序的输出进行推理。
出于同样的原因,在您的 for
循环中,您应该将 i<=5
替换为 i<5
。
1有关未定义行为的技术上更准确的定义,请参阅 this 其中提到:没有对程序行为的限制.
在下面的代码中:
#include<iostream>
using namespace std;
int main()
{
int A[5] = {10,20,30,40,50};
// Let us try to print A[5] which does NOT exist but still
cout <<"First A[5] = "<< A[5] << endl<<endl;
//Now let us print A[5] inside the for loop
for(int i=0; i<=5; i++)
{
cout<<"Second A["<<i<<"]"<<" = "<<A[i]<<endl;
}
}
输出:
第一个 A[5] 给出了不同的输出(是否称为垃圾值?),第二个 A[5] 在 for 循环中给出了不同的输出(在这种情况下,A[i] 给出的输出为 i)。谁能解释一下为什么?
同样在 for 循环中,如果我声明一个像 int sax = 100; 这样的随机变量,那么 A[5] 将取值 100 而我一点也不知道为什么会这样。
我在 Windows、CodeBlocks、GNUGCC 编译器
在你的程序中,我认为“没有任何语法问题”,因为当我在我的编译器中执行相同的代码时。那就没有任何问题喜欢你了。
它在直接和循环中给出相同的垃圾值。 enter image description here
好吧,你调用了未定义的行为,所以行为是错误的... 未定义 任何事情都可能发生,包括你在这里的表演。
在常见的实现中,数组末尾之后的数据可能会被不同的元素使用,只有编译器中的实现细节才能判断是哪一个。
此处您的实现已将下一个变量 (i
) 放置在数组之后,因此 A[5]
是 i
.
但是请不要依赖那个。不同的编译器或不同的编译选项可能会给出不同的结果。由于编译器可以自由假设您的代码不应调用 UB,因此优化编译器可以优化您的所有代码,只有您应该受到指责。
TL/DR:永远不要尝试试验 UB:从一致的行为到通过各种不一致的输出传递的立即崩溃,任何事情都可能发生。而且你看到的不会在不同的上下文中重现(这里的上下文甚至可以只是相同代码的不同运行)
问题是当你写的时候:
cout <<"First A[5] = "<< A[5] << endl<<endl;//this is Undefined behavior
在上面的语句中你越界。这是因为数组索引从 0
开始,而不是 1
.
因为你的数组大小是5
。这意味着您可以安全地访问 A[0]
、A[1]
、A[2]
、A[3]
和 A[4]
.
另一方面,您不能访问A[5]
。如果您尝试这样做,您将得到 未定义的行为。
Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior.
所以您看到的输出是未定义行为的结果。正如我所说,不要依赖具有 UB 的程序的输出。
因此,使程序正确的第一步是删除 UB。 然后并且只有那时你可以开始对程序的输出进行推理。
出于同样的原因,在您的 for
循环中,您应该将 i<=5
替换为 i<5
。
1有关未定义行为的技术上更准确的定义,请参阅 this 其中提到:没有对程序行为的限制.