【问题标题】:why the output is different and what is the wrong in this code?为什么输出不同,这段代码有什么问题?
【发布时间】:2018-04-17 21:59:59
【问题描述】:

所以我一直在尝试获取数组大小及其元素的输入,然后将元素显示到屏幕上,但是当我例如放 数组大小:7 数组元素:1 2 3 4 5 6 7 输出是:

1
2
3
4
5
6
6

代码:

#include <iostream>

using namespace std;

int main () {    
    int n , Arr[n];    
    cout << "please put the size of the array " ;    
    cin >> n;    
    cout << "please enter array's elemets ";    
    for (int k=0; k<n ; k++) {    
        cin >> Arr[k];    
    }    
    for (int i=0;i<n;i++){    
        cout << Arr[i] << endl;    
    }    
}

【问题讨论】:

  • int n , Arr[n]; 是一个错误。实际上不止1个错误..
  • 在标准 c++ 中,n 必须在编译时知道,因为数组的大小在编译时是固定的。同样对于允许此(VLA)通过扩展进行编译的非确认编译器,n 仍需要在声明之前进行初始化。
  • 即使使用 VLA 扩展,n 在使用时也未初始化
  • 我建议读一本 C++ 的书,你学校的图书馆肯定有。
  • 文件必须命名为“iostream .h” 不,这已经很久了。

标签: c++ arrays c++98


【解决方案1】:

int Arr[n] 其中n 不是编译时间常数是非法的 C++ 代码。一些编译器允许它作为扩展(可变长度数组)。

即使使用 VLA 扩展,代码也是无效的,因为 n 在您的代码中使用时未初始化。

首先是真正的解决方案:

使用std::vector (tadaaa):

#include <iostream>
#include <vector>

int main () {    
    int n;
    std::vector<int> arr;

    std::cout << "please put the size of the array " ;    
    std::cin >> n;

    arr.reserve(n); // optional

    std::cout << "please enter array's elemets ";
    for (int k=0; k<n ; k++) {
        int elem;
        std::cin >> elem;
        arr.push_back(elem);
    }

    for (auto e : arr) {
        std::cout << e << std::endl;    
    }    
}

如果你需要针对 C++98 进行编译(哇):

for (std::vector<int>::iterator it = arr.begin(); it != arr.end(); ++it) {
    std::cout << *it << std::endl;    
}

或者只是:

for (std::size_t i = 0; i < arr.size(); ++i) {
    std::cout << arr[i] << std::endl;    
}

如果你坚持使用 VLA(我不推荐):

int n;
cout << "please put the size of the array " ;    
cin >> n;    
int Arr[n];    

cout << "please enter array's elemets ";    
for (int k=0; k<n ; k++) {    
    cin >> Arr[k];    
}    
for (int i=0;i<n;i++){    
    cout << Arr[i] << endl;    
}

【讨论】:

  • For ( auto e : arr ) 在 c98 中是不允许的 :(
  • 您使用 C++98 有什么特别的原因吗?
  • 哈哈旧电脑旧IDE :(
  • @lazycracker 这不是借口。您可以安装轻量级 IDE。
  • OK 会这样做 :) thnx BTW :')
【解决方案2】:

正如许多其他人在评论部分提到的那样,另一种方法(如果您想坚持使用 C 数组)是在堆上动态分配数组。

#include <iostream>

using namespace std;

int main () {    
    int n;    
    cout << "please put the size of the array " ;    
    cin >> n; 
    int* Arr = new int[n]; //dynamically allocate an array to hold n int on the heap
    cout << "please enter array's elemets ";    
    for (int k=0; k<n ; k++) {    
        cin >> Arr[k];    
    }    
    for (int i=0;i<n;i++){    
        cout << Arr[i] << endl;    
    }    
    delete [] Arr; //make sure to clean up the heap memories
}

【讨论】:

  • 是的,这很棒 :) 我想过这样使用它 :)
  • 不,这不是很好。实际上是伟大的反面。在 C++ 中,你永远不应该使用原始的 new/delete
  • 当你把它放在一个更大的程序中的一个函数中并且new[]delete[]之间有一个异常时会发生什么?
  • 不,:(我不知道你能指导我吗我是初学者:)
  • 这将是内存泄漏,因为与堆栈上的变量/对象不同,您需要调用 delete 来释放您分配的堆内存。如果两者之间有异常,您的程序将无法到达 delete ... 行,从而导致内存泄漏。正如 bolov 所建议的,使用 std::vector 更安全、更好。希望这不会让您感到困惑。
【解决方案3】:

来自dcl.init#12

如果没有为对象指定初始化器,则该对象是 默认初始化。当使用自动或 获取动态存储时长,对象有一个不确定的 值,并且如果没有对对象执行初始化,则 对象保留一个不确定的值,直到该值被替换 ([expr.ass])。

unsigned char c;
unsigned char d = c;        // OK, d has an indeterminate value
int e = d;                  // undefined behavior

因此,在您的代码中:

int n , Arr[n]; 

n 有一个不确定的值,直到它被分配到cin &gt;&gt; n;

n 与这个不确定的值(非值-/零-/默认-初始化且未分配)一起使用,可能会导致未定义的行为。

【讨论】:

    猜你喜欢
    • 2016-04-20
    • 2019-10-27
    • 2015-04-25
    • 2018-09-09
    相关资源
    最近更新 更多