Индекс находился вне границ массива (C#)
Прошу помощи, задача состоит вот в чём:
В одномерном массиве, состоящем из
n
целочисленных элементов, вычислить:
- Произведение элементов массива с четными номерами;
- Сумму элементов массива, расположенных между первым и последним нулевыми элементами.
Вывести массив на экран.
Прилагаю код:
using System;
using System.Linq;
namespace lab3
{
internal class Program
{
static void Main(string[] args)
{
int[] massiv;
int firstnullelem = 0;
int secondnullelem = 0;
int proizv = 1;
int summaelemnull = 0;
Console.WriteLine("Введите размер массива");
string i = Console.ReadLine();
int razmermassiva = int.Parse(i);
massiv = new int[razmermassiva];
Console.WriteLine("Вам необходимо ввести " + razmermassiva + " эл-ов массива...");
for (int i2 = 0; i2 < razmermassiva; i2++)
{
Console.Write("Введите " + i2 + "-й эл-т массива >>> ");
string e = Console.ReadLine();
int e1 = int.Parse(e);
massiv.Append(e1);
}
for (int nachmas = 0; nachmas < massiv.Length; nachmas++)
{
int nomerelem = nachmas;
int chetnechet = nomerelem % 2;
if (chetnechet == 0)
{
proizv *= massiv[nachmas];
}
else
{
continue;
}
}
for (int perebor = 0; perebor <= massiv.Length; perebor++)
{
if (massiv[perebor] == 0)
{
firstnullelem = perebor;
break;
}
else
{
continue;
}
}
for (int obratperebor = massiv.Length; obratperebor >= 0; obratperebor--)
{
if (massiv[obratperebor] == 0)
{
secondnullelem = obratperebor;
break;
}
else
{
continue;
}
}
int konecsummi = secondnullelem;
for (int nachalosummi = firstnullelem; nachalosummi < konecsummi; nachalosummi++)
{
summaelemnull += massiv[nachalosummi];
}
Console.WriteLine("Произведение всех четных эл-ов массива: ", proizv);
Console.WriteLine("Сумма эл-ов массива от первого до последнего нулевого эл-та ", summaelemnull);
Console.WriteLine("Весь массив: ");
for (int tupo = 0; tupo <= massiv.Length; tupo++)
{
Console.WriteLine(tupo + "-й эл-т массива: ", massiv[tupo]);
}
}
}
}
Какие бы элементы не вводил, каким бы массив не делал по размеру, возникает исключение "Индекс находился вне границ массива".
Перепробовал менять условия циклов, не помогает.
Ответы (1 шт):
Вижу, что вам комментарии не особо помогли...
Ладно, вот вам исправленный код:
namespace lab3
{
internal class Program
{
static void Main(string[] args)
{
int[] Array;
int FirstMultipleIndex = 0; // multiple (англ.) — кратное (рус.)
int SecondMultipleIndex = 0;
int Product = 1; // product of numbers (англ.) — произведение чисел (рус.)
int Sum = 0;
Console.WriteLine("Введите кол-во элементов массива:");
int ArrayLength = int.Parse(Console.ReadLine());
Array = new int[ArrayLength];
Console.WriteLine("Вам необходимо ввести " + ArrayLength + " эл-ов массива...");
// в цикле принято обозначать инициализатор за i (j, k, l...)
for (int i = 0; i < ArrayLength; i++)
{
Console.Write("Введите " + i + "-й эл-т массива >>> ");
int ArrayElement = int.Parse(Console.ReadLine());
Array[i] = ArrayElement; // замена massiv.Append(e1);
}
for (int j = 0; j < Array.Length; j++)
{
int IsEven = j % 2; // Is even? (англ.) — Чётный? (рус.)
if (IsEven == 0)
{
Product *= Array[j];
}
}
for (int k = 0; k < Array.Length; k++)
{
if (Array[k] % 10 == 0) // изначально было неверное условие (нужен индекс кратного 10)
{
FirstMultipleIndex = k;
break;
}
}
for (int l = Array.Length - 1; l >= 0; l--)
{
if (Array[l] % 10 == 0)
{
SecondMultipleIndex = l;
break;
}
}
// тут, кстати, граница безопасна — используем <=, ведь индекс SecondMultipleIndex был вычеслен "со сдигом" границы массива
for (int m = FirstMultipleIndex; m <= SecondMultipleIndex; m++) // заменил < на <=
{
Sum += Array[m];
}
Console.WriteLine("Произведение всех чётных эл-ов массива: " + Product); // заместо "," используем "+" (конкатенация)
Console.WriteLine($"Сумма эл-ов массива от первого до последнего нулевого эл-та: {Sum}"); // а это — интерполяция (обратите внимание на знак $ перед кавычками)
Console.WriteLine("Весь массив: ");
for (int n = 0; n < Array.Length; n++)
{
Console.WriteLine(n + "-й эл-т массива: " + Array[n]);
}
}
}
}
Пояснения и замечания
- Пожалуйста, давайте понятные названия переменным — я их переименовал;
- Главная ваша проблема, о которой вас информировали в комментариях — в программировании отсчёт элементов начинается с
0
.
Допустим, у вас 2 яблока следующий Array
:
int[] Array = new int[]{1, 2}; // в современной версии C# это так: int[] Array = [1, 2];
Перебирая его в следующем цикле:
for (int i = 0; i <= Array.Length; i++)
{
Console.WriteLine("Элемент массива: ", Array[i]);
}
Возникнет исключение "Индекс вне границ массива":
System.IndexOutOfRangeException: "Index was outside the bounds of the array."
Почему? Потому что:
Array[0] = 1;
Array[1] = 2;
У нас же нет третьего элемента, верно? А что произойдёт после второго прохода в цикле? Он завершится? Нет, он продолжится, ведь i <= Array.Length
будет истино. Потому что i
после второго прохода будет равно 2
, как и Array.Length
. А есть ли в нашем массиве элемент Array[2]
? Нету.
Значит, цикл надо завершить на 1
проход раньше. Как? Вот так:
for (int i = 0; i < Array.Length; i++) // заменил <= на <
{
Console.WriteLine("Элемент массива: ", Array[i]);
}
Можно и так, как вам удобнее:
for (int i = 0; i <= Array.Length - 1; i++) // условно "уменьшил" максимальный i в проверке на 1 (по факту сдвинул верхнюю границу массива в проверке на 1)
{
Console.WriteLine("Элемент массива: ", Array[i]);
}
В данном случае максимальное значение для i
будет 1
— как раз у нас максимальный индекс массива это 1
.
В первый раз может показаться, что это сложно понять, но, работая с индесами в дальнейшем, вы привыкните.
- В циклах
for
у вас лишний блок кода:
else
{
continue;
}
Он не нужен — цикл и так будет продолжаться до тех пор, пока не будет выполнено условие.
Немного теории. Например, дан цикл:
for (int i = 0; i < 10; i++)
Цикл for
состоит из следующего:
- int i = 0; — инициализатор;
- i < 10; — предикат (условие);
- i++ — итератор (изменение).
Он может быть без любой из трёх частей (и даже без всех них сразу):
Вариант без инициализатора:
int i = 0; // инициализатор вне конструктора цикла
for (; i < 10; i++)
{
// Какой-то код
}
Вариант без предиката:
for (int i = 0; ; i++)
{
if (i >= 10) break; // если эту строку закомментировать, получится бесконечный цикл
}
Вариант без итератора:
for (int i = 0; i < 10; )
{
i++; // итератор в теле цикла
}
Я даже скажу больше — само условие в цикле не обязательно должно быть связано с самим циклом.
- Вы неверно пытались добавить значение в
int[]
. Как я и писал в комментариях,Array (int[])
!=List
. ДляArray
нельзя просто добавить значение с помощью методаAppend
.Append
вообще-то предназначен дляStringBuilder
. ДляList
предназначен методAdd
.
Массив же представляет собой фиксированное перечисление элементов. Вы можете задать значение индексу, но не "добавить" элемент в массив (путаете с List
).
- В
Console.WriteLine
нужно использовать либо конкатенацию (+), либо интерполяцию ($).
Советую вам изучить: