Массивы

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

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.


Изменено:

Язык Си: 6 комментариев

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

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

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

  4. #ifdef STM8
    ind.i = 250;
    #elif STM32
    ind.j = 1027;

    Точно #elif ? Что-то мне подсказывает, что здесь должно быть либо #else #ifdef STM32, либо просто #ifdef STM32

  5. «printf(«a\t: 10\n\r»);
    printf(«ab\t: 11\n\r»);
    printf(«abc\t: 12\n\r»);
    // a___: 10
    // ab__: 10
    // abc_: 10″

    Не понял, почему 10 в выводе в каждой строке?

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

    float pi = 3.1415926;
    printf(«%.0f\n\r», pi); // 3
    printf(«%.1f\n\r», pi); // 3.1
    printf(«%.2f\n\r», pi); // 3.14
    printf(«%.3f\n\r», pi); // 3.142
    printf(«%.4f\n\r», pi); // 3.1416″

    В то же время:
    «printf(«%.1f\n\r», pi); // 3.1
    printf(«%.2f\n\r», pi); // 3.14″

    Насколько я вижу, округление происходит по математическим правилам, в том числе при округлении пятерки. Где ошибка: в примере или в описании?

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

Ваш адрес email не будет опубликован.