
В последнем примере определен и инициализирован двумерный массив w[3] [3], состоящий из трех трехэлементных строк. Списки, выделенные в фигурные скобки, соответствуют строкам массива и используются для инициализации (присваивания начальных значений) элементов массива.
В случае отсутствия скобок инициализация будет выполнена неправильно.
В языке программирования С-51 можно использовать сечения массива, как и в других языках высокого уровня. Сечение массива - это массив меньшей размерности. Однако на использование сечений накладывается ряд ограничений. Сечения формируются вследствие опускания одной или нескольких пар квадратных скобок. Пары квадратных скобок можно отбрасывать только справа налево и строго последовательно. Сечения массивов используются при организации вычислительного процесса в подпрограммах-функциях, разрабатываемых пользователем.
Примеры:
int s[2][3];
Если при обращении к некоторой функции написать s [0], то будет передаваться нулевая строка массива s.
int b[2][3][4];
При обращении к массиву b можно написать, например, b[1] [2], и будет передаваться вектор из четырех элементов, а обращение b[1] даст двухмерный массив размером 3 на 4. Нельзя написать b[2] [4], подразумевая, что передаваться будет вектор, потому что это не соответствует ограничению, наложенному на использование сечений массива.
Для работы с литеральными строками в языке программирования С используются массивы символов, например:
char str[] = "объявление символьного массива";
Следует учитывать, что размер символьного массива всегда на один элемент больше числа символов в строке, т. к. последний из элементов массива является управляющей последовательностью '\0', являющейся признаком конца строки. В примере использовано неявное задание длины массива символов. Это стало возможным, т. к. массиву сразу присваивается конкретное значение. При программировании микроконтроллеров семейства MCS-51 такое задание массива может привести к неоправданному расходу внутренней памяти данных, поэтому лучше воспользоваться размещением строки в памяти программ:
char code str[] = "объявление массива символов";
Структуры
Работа с массивами облегчает понимание и написание программы, когда для обозначения похожих элементов используется один идентификатор.
Однако в ряде случаев приходится обрабатывать разнородные элементы, описывающие один объект. В этом случае вместо массива используется структура.
Структура - это составной объект, в который входят элементы - называемые членами или полями - любых типов, за исключением функций, а также типа void или неполного типа. В отличие от массива, который является однородным объектом, структура может быть неоднородной.
В простейшем случае тип структуры определяется записью вида:
"struct" [Идентификатор] '{' Список описаний '}'
В структуре обязательно должно быть указано хотя бы одно поле. Определение Описание полей структур имеет следующий вид:
Тип данных Описатель';'
где Тип данных указывает тип поля структуры для объектов, определяемых в Описателях. В простейшей форме описатели представляют собой идентификаторы переменных или массивы.
Пример объявления структур:

Переменные tochka1, tochka2 объявляются как структуры, каждая из которых состоит из трех полей: tzvet, x и у. Переменная simv объявляется как двумерный массив, состоящий из 63 элементов, описывающих рисунок символа. Во втором объявлении каждая из двух переменных - date1, date2 - состоит из трех полей: year, moth, day.
Существует и другой способ объявления переменной структурного типа.
Этот способ основан на использовании заранее объявленного типа структуры. Объявление структурного типа аналогично объявлению перечислимого типа. Структурный тип объявляется следующим образом:
"struct" Тип '{' Список описаний '}';
где Тип - это идентификатор.
В приведенном ниже примере идентификатор student объявляется как тип структуры, список описаний полей которой приводится далее в фигурных скобках:
struct student
{char name[25]; //Имя и фамилия студента
int id; //Номер в журнале
int age; //Возраст
char usp; //успеваемость
};
Тип структуры используется для последующего объявления структур данного вида в форме:
struct Тип Список идентификаторов';'
Пример:
struct student st[23];
Поле структуры может быть указателем на структуру того же самого типа, в которой оно объявлено. Ниже рассматривается пример такой ссылки.
struct node { int data; struct node * next; } st1_node;
Доступ к отдельным полям структуры осуществляется с помощью указания имени структуры и следующего через точку имени поля, например:
st2.id=5; //Присвоить значение полю id структуры st2
st1.name="Иванов"; //Присвоить значение полю name структуры st1
st1_node.data=1985; //Присвоить значение полю data структуры st1
st[1].name="Иванов"; //Занести студента Иванова в журнал
st[1].id=2; //поместить его в журнал под вторым номером
st[1].age=23; //Занести в журнал его возраст
Битовые поля
Элементом структуры может быть битовое поле, обеспечивающее доступ к отдельным битам памяти. Вне структур битовые поля объявлять нельзя. Нельзя также организовывать массивы битовых полей и нельзя применять к полям операцию определения адреса. В общем случае тип структуры с битовым полем задается в следующем виде:
"struct" '{' "unsigned" Идентификатор1 ':' Длина поля1'
"unsigned" Идентификатор2 ':' Длина поля2' '}'
Длина поля задается целым выражением или константой. Эта константа определяет число битов, отведенное соответствующему полю. Поле нулевой длины обозначает выравнивание на границу следующего слова.
Пример:
struct { unsigned a1 : 1;
unsigned a2 : 2;
unsigned a3 : 5;
unsigned a4 : 2; } prim;
Структуры битовых полей могут содержать и знаковые компоненты. Такие компоненты автоматически размещаются на соответствующих границах слов, при этом некоторые биты слов могут оставаться неиспользованными.
Доступ к элементам полей битов выполняется точно так же, как и к компонентам обычных структур. Само же битовое поле рассматривается как целое число, максимальное значение которого определяется длиной поля. Например:
Cntr.Cmd=30;
Объединения (смеси)
Иногда один и тот же элемент данных удобно обрабатывать по-разному, в зависимости от ситуации. Например, кодовое слово помехоустойчивого кода можно передавать целиком и можно осуществлять запись информационных и проверочных битов различными процедурами. Еще один пример. Четыре соседних байта можно интерпретировать в один момент времени (для обработки) как число с плавающей запятой, и эти же четыре байта в другой момент времени интерпретировать (для передачи или приема) как четырехэлементный массив байтов.
Объявление объединения подобно структуре, однако в каждый момент времени может использоваться только один из элементов объединения.
Тип объединения объявляется в следующем виде:
"union" '{' Описание элемента1';'
…
Описание элементаn';' '}';
Для каждого из элементов объединения выделяется одна и та же область памяти, т. е. все элементы перекрываются. Хотя доступ к этой области памяти возможен с использованием любого из элементов, элемент для этой цели должен выбираться так, чтобы полученный результат не был бессмысленным.
Доступ к элементам объединения осуществляется тем же способом, что и к полям структур. Тип объединения может быть объявлен точно так же, как и тип структуры.
Объединение применяется для следующих целей:
- инициализации используемого объекта памяти, если в каждый момент времени только один объект из многих является активным;
- интерпретации основного представления объекта одного типа, как если бы этому объекту был присвоен другой тип.
Размер области памяти, выделяемой для переменной типа объединения, определяется наиболее длинным элементом объединения. Когда используется элемент меньшей длины, то переменная типа объединения может содержать неиспользуемую память. Все элементы объединения хранятся в одной и той же области памяти, начиная с одного и того же адреса.