04_Использование_языков_высокого_уровня_Информ_материал_СПО_ч4 (1268620), страница 4
Текст из файла (страница 4)
Операции,применимые к структурам, годятся и для объединений.Объединения часто используются тогда, нужно выполнить специфическоепреобразование типов, потому что хранящиеся в объединениях данные можно обозначатьсовершенно разными способами. Например, используя объединения, можноманипулировать байтами, составляющими значение float, чтобы выполнять какое-либонеобычное округление.Как определяется объединение?union тег {тип имя_элемента;…………………..тип имя_элемента;};Например:union u_fc {float f;char ch[4];};typedef union { u32 U32; s32 S32;u16 U16[2]; s16 S16[2]; u8 U8[4];s8 S8[4]; } UU32;Инициализировать объединения можно только значением, имеющим тип его первогоэлемента. Например:union u_fc fc = {123.5};Как осуществляется доступ к элементам (членам, полям) объединения?Синтаксис доступа к элементам объединения в точности такой же, как в структурах:имя_объединения_переменной.имя_элемента_объединенияилиуказатель_на_объединение->имя_элемента_объединения4.2.11.
Битовые поляБитовое поле может быть членом структуры или объединения.Общий вид определения битового поля:тип имя:ширина; // тип – знаковое или беззнаковое целое;// ширина — длина десятичного словаДля обращения к полям используются те же конструкции, что и для обращения кобычным элементам структуры. Поля могут не иметь имени. С помощью этогоорганизуется пропуск необходимого количества разрядов.
Особая ширина, равная нулю,используется в случае, когда требуется выйти на границу следующего слова. Размещениеполей может быть слева направо и наоборот.Примеры:struct t_flags{ u16 fg1:1; u16 fg2:1; u16 fg3:3;u16 :2; u16 fg4:1; } flags;flags.fg1 = flags.fg2:1;Поля ведут себя как малые целые и могут участвовать в арифметических операциях. Поляне имеют адресов и не могут быть массивами, поэтому указывать на них нельзя.4.2.12.
ФункцииИспользование функций является фактически единственным способом справиться спотенциальной сложностью больших программ. Определения всех функций имеютодинаковый вид:тип имя_функции(список_формальных_параметров){ описания// Телооператоры// функции}Тип — тип возвращаемого функцией значения (в том числе void); функция можетвозвращать любой тип данных, за исключением массивов;имя_функции — идентификатор;список_формальных_параметров — это список элементов вида: тип имя_параметра,которые отделяются друг от друга запятыми.Функция может быть и без параметров, тогда ее список будет пустым. Такой пустойсписок можно указать в явном виде, поместив для этого внутри скобок ключевое словоvoid.
В Си функцию нельзя определять функцию внутри другой функции.Тело функции — это всегда блок или составной оператор, т.е. последовательностьописаний и операторов, заключенная в фигурные скобки. Важный оператор тела функции— оператор возврата в точку вызова:return выражение;илиreturn; // может отсутствоватьФункция не обязана возвращать какое-либо значение; оператор RETURN, не содержащийникакого выражения, приводит к такой же передаче управления, как «сваливание наконец» функции при достижении конечной правой фигурной скобки, но при этом ввызывающую функцию не возвращается никакого значения.Вызов функции:имя_функции(список_фактических_параметров)Согласование по типам между формальными и фактическими параметрами требует, чтобыв модуле-файле до первого вызова функции было помещено либо ее определение, либо ееописание (прототип), содержащее информацию о типе возвращаемого результата и отипах всех параметров.
Наличие такого прототипа позволяет компиляторуконтролировать соответствия типов параметров. Прототип (описание) функции можетвнешне почти полностью совпадать с заголовком ее определения:тип имя_функции(список_формальных_параметров); // достаточно// указать лишь типы параметровОсновное различие – точка с запятой в конце описания (прототипа). Второе отличие –необязательность имен формальных параметров в прототипе даже тогда, когда они есть взаголовке определения функции. В языке «С» все аргументы функций передаются «позначению». Это означает, что вызванная функция получает значения своих аргументов спомощью временных переменных, а не их адреса. Поэтому вызванная функция не можетизменить переменную из вызывающей функции; она может менять только своюсобственную временную копию. Если тип функции – void, то ее вызов: f(); при этомнеобязательно использовать возвращающий тип, возвращаемое значение.Указатели и аргументы функции:Можно организовать указатель на функцию.
Например:int (*p)(char); // возвращает указатель на тип int4.2.13. Класс хранения: область действия и время жизниОбластью видимости имени считается часть программы, в которой это имя можноиспользовать.Временем жизни объекта данных называется отрезок времени, в течение которогозначение этого объекта доступно для использования в некоторой части программы. Времяжизни объекта может быть столь коротким, как время исполнения операторов блока, илистоль же длинным, как время исполнения всей программы.В языке Си предусмотрены пять классов хранения: автоматический; регистровый; внутренний статический; внешний; внешний статический.Программа на Си обычно оперирует с множеством внешних объектов: переменных ифункций.
Прилагательное «внешний» противоположно прилагательному «внутренний»,которое относится к аргументам и переменным, определяемым внутри функций. Внешниепеременные определяются вне функций и потенциально доступны для многих функций.Сами функции всегда являются внешними объектами, поскольку в Си запрещеноопределять функции внутри других функций.Внутренние объекты (переменные)Автоматические переменныеКласс хранения таких объектов, как аргументы функций, называется автоматическим auto(другие названия – локальный, рабочий). Такое название означает, что область памяти дляхранения этих элементов данных выделяется автоматически при вызове функции и такжеавтоматически освобождается, когда выполнение этой функции завершается.
Областьдействия аргументов ограничена текущей функцией. Кроме того, автоматическиепеременные могут быть определены внутри любого блока операторов языка Си.Регистровые переменныеСлужебное слово register указывает компилятору, что надо попытаться хранитьсоответствующий объект (например, счетчик) в быстродействующих машинныхрегистрах, если это возможно.Идея состоит в том, чтобы переменные, объявленные register, разместить на регистрахмашины, благодаря чему программа, возможно, станет более короткой и быстрой. Однакокомпилятор имеет право игнорировать это указание. Данное объявление можетприменяться только к автоматическим переменным и к формальным параметрам функции.Внутренние статические переменныеОбъявление static можно использовать и для внутренних переменных. В отличие отавтоматических переменных они не возникают только на период работы функции, асуществуют постоянно.
Это значит, что внутренние статические переменныеобеспечивают постоянное сохранение данных внутри функции.Внутренние статические объекты имеют ту же область действия, что и автоматическиеобъекты. Однако временем жизни внутренних статических объектов является времяисполнения всей программы.Для следующего заголовка функции { static int x = 0 } справедливо, что когдафункция заканчивает работу, то значение переменой сохраняется (для обработкипрерываний).Внешние и внешние статические объекты (переменные)Внешние переменныеПоскольку внешние переменные доступны всюду, их можно использовать в качествесвязующих данных между функциями как альтернативу связей через аргументы ивозвращаемые значения.
Для любой функции внешняя переменная доступна по ее имени,если это имя было должным образом объявлено.Внешние переменные существуют постоянно, так что их значения сохраняются и междуобращениями к функциям. Таким образом, если двум функциям приходится пользоватьсяодними и теми же данными и ни одна из них не вызывает другую, то часто бываетудобнее оформить эти общие данные в виде внешних переменных, а не передавать их вфункцию и обратно через аргументы.Область действия внешней переменной или функции простирается отточки программы,где она объявлена, до конца файла, подлежащего компиляции. Однако если на внешнююпеременную нужно сослаться до того, как она определена, или если она определена вдругом файле, то ее объявление должно начинаться словом extern.
Важно отличатьобъявление внешней переменной от ее определения.Внешние статические объектыУказание static, примененное к внешней переменной или функции, ограничивает областьсоответствующего объекта концом файла. Это способ скрыть имена. Указание static чащевсего используется для переменных, но с равным успехом его можно применять и кфункциям. Обычно имена функций глобальны и видимы из любого места программы.Если же функция помечена словом static, то ее имя становится невидимым вне файла, вкотором она определена.Таблица 4.5. Характеристики классов храненияКлассхраненияОбластьдействияВремяжизниВнешнийВнешнийстатическийАргументыфункцииАвтоматическийРегистровыйВнутреннийстатическийПрограммаМодульФункцияБлокБлокБлокПрограммаПрограммаФункцияБлокБлокПрограмма4.3. Расширения языка Сх514.3.1.