Главная / Курсы / Golang / Массивы
# Глава 4. Массивы ## Понятие массива и его представление в памяти Массив — это структура данных, которая хранит упорядоченный набор однотипных элементов. Вот как можно объявить и инициализировать массив, в котором находятся пять целых чисел: ```go {.example_for_playground .example_for_playground_001} arr := [5]int{1, 2, 3, 4, 5} ``` Длина массива — это часть типа массива. Так, `arr` из примера выше имеет тип `[5]int`. `[5]int` в памяти компьютера — это всего лишь пять целочисленных значений, расположенных последовательно. Массивы в Go — это последовательность значений. Переменная массива означает весь массив, а не указатель на первый элемент, как, например, в языке C. Это означает, что когда вы передаете массив в функцию, то передается копия всего массива, а не указатель на него. Такого поведения можно избежать, создав указатель на массив и передав его в качестве аргумента. Чтобы не указывать количество элементов массива `[5]int`, используется следующая запись: ```go {.example_for_playground .example_for_playground_002} arr := [...]int{1, 2, 3, 4, 5} ``` В этом случае компилятор сам посчитает количество элементов. Тип массива `arr` от этого не поменяется, и будет по-прежнему `[5]int`. Можно инициализировать лишь первые несколько элементов, тогда оставшиеся получат значение по умолчанию: ```go {.example_for_playground .example_for_playground_003} arr := [10]int{1, 2, 3, 4, 5} ``` Массив в этом случае содержит следующие элементы: ``` [1 2 3 4 5 0 0 0 0 0] ``` Если нет необходимости инициализировать массив конкретными значениями, то он объявляется следующим образом: ```go var arr [5]int ``` Тогда каждому элементу массива будет присвоено значение по умолчанию для этого типа. Узнать длину массива можно с помощью функции `len()`: ```go fmt.Println(len(arr)) ``` Индексация элементов массива начинается с нуля, т.е. в примере ниже элемент с индексом `0` массива `arr` равен `1`. Элемент с индексом `4` равен `5`. Длина массива `arr` равна `5`. ```go arr := [5]int{1, 2, 3, 4, 5} ``` Чтобы обратиться к элементу массива с индексом `i`, достаточно поставить после имени массива квадратные скобки с этим индексом `[i]`: ```go arr[3] = 250 ``` Можно инициализировать конкретные элементы массива по их индексу: ```go arr := [10]int{4: 100, 7: 400} ``` Массив в этом случае содержит следующие элементы: ``` [0 0 0 0 100 0 0 400 0 0] ``` Простое число — это натуральное число, которое больше `1` и делится только на себя и на `1`. {.task_text} Напишите программу, которая заполнит массив из `100` элементов первыми `100` простыми числами. Выведите полученный массив на экран. {.task_text} ```go {.task_source #golang_chapter_0040_task_0010} package main import "fmt" func main() { // ваш код здесь } ``` Проверяйте на простоту все числа подряд и добавляйте простые в массив до тех пор, пока не заполните его. {.task_hint} ``` golang {.task_answer} package main import "fmt" func main() { var arr [100]int i := 0 // индекс простого числа number := 2 // число for i < 100 { isPrime := true for j := 2; j < number; j++ { if number%j == 0 { isPrime = false break } } if isPrime { arr[i] = number i++ } number++ } fmt.Println(arr) } ``` ## Ключевое слово `range` Для обхода массива необязательно заводить переменную-счетчик и проверять ее на равенство длине массива. Для этих целей удобно использовать цикл с `range`: ```go {.example_for_playground .example_for_playground_004} arr := [3]string{"С", "Oberon", "Pascal"} for key, val := range arr { fmt.Println(key, ": ", val) } ``` ``` 0 : С 1 : Oberon 2 : Pascal ``` Функция `range` возвращает два аргумента: ключ `key` и значение `val`. В данном случае ключ представляет собой индекс элемента массива, а `val` — значение элемента массива. В Go, если какая-либо из возвращаемых переменных не нужна, вместо имени можно поставить пустой идентификатор `_`. Например: ```go {.example_for_playground .example_for_playground_005} arr := [3]string{"С", "Oberon", "Pascal"} for _, val := range arr { fmt.Println(val) } ``` ``` С Oberon Pascal ``` ## Многомерные массивы Массивы могут быть многомерными. Вот как можно объявить двумерный массив (матрицу) из чисел типа `int` и задать элементу этой матрицы с индексами `2`, `3` значение `250`: ```go {.example_for_playground .example_for_playground_006} var arr [4][5]int arr[2][3] = 250 ``` На практике обычно используется одномерные и двумерные массивы, в исключительных случаях — трехмерные. Использовать массивы большей размерности, без веских на то причин, не рекомендуется. Это усложняет программный код и чревато ошибками. Объявите двумерный массив типа `int` размерностью `10x10` и задайте каждому его элементу значение, равное сумме индексов этого элемента. Например, для элемента с индексами `4` и `5` значение будет равно `4 + 5 = 9`. Выведите полученный массив в виде таблицы на экран, отделяя значения друг от друга символом табуляции `\t`. Последний элемент каждой строки таблицы символа табуляции содержать не должен. {.task_text} ```go {.task_source #golang_chapter_0040_task_0020} package main import "fmt" func main() { // ваш код здесь } ``` Чтобы пройти по всем элементам двумерного массива, необходимо написать цикл в цикле. Внешний цикл осуществляет проход по строкам, внутренний - по столбцам. {.task_hint} ``` golang {.task_answer} package main import "fmt" func main() { var arr [10][10]int for i := 0; i < 10; i++ { for j := 0; j < 10; j++ { arr[i][j] = i + j if j == 9 { fmt.Print(arr[i][j]) } else { fmt.Print(arr[i][j], "\t") } } fmt.Println() } } ``` Верхняя треугольная матрица (таблица) — матрица, у которой все элементы, стоящие ниже главной диагонали, равны нулю. Главная диагональ — набор элементов матрицы, взятый по диагонали от верхнего левого угла в направлении правого нижнего, т.е. таких элементов, для которых равны номер строки и номер столбца. {.task_text} Объявите двумерный массив типа `int` размерностью `10x10` и задайте его элементам такие значения, чтобы получилась верхняя треугольная матрица. {.task_text} Каждому ненулевому элементу этой матрицы задайте значение, равное сумме номеров этого элемента. Номера матрицы в линейной алгебре принято считать с единицы. Это нужно иметь в виду при вычислении суммы. Так, элемент в коде с индексами `[3][1]` должен быть равен `6`, потому что в линейной алгебре этот элемент имеет номера `[4][2]`. {.task_text} Выведите полученный массив в виде таблицы на экран, отделяя значения друг от друга символом табуляции `\t`. Последний элемент каждой строки таблицы символа табуляции содержать не должен. {.task_text} ```go {.task_source #golang_chapter_0040_task_0030} package main import "fmt" func main() { // ваш код здесь } ``` Если `i > j`, где `i` - индекс строки, а `j` - индекс столбца, то элемент находится ниже главной диагонали. {.task_hint} ``` golang {.task_answer} package main import "fmt" func main() { var arr [10][10]int for i := 0; i < 10; i++ { for j := 0; j < 10; j++ { arr[i][j] = i + j + 2 if i > j { arr[i][j] = 0 } if j == 9 { fmt.Print(arr[i][j]) } else { fmt.Print(arr[i][j], "\t") } } fmt.Println() } } ``` Напоследок заметим, что массивы имеют множество недостатков. Вот некоторые из них: - после того, как массив определен, вы не можете изменить его размер; - передавая массив функции в качестве параметра, вы на самом деле передаете его копию, поэтому изменения внутри массива по выходу из этой функции будут потеряны; - передача массива в функцию всегда выполняется медленно, поскольку каждый раз создается копия этого массива. Конечно, можно передать массив в функцию по указателю. Однако тип такого указателя зависит от размера массива, поскольку размер массива — часть его типа. Делать подобное неудобно. Этих недостатков лишены срезы, о которых пойдет речь в следующей главе. ## Резюме 1. В Go используются массивы, которые могут быть как одномерными, так и многомерными. 2. Для обхода массива удобно использовать цикл с `range`. 3. Массивы обладают множеством недостатков, которых лишены срезы, поэтому массивы в Go используются достаточно редко.
Отправка...
Наша группа в telegram. Здесь можно задавать вопросы и общаться.
Задонатить. Если вам нравится курс, вы можете поддержать развитие площадки!