C Урок 9. Массивы. Часть 1



Очень часто нам при написании программ требуется очень много данных одного типа, вследствие чего может потребоваться и огромное количество переменных, а требование уникальности имени последних приведёт к тому, что мы просто запутаемся в своей программе, не говоря уж о тех, кто будет наш исходный код читать. Такое требование может, например возникнуть, если мы хотим записывать в переменные показания какого-то счётчика каждую минуту и делать это мы собирается каждый час, а затем эти данные анализировать. Если использовать обычные переменные, то нам их уже потребуется 60 штук. Нам надо будет придумать 60 имён для них и потом не запутаться. Да и представьте, какое количество будет кода даже для того, чтобы эти переменные объявить.

Для этого нам приходят на помощь массивы.

Массив — это набор однотипных данных. Эти однотипные данные называются элементами массива.

Массив при его объявлении располагается в памяти непрерывно, что даёт также помимо всех прочих плюсов ещё и удобство обращения к его элементам.

Подобно переменным, каждый массив также имеет своё имя.

Кроме имени, у каждого массива есть ещё и его размер, который указывает, сколько именно элементов содержит массив.

Массивы также могут быть одномерными и многомерными. Многомерные массивы — это по сути массивы, элементами которых являются также массивы.

Начнём, как водится, с более простых массивов — одномерных.

При объявлении массива, подобно переменной, сначала мы указываем тип переменных, которые будут являться элементами массива, у нас же переменные однотипные по определению массива. Затем мы указываем имя массива, требования к которому аналогичны требованиям к именам переменных. И далее мы указываем в квадратных скобках размер нашего массива, который является количеством его элементов.

Давайте попробуем объявить массив, например из 10 элементов целого типа

 

int a[10];

 

Мы объявили неинициализированный массив, тем самым мы по большому счёту выделили непрерывный участок памяти для 10 переменных целого типа.

a — имя массива, int — его тип, 10 — количество элементов.

Таким образом, элементы массива после объявления имеют неизвестное значение, то значение, которое было в данном участке памяти до объявления.

Каким же образом нам заполнить элементы массива определёнными данными.

Для этого мы должны знать, как мы можем обратиться к каждому элементу массива.

Чтобы обратиться к элементу массива, мы в квадратных скобках после имени массива указываем индекс его элемента, которые считаются от 0

 

 

Поэтому, чтобы присвоить какое-то значение, например, пятому по счёту элементу массива, то мы поступаем следующим образом

 

a[4] = 15;

 

То есть, чтобы проинициализировать все элементы массива, мы в классическом случае делаем так

 

a[0] = -8; a[1] = 44; a[2] = 32; a[3] = -10; a[4] = 15;

a[5] = 56; a[6] = 27; a[7] = 72; a[8] = 60; a[9] = -1;

 

Получится вот такой результат

 

 

Также присвоить элементу значение мы можем и в результате вычисления каких-то выражений, например

 

a[6]++;

 

Проинициализировать элементы массива мы можем и при его объявлении.

Попробуем это сделать, чтобы получить тот же самый результат, что и при предыдущем способе инициализации

 

int a[10] = {-8, 44, 32, -10, 15, 56, 27, 72, 60, -1};

 

Тем самым мы инициализировали все элементы массива. Поэтому предыдущий способ инициализации элементов, когда мы присваиваем значения отдельных его элементов уже в ходе программы, а не при объявлении массива, подходит для случаев, когда надо изменить данные, либо когда нам надо инициализировать малое количество данных.

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

 

int a[] = {-8, 44, 32, -10, 15, 56, 27, 72, 60, -1};

 

В данном случае компилятор сам определит размер массива.

Давайте рассмотрим ещё некоторые способы инициализации элементов массивов.

Если мы хотим заполнить массив нулями, то мы можем поступить так при его объявлении

 

int a[10] = {0};

 

Ещё один способ сделать добиться такого же результата

 

int a[10] = {};

 

В этих случаях мы всем десяти элементам массива присвоим значение 0

 

 

А что будет, интересно, если мы поступим вот так?

 

int a[10] = {7};

 

 

Казалось бы, мысля логически, все элементы массива получат значение 7. Но не тут-то было! Первый элемент будет равен 7, остальные получат значение 0

 

 

Попробуем сделать вот так

 

int a[10] = {7, -5, 15};

 

Результат, соответственно, будет таким

 

 

Таким образом, если мы инициализируем при объявлении количество элементов, меньшее размеру массива, то данные значения получат первые элементы, а остальные заполнятся нулями.

Также в качестве доступа к элементам, а также при инициализации, значение индекса элемента и также значение размера при объявлении может быть значением какой-либо переменной или константы.

Поэтому мы можем объявить массив следующим образом

 

int n = 10;

int a[n];

 

При таком объявлении массив у нас также будет размером в 10 элементов.

Подобным образом мы можем получить доступ к определённому элементу массива

 

n = 6;

a[n] = 1;

 

В данном случае мы присвоили элементу с индексом 6 значение 1.

Обычно такой способ очень применим в случае занесения в элементы массива каких-то упорядоченных данных или данных из какого-то потока или из аналогичных элементов другого массива.

Например. если мы хотим в элементы массивы занести числа от 1 до 10, то мы поступим следующим образом

 

int i;

int a[10];

for(i=0;i<10;i++)

{

   a[i] = i+1;

}

 

В данном случае результат будет таким

 

 

Пока мы изучали поведение массивов, пользуясь только типом int.

В принципе, при использовании других типов данных поведение массивов будет аналогичным.

Несколько отличается работа с массивами символов или, как их ещё называют, со строковыми массивами. Там могут существовать ещё некоторые виды их инициализации и работы с их элементами.

Давайте чуть позже займёмся строчными массивами, а пока перейдём к практической части и немного проработаем то, с чем уже познакомились.

Создадим новый проект из проекта прошлого занятия с именем MYPROG08 и присвоим ему имя MYPROG09.

Откроем файл main.c и в функции main(), как обычно, удалим весь код тела кроме возврата нуля, останется от него вот это

 

int main()

{

   return 0; //Return an integer from a function

}

 

 

Также в файле build.cmd немного изменим вот эту строчку, потому, что нам интересно будет в отладке посмотреть некоторые вещи

 

gcc -g3 -Wall -c main.c

 

В функции main() файла main.c объявим сначала вот такую переменную для счётчика

 

 

Далее объявим целочисленный массив и присвоим значения его элементам сначала вот таким образом

 

 

Покажем значения элементов в консоли, чтобы сразу видеть результат работы кода

 

 

Соберём код и проверим, как заполнился данными наш массив

 

Все элементы заполнились.

Попробуем проинициализировать массив во время его объявления. Закомментируем сначала вот этот участок кода

 

 

Добавим теперь вот такой код в нашу программу

 

 

Проверим результат

 

 

Результат будет таким же.

Теперь попробуем заполнить элементы массива нулевыми значениями, для чего, закомментировав предыдущий код, напишем следующий

 

 

Просмотрим в консоли наши элементы, собрав предварительно код

 

 

В элементах у нас нули. Всё правильно.

Попробуем проинициализировать только один первый элемент массива, закомментировав сначала также предыдущий код

 

 

Проверим, как это сработает

 

 

Всё сработало. Первый элемент получил значение 18, остальные проинициализировались нулями.

Попробуем присвоить значения первым трём элементам

 

 

Проверим

 

 

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

Теперь давайте немного познакомимся со спецификой работы с символьными (строчными) массивами.

Мы также можем символьный массив проинициализировать обычным классическим первым способом, сначала его объявив, а потом уже присваивая значения его элементам

 

str1[0] = 'H'; str1[1] = 'e'; str1[2] = 'l'; str1[3] = 'l'; str1[4] = 'o';

str1[5] = '!'; str1[6] = '\0'; str1[7] = 0; s tr1[8] = 0; str1[9] = 0;

 

Результат будет таким

 

Также подойдёт и второй способ заполнения

 

char str1[10] = {'H', 'e', 'l', 'l', 'o', '!', '\0'};

 

Результат будет таким же.

Также мы можем воспользоваться для инициализации строк в символьных массивах при помощи специальной строковой функции strcpy, только данный способ мы рассмотрим в практической части.

Можно инициализировать строку в массиве вот так

 

char str1[10] = {"Hello!"};

 

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

Можно поступить и вот так, обходясь без фигурных скобок

 

char str1[10] = "Hello!";

 

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

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

 

char str1[] = "Hello!";

 

В данном случае массив будет состоять из 7 элементов, 6 из которых — символы нашей строки, а седьмой — ноль, которым компилятор завершит обязательно нашу строку

 

Давайте теперь попрактикуемся немного со строками.

Вернёмся в наш проект, в функции main() закомментируем наш последний код и введём следующий, в котором мы объявим и сразу проинициализируем символьный массив. Мы не будем сначала объявлять, потом инициализировать, так мало кто делает, и мы тоже не будем. Затем отобразим его элементы сначала в числовом, затем в символьном виде, а затем ещё отобразим как обычную строку

 

 

Соберём код и посмотрим, что у нас получится

 

 

Вот такой вот результат. В первой строке в консоли мы видим коды наших символов, во второй — сами символы по отдельности, а в третьей — всю строку в нормальном виде.

Теперь попробуем наш массив объявить как безразмерный и всё отобразить тем же способом, опять же закомментировав предыдущий код

 

 

Мы комментируем участки кода для того, чтобы затем, после открытия впоследствии наших исходников, мы понимали ход наших мыслей.

Посмотрим результат работы кода

 

 

Отлично!

Только при инициализации безразмерных массивов надо быть аккуратными, чтобы потом не попытаться обратиться к его несуществующим элементам. Мы должны чётко понимать, какой размер нашего массива. Правда, при использовании библиотечных функций работы со строками, в них всё проверяется и риска никакого нет, но если мы решили сами получать доступ к тем или иным элементам, то определённый риск существует.

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

 

 

Предыдущий урок Программирование на C Следующая часть

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

C Массивы

2 комментария на “C Урок 9. Массивы. Часть 1
  1. Добрый вечер!
    Каким образом, можно сделать инкремент одного элемента в массиве.
    Допустим имеем массив — uint8_t send[] = {0x0F,0x00,0x02,0x00,0x00,0x00};
    Необходимо сделать инкремент на единицу второго элемента массива, при этом не изменяя остальные элементы массива?

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*