#c #variables
#c #переменные
Вопрос:
Я создаю простую программу быстрой сортировки, которая инициализирует пустой массив и запрашивает у пользователей входные данные, чтобы определить, сколько элементов будет отсортировано и какие элементы будут отсортированы.
Проблема, с которой я сталкиваюсь, заключается в том, что локальная переменная изменяется, несмотря на то, что на нее ссылаются только после назначения. Ниже прилагается код.
int main()
{
int amount;
int numbersarray[] = {};
std::cout << "How many numbers do you want to sort? " << std::endl;
std::cin >> amount;
for(int i = 0; i <= amount; i ){
std::cout << "Enter number to be sorted: " << std::endl;
std::cin >> numbersarray[i];
}
std::cout <<"Amount to be sorted: " << amount << std::endl;
for(int i = 0; i <= amount; i ){
std::cout << numbersarray[i] << std::endl;
}
}
То, что я ожидаю, произойдет, когда я введу сумму как 5, я должен быть в состоянии ввести 5 элементов в массив, однако вместо этого напечатанная сумма равна 2, а максимальное количество элементов, которые я могу поместить в массив, равно 3.
Ниже приведен результат выполнения.
How many numbers do you want to sort?
5
Enter number to be sorted:
5
Enter number to be sorted:
2
Enter number to be sorted:
5
Amount to be sorted: 2
5
2
5
Я пытался возиться с оператором for, но я не думаю, что я делаю это правильно, поскольку это не устранило проблему, манипуляция с оператором for, которую я делаю, изменяет условие (т. е. !=, <, <=)
Комментарии:
1.
int numbersarray[] = {};
массивы не являются динамическими в C . Используйтеstd::vector
.2. Какой компилятор вы используете, поскольку он не должен компилироваться в соответствии со стандартом? Если вы используете GCC, используйте
-pedantic-errors
в настройках вашего компилятора, чтобы он отклонял этот код.3.
int numbersarray[] = {}
не допускается в c (хотя некоторые компиляторы разрешают это по умолчанию как расширение языка). В любом случае, она не содержит элементов, и попытка доступа к одному из них является неопределенным поведением, что означает, что возможно практически все. Это включает в себя, казалось бы, невозможные вещи, такие как несвязанные переменные, спонтанно меняющие значения.4. @tkausl Имейте в виду, что простого использования
std::vector
недостаточно. Если она используется в качестве дополнительной замены (просто меняется наstd::vector<int> numbersarray;
), она будет скомпилирована и по-прежнему будет вести себя так же. Вам также необходимо использоватьemplace_back
или другие функции-члены вставки, чтобы правильно вводить новые элементы.5. @b Установите флажок «педантичный» в разделе «предупреждения» на вкладке «Параметры». Это остановит ее компиляцию.
Ответ №1:
У вас неопределенное поведение. Случиться может все, что угодно. Локальная переменная может измениться без причины, программа может аварийно завершиться, и ваш компьютер может отформатироваться под Linux 6.9
Существует множество проблем. Во-первых, ваша программа недействительна в соответствии со стандартом:
int numbersarray[] = {};
Это недопустимо. Массиву нужен размер:
constexpr int max_amount = 32;
int numbersarray[max_amount] = {};
Если вам нужно, чтобы она была динамической, используйте vector:
std::vector<int> numbersarray;
numbersarray.resize(amount);
Во-вторых, у вас есть другой источник неопределенного поведения:
// Iterates too much, numbersarray[amount] is past the end
// ~~~v~~~~~~~
for(int i = 0; i <= amount; i ){
std::cout << "Enter number to be sorted: " << std::endl;
std::cin >> numbersarray[i];
}
Это должно быть:
for(int i = 0; i < amount; i ){
std::cout << "Enter number to be sorted: " << std::endl;
std::cin >> numbersarray[i];
}
Чтобы избежать недопустимого кода и неопределенного поведения, вам следует включить предупреждения.
Ответ №2:
numbersarray
представляет собой массив в стиле C с нулевым размером и не регулирует его размер динамически (большинство компиляторов могут даже не выполнить компиляцию int numbersarray[] = {};
, поскольку пустой инициализатор не разрешен для массива с неопределенным размером).
Запись или чтение ее элементов вызывает неопределенное поведение (которое может быть нарушением доступа, изменением несвязанных переменных и многим другим). Это причина, по которой вы можете увидеть изменение значений локальных переменных. Кто-то другой, использующий тот же код, может получить совершенно другое поведение, поскольку оно не определено.