Материал: lectures_3

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

спецификаторы класса памяти.

квалификаторы типа.

спецификаторы типа.

Спецификаторы класса памяти.

Имеются следующие спецификаторы класса памяти:

auto.

extern

regester

static

typedef

Класс памяти определяет время существования и вид связывания объявляемого имени. Ниже в таблице приводится назначение спецификаторов класса памяти приведено.

Спецификатор

Назначение

auto

Спецификатор допустим только в блоках и предназначен для

 

указания на то, что переменная является локальной

 

(автоматической). В программах обычно не используется в связи с

 

тем, что по умолчанию локальные переменные имеют класс памяти

 

auto.

extern

Этот спецификатор используется для указания на то, что

 

определяемое имя имеет внешнее связывание.

register

Спецификатор применяется при работе с локальными переменными

 

с той целью, чтобы рекомендовать компилятору хранить эту

 

переменную в регистре. Современные компиляторы часто

 

игнорируют эту спецификацию в связи с тем, что могут справиться

 

с оптимизацией использования регистров лучше программиста.

static

Этот спецификатор может появляться в объявлениях функций и

 

переменных. В объявлениях функций этот спецификатор указывает

 

на внутренное связывание. В объявлениях переменных назначение

 

спецификатора зависит от контекста, в котором встречается

 

объявление. В том случае, когда объявление находится вне

 

функций, то спецификатор указывает на внутреннее связывание.

 

Для локальных переменных определяет размещение переменной в

 

статической области оперативной памяти.

typedef

Определяет не имя функции или переменной, а имя типа. Имя типа

 

располагается на месте объявителя.

Квалификаторы типа

Классификаторы const и volatile были введены в язык Си стандартом C89. Классификатор restrict был добавлен в язык стандартом С99.

Квалификатора const следует использовать в объявлениях тех объектов, значения которых должны оставаться неизменными. Имя константного объекта не должно встречаться в левой части оператора присваивания.

Квалификатор volatile предполагает, что значение объекта может внезапно измениться. На практике переменная, привязанная к некоторому аппаратному регистру, должна быть объявлена с использование этого

71

квалификатора. Наличие рассматриваемого квалификатора обязывает компилятор отказаться от выполнения оптимизации.

Квалификатор restrict используется только с указателями и будет рассмотрен в разделе 38.

Спецификаторы типа

Любой объявляемый объект должен иметь тип, определяемый одним или несколькими спецификаторами типа. Спецификаторы типа могут иметь следующий вид:

последовательность спецификаторов встроенного (фундаментального) типа.

имя перечисления.

typedef-имя.

Использование спецификаторов

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

спецификаторы класса памяти, квалификаторы типа, спецификаторы типа.

спецификаторы класса памяти, спецификаторы типа,

квалификаторы.

Первый формат является традиционным, однако второй формат в последнее время все чаще используется.

35.2.Описатели

Основным элементом каждого описателя является объявляемое имя. Этот элемент является обязательным. Кроме того, в объявитель может входить дополнительная информация, относящаяся к типу. В состав дополнительных компонентов могут входить классификаторы типа и некоторые операторы языка Си:

* - оператор разыменования (для объявления указателей см. пункты 17 и

38).

() – оператор функция (для объявления функций см. пункт 37).

[] – оператор индексирования (для объявления массивов см. пункт 39). Оператор * в объявителе используется (по отношению к объявляемому

имени) в качестве префикса, а операторы () и [] – в качестве суффикса. Можно провести некоторую аналогию между использованием операторов в объявителях и выражениях. Суффиксные операторы «сильнее» связаны с именем, чем префиксные.

Приведем примеры объявлений, В комментариях использованы следующие сокращения: ПС – послеовательность спецификаций, СО – список объявителей.

72

int n, m;

//ПС – спецификатор типа int, СО – два идентификатора перемен

//ных: n и m

double *px;

//ПС – спецификатор типа double, СО – идентификатор переменной

//px и префиксный оператор разыменования *

35.3.Использование зарезервированного слова

typedef для объявления синонимов типов

Отметим, что typedef не позволяет объявлять новые типы. Его назначение состоит в том, чтобы назначать имя для уже существующего типа. В зависимости от вида существующего типа целесообразно различать три случая:

встроенный (фундаментальный) тип.

перечисление и структура.

все прочие типы; их характерной особенностью является отсутствие у типа имени.

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

Для перечислений и структур применение typedef позволяет устранить из имени типа зарезервированное слово. Для перечислений таким именем является enum, а для структур – struct.

Для всех оставшихся случаев применение рассматриваемого способа позволяет упростить структуру новых объявлений.

Приведем ряд примеров.

Пример 1. Синоним для встроенного типа. Рассмотрим некоторый фрагмент кода, в котором будет объявлен синоним (integer) для встроенного типа int.

typedef int integer;

После объявления этого синонима у программиста появляется альтернатива, существо которой состоит в том, что наряду с обычным

именем типа int, он имеет возможность пользоваться новым именем. int n;

integer m;

Бессистемное использование этих двух альтернативных возможностей пользы не приносит. Смысл в объявлении синонима в том случае, когда программист откажется от стандартного имени int, и будет использовать альтернативное integer.

integer n, m;

При этом появляется возможность его оперативного изменения. Например, если окажется, что тип int следовало бы заменить другим типом.

73

Например, типом double int. такая замена может быть осуществлена

редактированием объявления имени integer. typedef double int integer;

integer n, m;

Теперь переменные n и m имеют тип double int.

Пример 2. Синоним для типа, у которого нет своего имени. Обратимся к программному коду, приведенному ниже. В этом коде объявлен синоним ptr_dbl для существующего типа double*. Теперь программист имеет альтернативные возможности для объявления указателей на объекты типа

double. Это и продемонстрировано в приведенном ниже коде. typedef double* ptr_dbl;

double *pb1; ptr_dbl pb2;

36. Функции

36.1.Понятие об абстракции и инкапсуляции

Известно, что сложность программирования обусловлена в первую очередь сложностью решаемых задач. Основным способом преодоления этих сложностей является применение декомпозиции. Декомпозиция сводится к тому, что исходная задача заменяется совокупностью подзадач, совместное решение которых приводит к искомому решению. Однако не любая декомпозиция заканчивается успешно. Типичной является следующая ситуация. Программные компоненты, реализующие решение отдельных подзадач работают корректно, а их объединение не работает. Классическим примером неудачной декомпозиции является попытка написать текст пьесы, распределив работу между отдельными исполнителями, следующим образом. Определяется состав действующих лиц. Затем каждому исполнителю указывается список действующих лиц пьесы и поручается написать часть текста пьесы, в которой они участвуют. Представляется, что результат будет самый плачевный.

Существует мнение, что качество декомпозиции может быть повышено в том случае, когда при ее выполнении применяется абстракция.

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

74

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

В языке Си имеется развитый аппарат подпрограмм, которые называются функциями.

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

При использовании функций важно получить ответ на следующие вопросы:

1.Какова роль функций в программировании?

2.Какие разновидности функций имеются в языке Си?

3.Чем отличается понятие функции языка Си от понятия функции, принятого в математике?

4.В чем состоят преимущества и недостатки применения функций при программировании на языке Си?

5.Как оценить качество разработанной функции?

6.Как организованы функции языка Си?

7.Из каких структурных частей состоит функция языка Си?

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

36.2.Функция языка Си и процедурная абстракция

Как отмечалось ранее, применение абстракции позволяет повысить качество декомпозиции. Язык Си позволяет реализовать один из видов абстракции, который принято называть процедурной абстракцией. Такой вид абстракции основан на применении подпрограмм. В процедурной абстракции используется способ, называемый абстрагированием через параметризацию.

75

Источник: https://studfile.net/preview/16544272/