Индекс находился вне границ массива (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 шт):

Автор решения: Chaos_Sower

Вижу, что вам комментарии не особо помогли...

Ладно, вот вам исправленный код:

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]);
            }
        }
    }
}

Пояснения и замечания

  1. Пожалуйста, давайте понятные названия переменным — я их переименовал;
  2. Главная ваша проблема, о которой вас информировали в комментариях — в программировании отсчёт элементов начинается с 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.

В первый раз может показаться, что это сложно понять, но, работая с индесами в дальнейшем, вы привыкните.

  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++; // итератор в теле цикла
}

Я даже скажу больше — само условие в цикле не обязательно должно быть связано с самим циклом.


  1. Вы неверно пытались добавить значение в int[]. Как я и писал в комментариях, Array (int[]) != List. Для Array нельзя просто добавить значение с помощью метода Append. Append вообще-то предназначен для StringBuilder. Для List предназначен метод Add.

Массив же представляет собой фиксированное перечисление элементов. Вы можете задать значение индексу, но не "добавить" элемент в массив (путаете с List).

  1. В Console.WriteLine нужно использовать либо конкатенацию (+), либо интерполяцию ($).

Советую вам изучить:

→ Ссылка