popov . dev

Главная

Библиотека

Статьи

Массивы в языке ...

Массивы в языке программирования C

В языке Си массив - это набор последовательных объектов одного типа в памяти. Как создавать и использовать массивы, объясняется в этом разделе главы. Массив может представлять собой набор последовательных целых чисел, набор последовательных чисел с плавающей точкой, набор последовательных символов и т.д. Что касается символов (char), то различные символы, расположенные рядом друг с другом, будут образовывать строку, если последний символ равен \0, т.е. null. На самом деле, в C или любом другом языке невозможно создать набор последовательных строк для массива.

Массив целых чисел

Ниже приведен массив из 5 целых чисел:

int arrInt[] = {25, 20, 256, 5, 7};

Для объявления массива можно использовать следующий синтаксис:

Type arrayName[] = {value1, value2, value3, . . .}

Он начинается с указания типа объектов, которые будут находиться в массиве. Далее следует имя (идентификатор) массива. За ним следуют открытые квадратные и закрытые квадратные скобки. Далее оператор присваивания. Следующий блок разделен фигурными скобками. Внутри него находятся данные массива. Все данные должны быть одного типа. Данные разделяются запятыми. После последнего элемента данных запятая не нужна. Эта последняя запятая на самом деле необязательна. Все данные хранятся в объекте в области памяти, вместе с другими объектами образуя последовательный набор данных одного типа.

Данные в массиве содержат значения. Например, массив целых чисел может быть массивом оценок учащихся в тесте. Название массива должно быть связано со значением данных. Ниже приведен пример создания массива оценок для 10 учащихся.

int marks[] = {43, 29, 35, 50, 60, 65, 78, 56, 67, 90};

Массивы значений с float, _Bools и char

Ниже приведен пример создания массива с float:

float arrFlt[] = {12.56, 0.258, 5.4, 456.01};

Число элементов в массиве с float равно 4. Для компилятора gcc каждый из этих элементов с плавающей точкой занимает четыре байта (32 бита). Объект типа int также занимает четыре байта (в gcc).

Ниже приведен пример создания массива _Bool:

_Bool arrB[] = {1, 0, 0, 1, 0, 1};

Пример создания массива символов:

char arrChar[] = {'A', 'a', 'C', 'e', 'F', 'Y'};

Обратите внимание, что каждое значение char в массиве заключено в одинарные кавычки.

Объявление массива

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

Type arrayName[size];

Он начинается с типа, имени массива и затем квадратных скобок, внутри которых указано положительное целое число, указывающее на размер массива. Чтобы определить массив int, размер которого (количество элементов) будет равен 15, используем следующий код:

int myArr[15];

Определение означает наличие идентификатора и типа, а также выделение памяти. Без фактических элементов, назначенных массиву myArr, 15 в квадратных скобках все равно выделяют пространство для 15 целых чисел: это 15 X 4 байта для общего количества байт, поскольку одно целое число занимает 4 байта. Каждое из этих 15 местоположений может иметь или не иметь значение по умолчанию для integer, равное 0 (в зависимости от компилятора). Объявление означает наличие идентификатора и типа, с выделенной памятью или без нее. Другими словами, определение - это объявление, но объявление не обязательно является определением.

Позиция (индекс)

Элементы в массиве имеют свои позиции. Рассмотрим следующий массив:

int marks[] = {43, 29, 35, 50, 60, 65, 78, 56, 67, 90};

Первый элемент в массиве равен 43; второй - 29; третий - 35 и так далее. Значения в массиве имеют позиции. Эти позиции называются индексами (index). Подсчет индекса в вычислениях и массивах начинается с нуля, а не с единицы. Таким образом, индекс 43, указанный выше, равен нулю; индекс 29 равен 1; индекс 35 равен 2; и так далее.

Доступ к элементу массива

Чтобы получить доступ к значению в массиве, необходимо знать индекс. Синтаксис для доступа к элементу массива (значению) после определения или инициализации массива следующий:

arrayName[index];

Если требуется получить доступ к первому элементу массива, введите:

marks[0];

Чтобы получить доступ к третьему элементу, введите:

marks[2];

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

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

После объявления массива становится известен его размер. Кроме того, после инициализации массива размер массива остается неизменным. После объявления массива без инициализации массив становится пустым. Однако после инициализации массива значениями, отличными от значений по умолчанию (практическими значениями), массив не является пустым. В любом случае, значение элемента массива может быть присвоено или изменено следующим образом:

arrayName[index] = value;

Предположим, что требуется значение 47 для массива int с индексом 5. Чтобы присвоить или изменить значение с индексом 5, введите:

marks[5] = 47;

Не забудьте поставить точку с запятой в конце выражения. Помните, что индекс 5 в означает позицию (порядковый номер) 6.

Пример

В следующем примере определен массив int. Этому массиву присваиваются (инициализируются) пять целых чисел, которые затем отображаются. Отображение выполняется с помощью цикла for.

#include <stdio.h>

int main(int argc, char *argv[])
{
    int myIntArr[5];

    myIntArr[0] = 8;
    myIntArr[1] = 63;
    myIntArr[2] = 55;
    myIntArr[3] = 78;
    myIntArr[4] = 2;

    for (int i = 0; i < 5; i++) {
        printf("%i ", myIntArr[i]);
    }
    printf("\n");

    return 0;
}

Результат следующий: 8 63 55 78 2. Массив все еще может быть определен с помощью initializer_list и числа в квадратных скобках следующим образом:

int marks[10] = {43, 29, 35, 50, 60, 65, 78, 56, 67, 90};

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

Нужно знать размер массива

Размер массива означает количество элементов в массиве. Программист, определяющий массив, должен знать размер массива при его определении. Однако, если массив был разработан другим программистом, и текущий программист не знает размер, то текущий программист все равно может определить размер. Это делается с помощью оператора sizeof. Если аргументом оператора sizeof является идентификатор массива, то оператор sizeof вернет общее количество байт в массиве. Это число делится на размер в байтах каждого элемента массива (все элементы массива имеют одинаковый размер в байтах), чтобы получить количество элементов в массиве. То есть:

numberOfElements = sizeof(arrayName) / sizeof(Type);

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

numberOfElements = sizeof(arrayName) / sizeof(arrayName[0]);

Помните, что подсчет индекса начинается с 0, а не с 1. Таким образом, индекс для первого элемента равен 0. Таким образом, когда известен тип каждого элемента, используется первая формула. Когда тип каждого элемента неизвестен, используется вторая формула. Следующая программа иллюстрирует расчет по второй формуле:

#include <stdio.h>

int main(int argc, char *argv[])
{
    int arrInt[] = {25, 20, 256, 5, 7};
    int numOfElems = sizeof(arrInt) / sizeof(arrInt[0]);
    printf("%i\n", numOfElems);

    return 0;
}

Результат равен 5. В массиве 5 целых чисел, каждое из которых занимает четыре байта. Таким образом, общее количество байтов в массиве равно 20 байтам. 20/4 = 5, количество элементов в массиве.

Имя массива в виде постоянного указателя

Рассмотрим следующий массив:

int arr[] = {000, 100, 200, 300, 400};

Имя массива arr на самом деле является идентификатором, который содержит адрес первого элемента массива. Следующее выражение возвращает первое значение массива:

*arr;

В случае с массивом оператор инкремента ++ ведет себя по-другому. Вместо добавления 1 он заменяет адрес указателя адресом следующего элемента в массиве. Однако имя массива является постоянным указателем, что означает, что его содержимое (адрес указанного объекта) не может быть изменено или увеличено. Таким образом, для увеличения начальный адрес массива должен быть присвоен непостоянному указателю следующим образом:

int *ptr = arr;

Теперь значение ptr можно увеличивать, чтобы оно указывало на следующий элемент массива. Значение ptr было объявлено здесь как объект-указатель. Без * здесь это был бы не указатель; это был бы идентификатор для хранения объекта int, а не для хранения адреса памяти (для указанного объекта).

Следующий фрагмент кода, в последней итерации, указывает на четвертый элемент:

++ptr;
++ptr;
++ptr;

А данным кодом мы выводим четвертое значение массива:

#include <stdio.h>

int main(int argc, char *argv[])
{
    int arr[] = {000, 100, 200, 300, 400};
    int *ptr = arr;

    ++ptr;
    ++ptr;
    ++ptr;

    printf("%i\n", *ptr);

    return 0;
}

Результат равен 300. Обратите внимание на использование оператора косвенного обращения * в объявлении указателя и инструкции printf(). Это два разных варианта использования оператора косвенного обращения.

Добавление целого числа к указателю

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

#include <stdio.h>

int main(int argc, char *argv[])
{
    int arr[] = {000, 100, 200, 300, 400};
    int *ptr = arr;

    ptr = ptr + 3;

    printf("%i\n", *ptr);

    return 0;
}

Результат по-прежнему равен 300, как и ожидалось.

Неизменяемое содержимое массива

Рассмотрим следующий фрагмент кода:

 float arr[] = {0.0, 1.1, 2.2, 3.3, 4.4};
 arr[2] = 2.5; 

Массив объявляется обычным способом для первого оператора, а значение с индексом 2 изменяется во втором операторе. Имя массива, arr - это постоянный указатель, означающий, что содержащийся в нем адрес, который указывает на первый элемент массива, не может быть изменен. Это не означает, что значения элементов массива не могут быть изменены. На самом деле значение элемента с индексом 2 было изменено.

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

 const float arr[] = {0.0, 1.1, 2.2, 3.3, 4.4}; 
arr[2] = 2.5; 

Комментарии

Для того чтобы оставить свое мнение, необходимо зарегистрироваться на сайте