Массивы

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

int a[5];
int numbers[5] = {1, 2, 3, 4, 5};
int vector[] = {1, 2};
int buffer[BUFFER_SIZE] = {0}; // c99
int arr[6] = { [4] = 29, [2] = 15 };
int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 }; // GNU extension
int whitespace[256]
= { [' '] = 1, ['\t'] = 1, ['\h'] = 1,
['\f'] = 1, ['\n'] = 1, ['\r'] = 1 };

Ниже приведено графическое представление массива a[5].

Индексация начинается с нуля, а обращение к i-й ячейке производится записью a[i]. Например, чтобы записать во вторую ячейку значение 35, нужно написать:

a[1] = 35;

По определению имя массива — это адрес его первого элемента, т.е. записи int *arr_prt = &a[0]; и int *arr_prt = a; эквивалентны, однако есть одна тонкость. Стоит помнить, что указатель — это переменная, а потому можно писать arr_ptr = a или arr_ptr++, а вот записи a = arr_ptr или a++недопустимы.

Так как работа происходит с указателем, запись a + 1 будет указывать на элемент, следующий за нулевым элементом массива, соответственно, можно перемещаться по памяти, используя адресную арифметику. Чтобы получить значение второго элемента массива, можно применить операцию разыменования *(a + 1). Такая запись будет эквивалентна a[1].

Более того, вы можете записать тоже самое по другому: 1[a].

Аналогичным образом можно создать двумерный массив.

#define LCD_WIDTH               128
#define LCD_HEIGH 48
uint8_t screen[LCD_WIDTH][LCD_HEIGHT];

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

Массивы указателей

Если необходимо хранить фиксированные строки (массивы символов) разной длины, лучше использовать массивы указателей.

static char cmd[][15] = { "AT+PWR", "AT+ATE=0", "AT+GSM_MODE=ON" };

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

static char *cmd = { "AT+PWR", "AT+ATE=0", "AT+GSM_MODE=ON" };

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


Изменено:

Язык Си: 3 комментария

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

  2. Термин «регистр ядра» довольно специфичен. Звучит не привычно. А почему не использовать термин CPU или процессор или на худой конец микроконтроллер?

  3. Смысл статических переменных вне функции мне кажется не раскрыт. Такой модификатор делает переменную недоступной из других единиц трансляции. Т.е. не будет конфликта имен между разными .с файлами.

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

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

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.