Одномерные массивы целых чисел на языке Си
Привет! Сегодня мы погрузимся в мир массивов — одной из самых важных структур данных в программировании. Представь: вместо сотен переменных ты сможешь управлять всеми данными одной командой. Готов стать мастером массивов? Поехали!
🎯 Что такое массив и зачем он нужен?
Представь, что ты ведёшь статистику в игре: сколько очков набрал каждый из 20 игроков. Создавать 20 отдельных переменных — это кошмар! Массив решает эту проблему: он хранит все значения вместе, и к каждому можно обратиться по его номеру (индексу).
💡 Определение
Массив — это набор элементов одного типа, у которых общее имя. Каждый элемент имеет свой индекс — номер позиции в массиве.
📦 Аналогия из жизни
Массив — это как полка с пронумерованными коробками:
- Каждая коробка (элемент) содержит один предмет (значение)
- Все коробки одинакового размера (один тип данных)
- Чтобы достать что-то, нужно знать номер коробки (индекс)
⚠️ Важно! Индексация с нуля
В языке Си индексы массивов начинаются с 0, а не с 1. Это как этажи в американских зданиях: первый этаж называется "0 floor".
int scores[5]; // Массив из 5 целых чисел
// Индексы: 0, 1, 2, 3, 4
📝 Как описать массив в программе
Прежде чем использовать массив, его нужно объявить — сказать компилятору: "Выдели мне память под N элементов такого-то типа".
Объявление массива — выделение памяти для хранения элементов
🔧 Общий формат объявления
тип_данных имя_массива[размер];
Примеры:
int temperatures[7]; // Массив для температуры на каждый день недели
float prices[100]; // Массив из 100 цен (дробные числа)
char symbols[10]; // Массив из 10 символов
Что происходит? Компилятор резервирует в памяти место для всех элементов сразу. Для int temperatures[7] будет выделено 7 ячеек подряд, каждая размером с целое число.
🎨 Инициализация массива (заполнение при создании)
Если значения известны заранее, можно сразу их записать:
int scores[5] = {100, 85, 92, 78, 95};
// scores[0] = 100
// scores[1] = 85
// scores[2] = 92
// scores[3] = 78
// scores[4] = 95
Или короче (компилятор сам посчитает размер):
int scores[] = {100, 85, 92, 78, 95}; // Размер = 5
⚙️ Как работать с элементами массива
Чтобы получить или изменить значение, используй имя_массива[индекс]
🎯 Обращение к элементу
int A[3] = {10, 20, 30};
printf("%d\n", A[0]); // Выведет: 10
printf("%d\n", A[2]); // Выведет: 30
A[1] = 99; // Теперь A[1] = 99
⚠️ Внимание!
Индексы идут от 0 до (размер - 1). Для массива из 5 элементов допустимые индексы: 0, 1, 2, 3, 4. Обращение к A[5] — ошибка!
🔧 Заполнение массива
Рассмотрим три основных способа, как можно заполнить массив данными
Три способа заполнения массива: ввод, формула, случайность
⌨️ Ввод с клавиатуры
int A[8];
int i;
printf("Введите 8 чисел:\n");
for (i = 0; i < 8; i++) {
scanf("%d", &A[i]);
}
Как это работает? Цикл for повторяет действие 8 раз, каждый раз меняя i от 0 до 7. На каждой итерации программа ждёт ввод числа и сохраняет его в A[i].
📐 Заполнение по формуле
int A[7];
int i;
for (i = 0; i < 7; i++) {
A[i] = 2 * i + 1; // Нечётные числа
}
Какие значения получатся?
| i | Выражение | A[i] |
|---|---|---|
| 0 | 2*0 + 1 | 1 |
| 1 | 2*1 + 1 | 3 |
| 2 | 2*2 + 1 | 5 |
| 6 | 2*6 + 1 | 13 |
🎲 Случайные числа
#include <stdlib.h> // Для rand()
#include <time.h> // Для time()
int A[10];
int i;
srand(time(NULL)); // Инициализация
for (i = 0; i < 10; i++) {
A[i] = rand() % 100; // От 0 до 99
}
Зачем rand() % 100? Функция rand() возвращает большое число. Операция % 100 берёт остаток от деления на 100, получая числа от 0 до 99.
❓ Вопрос
Какие значения будут присвоены элементам массива A?
for (i = 0; i < 7; i++) {
A[i] = 2 * i;
}
Ответ: 0, 2, 4, 6, 8, 10, 12
🖥️ Вывод массива на экран
Во многих случаях бывает полезно вывести значения элементов массива на экран
➡️ Вывод в строку через пробел
int A[5] = {12, 7, 34, 9, 21};
int i;
for (i = 0; i < 5; i++) {
printf("%d ", A[i]);
}
// Результат: 12 7 34 9 21
⬇️ Вывод в столбик
for (i = 0; i < 5; i++) {
printf("A[%d] = %d\n", i, A[i]);
}
// Результат:
// A[0] = 12
// A[1] = 7
// A[2] = 34
// A[3] = 9
// A[4] = 21
🧮 Пример 1: Сумма элементов массива
Задача: В посёлке N домов. Известно, сколько людей живёт в каждом доме. Нужно подсчитать общее количество жителей.
Алгоритм суммирования: обходим все элементы и накапливаем сумму
💡 Решение
Идея: Заведём переменную sum (сумма), изначально равную 0. Пройдём по всем элементам массива и будем прибавлять каждое значение к sum.
#include <stdio.h>
int main() {
int N = 5; // Количество домов
int A[5] = {120, 85, 200, 150, 95}; // Жители
int sum = 0;
int i;
// Суммируем
for (i = 0; i < N; i++) {
sum = sum + A[i];
}
printf("Всего жителей: %d\n", sum);
return 0;
}
Вывод: Всего жителей: 650
📊 Как это работает (трассировка)
| Шаг | i | A[i] | Операция | Текущее значение sum |
|---|---|---|---|---|
| 0 | - | - | sum = 0 | 0 |
| 1 | 0 | 120 | sum += A[0] | 120 |
| 2 | 1 | 85 | sum += A[1] | 205 |
| 3 | 2 | 200 | sum += A[2] | 405 |
| 4 | 3 | 150 | sum += A[3] | 555 |
| 5 | 4 | 95 | sum += A[4] | 650 |
💻 Попробуй на компьютере!
Выполни эту программу и проверь результат. Попробуй изменить значения в массиве — сумма тоже изменится!
🔍 Пример 2: Поиск максимального элемента
Задача: У тебя есть массив с результатами игроков. Нужно найти лучший результат (максимальное значение).
Алгоритм поиска максимума: сравниваем элементы и запоминаем лучший
💡 Алгоритм поиска максимума
Идея (как в реальной жизни):
- Берём первую карточку — это временный "чемпион"
- Сравниваем со второй: если она больше — она новый чемпион
- Повторяем со всеми остальными карточками
- В конце у нас остаётся настоящий максимум
#include <stdio.h>
int main() {
int A[5] = {100, 120, 130, 80, 70};
int imax; // Индекс максимального элемента
int i;
imax = 0; // Начинаем с первого элемента
for (i = 1; i < 5; i++) { // Проверяем остальные
if (A[i] > A[imax]) {
imax = i; // Нашли нового чемпиона!
}
}
printf("Максимальный элемент: A[%d] = %d\n", imax, A[imax]);
return 0;
}
Вывод: Максимальный элемент: A[2] = 130
📋 Трассировка алгоритма
| imax | i | A[i] > A[imax] | Действие |
|---|---|---|---|
| 0 | 1 | 120 > 100 ✓ | imax = 1 |
| 1 | 2 | 130 > 120 ✓ | imax = 2 |
| 2 | 3 | 80 > 130 ✗ | - |
| 2 | 4 | 70 > 130 ✗ | - |
Результат: Максимальный элемент — A[2] = 130
❓ Подумай!
Если в массиве несколько элементов, значения которых равны максимальному значению, то данная программа найдёт первый из них (первое вхождение). Подумайте, что нужно изменить в программе, чтобы она находила последний из максимальных элементов. Как следует преобразовать программу, чтобы с её помощью можно было найти минимальный элемент массива?
🎯 Пример 3: Поиск элемента по значению
Задача: Проверить, есть ли в массиве конкретное значение (например, игрок с ником "777").
Последовательный поиск: проверяем каждый элемент по очереди
💡 Решение
#include <stdio.h>
int main() {
int A[5] = {45, 23, 77, 12, 99};
int x; // Искомое значение
int k = 0; // Индекс найденного элемента (0 = не найден)
int i;
printf("Что ищем? ");
scanf("%d", &x);
for (i = 0; i < 5; i++) {
if (A[i] == x) {
k = i + 1; // Сохраняем позицию (i+1, т.к. для пользователя удобнее с 1)
break; // Нашли — выходим из цикла
}
}
if (k == 0) {
printf("Элемент не найден\n");
} else {
printf("Элемент найден на позиции %d\n", k);
}
return 0;
}
🔧 Как это работает?
- Переменная
kизначально равна 0 (признак "не найдено") - Если элемент найден,
kполучает номер позиции breakпрерывает цикл — незачем искать дальше
Результатом решения задачи второго типа (нахождение элемента массива, значение которого равно заданному значению) может быть:
- k — индекс элемента массива такой, что A[k] = x, где x — заданное число
- сообщение о том, что искомого элемента в массиве не обнаружено
🎮 Альтернативный вариант
Если в массиве несколько элементов, значения которых равны заданному числу, то программа найдёт последний из них. Во многих случаях требуется найти первый из элементов, имеющих соответствующее значение, и дальнейший просмотр массива прекратить. Для этой цели можно использовать следующий фрагмент программы:
i = 0;
do {
i = i + 1;
} while ((A[i] != x) && (i < N));
if (A[i] == x) {
printf("%d\n", i);
} else {
printf("Нет\n");
}
❓ Вопрос для размышления
Зачастую требуется определить количество элементов, удовлетворяющих некоторому условию. В этом случае вводится переменная, значение которой увеличивается на единицу каждый раз, когда найден нужный элемент.
Количество каких элементов массива подсчитывается с помощью следующего фрагмента программы?
k = 0;
for (i = 0; i < N; i++) {
if (A[i] % 2 == 0) {
k = k + 1;
}
}
printf("k=%d\n", k);
Ответ: Подсчитывается количество чётных элементов массива
❓ Ещё один вопрос
Какому условию удовлетворяют элементы массива, значения которых суммируются с помощью следующего фрагмента программы?
s = 0;
for (i = 0; i < N; i++) {
if ((A[i] % 2 == 0) && (A[i] % 10 == 4)) {
s = s + A[i];
}
}
printf("s=%d\n", s);
Ответ: Суммируются элементы, которые являются чётными И оканчиваются на 4 (например: 4, 14, 24, 34...)
🔄 Сортировка массива
Сортировка — это расстановка элементов в определённом порядке (по возрастанию или убыванию). Это как выстроить игроков по рангу или отсортировать файлы по дате.
Визуализация сортировки выбором: находим минимум и ставим на нужное место
📚 Типы порядка
Есть два основных типа порядка:
- По возрастанию (неубывающий): каждый следующий элемент ≥ предыдущего
Пример: 1, 2, 3, 5, 7 - По убыванию (невозрастающий): каждый следующий элемент ≤ предыдущего
Пример: 10, 8, 5, 3, 1
🎯 Сортировка выбором
Идея: Ищем самый маленький элемент, ставим его на первое место. Потом ищем второй по величине — на второе место. И так далее.
Алгоритм:
- Находим минимальный элемент во всём массиве
- Меняем его местами с первым элементом
- Теперь первый элемент на своём месте — забываем про него
- Повторяем для оставшейся части массива
💻 Код программы
#include <stdio.h>
int main() {
int A[5] = {9, 1, 4, 3, 6};
int i, j, imin, temp;
// Сортировка выбором
for (i = 0; i < 4; i++) { // Последний элемент и так на месте
imin = i; // Ищем минимум в неотсортированной части
for (j = i + 1; j < 5; j++) {
if (A[j] < A[imin]) {
imin = j;
}
}
// Меняем местами A[i] и A[imin]
temp = A[i];
A[i] = A[imin];
A[imin] = temp;
}
// Выводим результат
for (i = 0; i < 5; i++) {
printf("%d ", A[i]);
}
printf("\n");
return 0;
}
Вывод: 1 3 4 6 9
📊 Процесс сортировки (пошагово)
Рассмотрим процесс сортировки выбором на примере массива A = {9, 1, 4, 3, 6}
| Индекс | 0 | 1 | 2 | 3 | 4 |
|---|---|---|---|---|---|
| Исходный | 9 | 1 | 4 | 3 | 6 |
| Шаг 1 | 1 | 9 | 4 | 3 | 6 |
| Шаг 2 | 1 | 3 | 4 | 9 | 6 |
| Шаг 3 | 1 | 3 | 4 | 9 | 6 |
| Шаг 4 | 1 | 3 | 4 | 6 | 9 |
| Итого | 1 | 3 | 4 | 6 | 9 |
Зелёным цветом отмечены элементы, которые уже стоят на своих местах.
❓ Вопрос
В этом массиве из 8 элементов операцию выбора максимального элемента мы проводили 7 раз. В массиве из N элементов такая операция будет проводиться N - 1 раз. Объясните почему.
Ответ: Потому что когда мы отсортируем N-1 элементов, последний элемент автоматически окажется на своём месте — его не нужно проверять.
💻 Практическое задание
Запишите полный текст программы и выполните её на компьютере для рассмотренного в примере массива A.
Разработайте подпрограммы max и swap для поиска максимального элемента и обмена значениями двух элементов. Модифицируйте программу сортировки выбором, использовав в ней одну или обе из названных подпрограмм.
🗂️ Массивы и последовательности
Если требуется обработать некоторое множество однотипных целочисленных данных, то в зависимости от решаемой задачи можно пойти одним из двух путей
📦 Обработка массива
В памяти компьютера будут храниться все элементы рассматриваемого множества; при необходимости к любому из них можно обратиться из разных мест программы.
Пример: Когда нужно многократно обращаться к данным, сравнивать элементы, искать максимум/минимум.
🔄 Обработка последовательности
В памяти компьютера будет храниться единственный элемент рассматриваемого множества — тот, который был введён последним; значения ранее введённых элементов множества будут утеряны безвозвратно.
Пример: Когда нужно только подсчитать количество или сумму элементов с определённым свойством.
💾 Когда использовать массив?
Такой вариант экономичен с точки зрения использования памяти, но он не применим для решения ряда задач.
Массив необходим, когда:
- Нужно многократно обращаться к элементам
- Требуется сортировка данных
- Нужно найти максимум/минимум и его позицию
- Требуется изменять данные и снова к ним возвращаться
📌 Самое главное
Давайте подведём итоги нашего путешествия в мир массивов:
тип имя[размер];
🎮 Проверь себя
Проверьте, как хорошо вы усвоили материал!
1. Объясни разницу: чем отличается индекс элемента от значения элемента? Приведи пример.
Подсказка: Индекс — это "адрес" ячейки (номер коробки), а значение — это то, что в ней лежит.
Пример: В массиве int A[3] = {10, 20, 30}; индекс 1 указывает на вторую ячейку, а значение A[1] = 20.
2. Может ли массив одновременно содержать целые числа (типа int) и дробные (типа float)? Почему?
Ответ: Нет, массив может содержать только элементы ОДНОГО типа. Это его главное свойство.
3. Для чего нужны массивы? Почему нельзя обойтись обычными переменными?
Представь, что тебе нужно хранить баллы 100 игроков. Создавать 100 переменных score1, score2, ... score100 — это...
4. Что означает каждая часть в записи float temperatures[7];?
float— тип элементов (дробные числа)temperatures— имя массива[7]— размер массива (7 элементов)
5. Какой массив создан следующим кодом? Сколько в нём элементов? Какие значения?
int A[] = {5, 10, 15, 20};
Ответ: Массив целых чисел из 4 элементов со значениями: A[0]=5, A[1]=10, A[2]=15, A[3]=20
6. Какие преимущества обеспечивает хранение длины массива в отдельной переменной?
Подумай: если размер массива изменится, что придётся менять в программе?
7. Напиши два варианта программы, вычисляющей среднюю за неделю температуру воздуха. Организуй:
а) обработку последовательности;
б) обработку массива.
Исходные данные вводятся с клавиатуры.
Подсказка для варианта а): Можно сразу суммировать вводимые значения, не сохраняя их.
Подсказка для варианта б): Сначала заполни массив, потом посчитай сумму.
8. Дан массив из десяти целых чисел. Напиши программу подсчёта:
а) количества чётных элементов массива;
б) суммы нечётных элементов массива;
в) количества элементов массива, имеющих максимальное значение.
Для пункта а): Используй условие A[i] % 2 == 0
Для пункта в): Сначала найди максимум, потом посчитай, сколько элементов равны ему
9. В классе 20 учеников писали диктант по русскому языку. Напиши программу, подсчитывающую количество двоек, троек, четвёрок и пятёрок, полученных за диктант.
Совет: Создай 4 переменных-счётчика: count2, count3, count4, count5
10. Объявлен набор в школьную баскетбольную команду. Известен рост каждого из N учеников, желающих попасть в эту команду. Составьте алгоритм подсчёта количества претендентов, имеющих шанс попасть в команду, если рост игрока команды должен быть не менее 170 см. Напишите программу, считая рост претендента в команду случайным числом из диапазона от 150 до 200 см, а число претендентов N = 50.
Подсказка: A[i] = 150 + rand() % 51; даст случайное число от 150 до 200
11. В целочисленных массивах A и B содержатся длины катетов десяти прямоугольных треугольников (A[i] — длина первого катета, B[i] — длина второго катета i-го треугольника). Напишите программу, которая по имеющимся данным определит треугольник с наибольшей площадью и выведет его номер, длины катетов и площадь. Предусмотрите случай, когда таких треугольников несколько.
Формула площади: S = (A[i] * B[i]) / 2
Подсказка: Найди максимальную площадь, затем выведи все треугольники с такой площадью
12. Занесите информацию о десяти странах мира в массивы NAME (название страны), K (численность населения), S (площадь страны). Напишите программу, выводящую названия стран в порядке возрастания плотности их населения.
Формула плотности: плотность = K[i] / S[i]
Подсказка: Создай дополнительный массив для хранения плотности, отсортируй его, выводя соответствующие названия стран
13. Найдите информацию о таких частных случаях списка, как стек и очередь. Подготовьте короткое сообщение.
Стек: Последним пришёл — первым вышел (как стопка тарелок)
Очередь: Первым пришёл — первым вышел (как очередь в магазине)
🎯 Практические задания
Попробуй применить полученные знания на практике!
✍️ Задание 1: Заполнение массива
Создай массив из 10 элементов и заполни его:
- а) Числами от 1 до 10
- б) Квадратами чисел от 1 до 10
- в) Случайными числами от 0 до 100
Выведи массив на экран после каждого заполнения.
🔍 Задание 2: Поиск элементов
Дан массив: {45, 23, 77, 12, 99, 23, 8}
Напиши программу, которая:
- Найдёт и выведет максимальный элемент
- Найдёт и выведет минимальный элемент
- Посчитает количество элементов больше 50
🎨 Задание 3: Модификация массива
Создай массив из 8 элементов с любыми значениями. Напиши программу, которая:
- Увеличит все элементы массива в 2 раза
- Выведет изменённый массив
- Посчитает сумму всех элементов нового массива
🔄 Задание 4: Сортировка
Реализуй программу сортировки массива {64, 34, 25, 12, 22, 11, 90} по возрастанию методом выбора.
Выведи массив до и после сортировки.
📊 Задание 5: Статистика
Дан массив оценок 15 учеников: случайные числа от 2 до 5.
Напиши программу, которая:
- Заполнит массив случайными оценками
- Посчитает количество каждой оценки
- Вычислит средний балл класса
🎮 Задание 6: Игровая статистика
Создай массив из 10 элементов — очки игроков в матче.
Напиши программу, которая:
- Найдёт игрока с максимальными очками
- Найдёт игрока с минимальными очками
- Выведет разницу между лучшим и худшим результатом
💡 Полезные советы
Несколько важных рекомендаций для работы с массивами
✅ Хорошие практики
- Всегда проверяй границы массива (индексы от 0 до N-1)
- Используй константы для размера массива
- Давай массивам понятные имена (scores, temperatures, prices)
- Инициализируй переменные-счётчики нулём
- Комментируй сложные алгоритмы
⚠️ Частые ошибки
- Обращение к несуществующему индексу (A[10] при размере 10)
- Забыть инициализировать счётчики и суммы
- Использовать
=вместо==в условии - Начинать цикл с 1 вместо 0
- Не учитывать, что последний индекс = размер - 1