Почему вывод отличается и что не так в этом коде?

Поэтому я пытался получить ввод размера массива и его элементов, а затем отобразить элементы на экране, но когда я, например, поместил размер массива: 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;    
    }    
}

3 ответа

int Arr[n] где n не является константой времени компиляции, является недопустимым кодом C++. Некоторые компиляторы допускают это как расширение (Array Length Array).

Даже с расширением 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;    
}

Как многие другие упоминали в разделе комментариев, другой способ (в случае, если вы хотите придерживаться массива 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
}

Из 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 >> n;

с помощью n с этим неопределенным значением (не инициализированным значением / нулем / по умолчанию и не назначенным) может привести к неопределенному поведению.

Другие вопросы по тегам