#c #for-loop #vector #output
#c #для цикла #вектор #вывод
Вопрос:
Я начинаю программировать и немного изучаю C в Codecademy. Я написал следующий код как часть упражнения по использованию векторов, где мне нужно было написать программу, которая находит сумму четных чисел и произведение нечетных чисел в векторе
#include <iostream>
#include <vector>
int main() {
//Declaring variables
int i, sum = 0;
int product = 1;
std::vector<int> example = {2,4,3,6,1,8};
//Loop for calculations
for (i = 0; i <= example.size(); i )
{
if (example[i] % 2 == 0)
{
sum = sum example[i];
}
else
{
product = product * example[i];
}
}
std::cout << "Sum of even numbers: " << sum << "n";
std::cout << "Product of odd numbers: "<< product << "n";
}
Особенность этого небольшого фрагмента кода в том, что результат для произведения нечетных чисел равен 396147.
Удаление 6-го элемента дает правильный результат, поскольку я вижу, что результат равен 3 (который я должен был получить независимо, поскольку я не изменил количество нечетных чисел в моем векторе).
Аналогично, ДОБАВЛЕНИЕ элементов также заставляет программу печатать правильные числа, заставляя меня думать, что что-то не так конкретно с вычислением произведения нечетных чисел в моем векторе, когда у меня есть ровно 6 элементов.
Пожалуйста, обратите внимание, что вычисление суммы четных чисел в векторе остается подходящим независимо от количества элементов.
Примеры выходных данных для разных векторов:
Векторы с 6 элементами: std::векторный пример = {2,4,3,6,1,9}; -> результат для произведения нечетных чисел равен 3565323.
std::векторный пример = {2,4,3,6,1,5}; -> результат для произведения нечетных чисел равен 1980735.
Вектор с 5 элементами: std::векторный пример = {2,4,3,6,1}; -> результат для произведения нечетных чисел равен 3.
Вектор с 7 элементами: std::векторный пример = {2,4,3,6,1,4,8}; -> результат для произведения нечетных чисел равен 1980735.
Есть идеи, почему это происходит? Спасибо.
Комментарии:
1.
for (i = 0; i <= example.size(); i )
должно бытьfor (i = 0; i < example.size(); i )
2. поскольку мы живем в 2019 году, вам следует упростить с
for( auto n: example ) ...
Ответ №1:
У вас есть доступ за пределы вашего цикла:
for (i = 0; i <= example.size(); i )
// ^^ this is the bug
поскольку именно так работает индексирование:
std::vector<int> example = {2, 4, 3, 6, 1, 8};
// indices: 0 1 2 3 4 5
где становится очевидным, что example.size()
то, что находится 6
в этом примере, находится за пределами контейнера. Цикл следует изменить на
for (std::size_t i = 0; i < example.size(); i )
как будто i = example.size()
, example[i]
приводит к неопределенному поведению. Обратите внимание далее, что я уменьшил область действия вашего счетчика циклов i
, который может быть объявлен в init-части цикла for, и изменил его тип на std::size_t
, который является фактическим типом, используемым для индексирования контейнеров стандартной библиотеки.
Комментарии:
1. Следуя этой логике, почему мои векторы (любого размера) вообще работают? Разве у 5-элементного вектора не должны быть проблемы с 5-м элементом и так далее?
2. Природа неопределенного поведения такова, что может произойти все, что угодно. Вы не можете делать никаких предположений о том, каков результат.
Ответ №2:
так и должно быть, for (i = 0; i < example.size(); i )
поскольку индексация массива / вектора начинается с 0
, а последняя запись имеет индекс size()-1
.
Ответ №3:
проблема в вашем цикле с вектором, поэтому любой массив или вектор присваивается с 0-го индекса и перемещается в (n-1) последний индекс
включить
#include <vector>
int main() {
//Declaring variables
int i, sum = 0;
int product = 1;
std::vector<int> example = {2,4,3,6,1,8};
//Loop for calculations
for (i = 0; i < example.size(); i )
{
if (example[i] % 2 == 0)
{
sum = sum example[i];
}
else
{
product = product * example[i];
}
}
std::cout << "Sum of even numbers: " << sum << "n";
std::cout << "Product of odd numbers: "<< product << "n";
}
Комментарии:
1. Никаких объяснений, только перепечатка с одним измененным символом, а также в качестве уже данного ответа…
2. Что вы изменили и почему? Пожалуйста, добавьте такое объяснение к вашему ответу, чтобы другие могли извлечь из него уроки