fl
МИКРОКОНТРОЛЛЕРЫ
fl
Если определение функции (definition) по природе своей
может быть только одно (в языке С не может быть
двух
разных функций с
одним и тем же
именем), то объявле-
ний (declaration) функции может быть в программе сколь-
ко угодно, лишь бы они не противоречили друг другу.
Именно объявлениями стандартных функций библиоте-
ки языка С буквально нашпигованы те файлы *.h, кото-
рые включаются в программу препроцессорными дирек-
тивами #include, и которые поэтому позволяют нам
пользоваться ими в своих программах. Если в начале про-
граммы заранее объявить все функции (declaration), име-
ющиеся в программе, после этого не будет иметь реши-
тельно никакого значения, в каком порядке они опреде-
лены в программе (definition). Это - альтернативный (и,
честно говоря, бопее правильный) способ решения про-
блемы, про которую мы говорили, комментируя преды-
дущий участок программы (описание вызываемых функ-
ций перед вызывающими). Что касается слова typedef,
то это - особая форма записи описаний в программе. Это
-
определение нового типа
данных. Если, к примеру, в
программе записана строка int array[10], это обозначает
определение массива из десяти целых чисел (размером
по 4 байта каждое), который называется array. Но если в
программе записана строчка typedef int array[10], то это
обозначает, что в программе появился новый
тип
дан-
ных, который называется array, и представляет из себя
массив из 10 целых чисел. Теперь мы можем чуть пони-
же этого объявления написать строку array X, и она для
компилятора будет обозначать то же самое, что и int Х[10]!
Т.е слово array теперь для компилятора - синоним “мас-
сива из 10 целых чисел”. Определение типов typedef -
очень удобная возможность: она позволяет значительно
упростить описание сложно устроенных переменных, осо-
бенно если их в программе много. В нашем случае мы
указали компилятору, что везде, где будет упомянут тип
exitProc, речь будет идти о функции, не возвращающей
никакого результата, и получающей однобайтовое целое
число без знака в качестве параметра.
Участок программы под номером <2> - это второй (а
также третий) способ образования новых типов данных.
Это -
структура
данных. Структура данных, в отличие от
массива, образуется из нескольких разнородных элемен-
тов (в нашем случае - три целых числа и один
указатель
на функцию, о котором мы подробнее скажем немного
позже). Для описания структуры данных используется
ключевое слово struct, за которым в фигурных скобках
следует перечисление всех ее элементов. Каждый эле-
мент структуры, как видите, имеет собственное имя для
того, чтобы отличить его от других элементов внутри
структуры. Обратите внимание на последний элемент
структуры - это
указатель
на функцию (мы ранее опре-
делили тип exitProc как функцию определенного типа).
Указатель - это третий способ образования новых типов.
Объявляется он так же, как обычный тип данных, но пе-
ред именем переменной ставится символ
Указатель
на функцию (в нашем случае) - это не сама функция, это
адрес ее в памяти программ! Если вызов обычной функ-
ции в ассемблере выполняется командой rcall имя_функ-
ции, то вызов функции по ее указателю выполняется ко-
мандой icaJI - косвенный вызов! Точно так же, если в про-
грамме объявлена переменная int *ref (указатель на це-
лое число), то работа с данными, на который он указыва-
ет, ведется не командами Ids, а командами Id с примене-
нием регистров X, Y или Z! Запомните: указатель на дан-
ные - это, фактически, их адрес в памяти программ или
памяти данных, поэтому размер переменных-указателей
всегда один и тот же, независимо от того, на какие типы
данных он указывает (его размер определяется шириной
адресной шины процессора). Обратите также внимание
на то, что внутри структуры можно употреблять не толь-
ко встроенные типы данных, но и типы, созданные ранее
программистом. Внутри структуры может быть объявлен
массив, элементы массива, в свою очередь, могут быть
структурами, а в них могут содержаться указатели - и
так до бесконечности, пока компилятору (или програм-
мисту) не снесет крышу © И последний штрих к описа-
нию: имя automatüne - это не имя переменной, а имя но-
вого типа данных, потому что перед его описанием рас-
положено ключевое слово typedef.
Участок программы под номером <3> - это многократ-
но описанная нами автоматная таблица. Видно, что это
массив данных из структур типа automatLine. В этом опи-
сании следует обратить внимание на три момента:
в описании массива в квадратных скобках
не задан его размер
при инициализации массива в общих фигурных
скобках есть вложенные фигурные скобки
для каждой строки таблицы
в описании строк таблицы использованы имена
функций без следующих за ними круглых скобок
Первое возможно потому, что при описании массива
мы одновременно указали и его инициализацию. В этом
случае компилятор сам посчитает, сколько элементов
массива было фактически проинициализировано, и имен-
но такого размера и создаст массив. Это - единственный
случай при программировании на языке С, когда размер
массива можно (автор бы даже сказал - нужно) не ука-
зывать. Вложенные скобки (второй момент) требуются по-
тому, что массив состоит не из встроенных типов дан-
ных, а из структур, имеющих собственное “устройство”.
Данные, указанные внутри вложенных скобок, заполня-
ют элементы структуры в том порядке, в котором они были
описаны в struct. Если бы внутри структуры был описан,
к примеру, массив, для его инициализации потребовалась
бы третья пара вложенных скобок. В принципе, некото-
рые компиляторы позволяют такие вложенные скобки не
указывать, но привыкать к этому не следует, потому что
это - отступление от стандарта языка. И, наконец, третье
- упоминание имени функции без следующих за ним круг-
лых скобок в языке С трактуется как
вычисление адреса
функции, что нам, собственно говоря, и нужно. Описате-
ля
static,
расположенного перед описанием автоматной
таблицы, мы пока касаться не будем - он будет разобран
в одной из следующих статей.
Продолжение в №1/2009
Радиолюбитель - I 2 /2 0 0 8 U
41
предыдущая страница 41 Радиолюбитель 2008-12 читать онлайн следующая страница 43 Радиолюбитель 2008-12 читать онлайн Домой Выключить/включить текст