我想反转我的数组。为啥这段代码给出垃圾值?
Posted
技术标签:
【中文标题】我想反转我的数组。为啥这段代码给出垃圾值?【英文标题】:I wanted to reverse my array. Why this code gives garbage value?我想反转我的数组。为什么这段代码给出垃圾值? 【发布时间】:2020-05-22 20:18:17 【问题描述】: #include <iostream>
using namespace std;
int main()
int n;
int a[n];
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
for(int i=n;i>=0;i--)
cout<<a[i]<<" ";
输入:- 4 1 2 3 4 输出 4199008 4 3 2 1
【问题讨论】:
在编译器上启用警告。int a[n];
并非每个编译器都支持,如果不是错误,则应生成警告。你不先初始化n
。你实际上想要std::vector<int>
。另外,do not use using namespace std;
。您可以使用 std::reverse()
反转任何支持双向迭代的容器。
另外,您的第二个循环索引a[n]
,即UB。你需要从n-1
开始。
您的代码显然不会尝试“反转数组”。见 std::reverse。应用它后,cout 生成的数组,从头到尾。这可以简化和记录您的编码意图,并避免意外的未定义行为。
【参考方案1】:
对于初学者,程序具有未定义的行为,因为变量 n
未初始化
int n;
所以这个声明
int a[n];
无效。此外,可变长度数组不是标准的 C++ 特性。而是使用标准类模板std::vector
。
也在这个循环中
for(int i=n;i>=0;i--)
cout<<a[i]<<" ";
您正在尝试访问索引为 n
的不存在元素。
此外,您没有反转数组。您正试图以相反的顺序输出一个数组。
注意在标头<algorithm>
中声明了标准算法std::reverse
和std::reverse_copy
。
这是一个示例,使用您的方法的程序看起来如何
#include <iostream>
#include <vector>
int main()
size_t n = 0;
std::cout << "Enter the size of an array ";
std::cin >> n;
std::vector<int> v( n );
std::cout << "Enter " << n << " elements: ";
for ( auto &item : v ) std::cin >> item;
std::cout << "The array in the reverse order\n";
for ( size_t i = v.size(); i != 0; )
std::cout << v[--i] << ' ';
std::cout << '\n';
return 0;
程序输出可能看起来像
Enter the size of an array 10
Enter 10 elements: 0 1 2 3 4 5 6 7 8 9
The array in the reverse order
9 8 7 6 5 4 3 2 1 0
如果使用标准算法,那么您的程序可以如下所示
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
int main()
size_t n = 0;
std::cout << "Enter the size of an array ";
std::cin >> n;
std::vector<int> v( n );
std::cout << "Enter " << n << " elements: ";
std::copy_n( std::istream_iterator<int>( std::cin ), n, std::begin( v ) );
std::cout << "The array in the reverse order\n";
std::reverse_copy( std::begin( v ), std::end( v ),
std::ostream_iterator<int>( std::cout, " ") );
std::cout << '\n';
return 0;
程序输出可能与上面显示的方式相同
Enter the size of an array 10
Enter 10 elements: 0 1 2 3 4 5 6 7 8 9
The array in the reverse order
9 8 7 6 5 4 3 2 1 0
【讨论】:
荣誉奖:rbegin()
和 rend()
这使得 reverse_copy
完全没有必要。【参考方案2】:
a[n]
将返回最后一个元素之后的元素。逆序迭代时,以i=n-1
开头。
【讨论】:
还有更多需要修复的地方,例如int a[n]
之前的 n
被初始化。除非n
是const
,否则即使初始化它也不起作用。【参考方案3】:
在你的程序开始时有一个错误:
int n; // You declare n with no value
int a[n]; // You use is
cin>>n; // After you used it you get your value-
现在我可以假设这只是复制时的错误,因为您提供了输入和输出
输入:- 4 1 2 3 4 输出 4199008 4 3 2 1
所以忘记这一点,你声明一个大小为 n 的数组。 请记住,数组的元素将从 0 变为 n-1。 现在看看你的第二个 for 循环
// the first element you acces is n and you stop at 1
// but the array goes from n-1 to 0
for(int i=n;i>=0;i--)
cout<<a[i]<<" ";
所以你仍然会得到 n 个值作为输出,但你访问的第一个元素在数组之外。这就是为什么你会得到一个垃圾值,那是一个遗留在那里的值。
一个解决方案是改变for循环
for(int i=n-1;i>=-1;i--)
cout<<a[i]<<" ";
【讨论】:
【参考方案4】:在反转数组时,从 n-1 开始循环,即 i=n-1(n 是数组中的元素数)。并运行循环直到 i>=0。如果你从 n 开始循环,它将读取超出范围的非法索引,并给你垃圾值。
for(int i=n-1; i>=0; i++)
cout<<arr[i]<<" ";
【讨论】:
以上是关于我想反转我的数组。为啥这段代码给出垃圾值?的主要内容,如果未能解决你的问题,请参考以下文章