Модификатор volatile

Ключевое слово volatile указывает на то, что данная переменная в любой момент может быть изменена в результате выполнения внешних действий, не контролируемых программой. Например, следующая строка описывает переменную event_time, значение которой может измениться без ведома программы:

volatile int event_time;

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

Одновременное использование const и volatile

Допускается одновременное употребление ключевых слов const и volatile при объявлении переменных. Так, в следующей строке создается переменная, обновляемая извне, но значение которой не может быть изменено самой программой:

const volatile constant_event_time;

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

42. Модификаторы pascal, cdecl, near, far и huge. Модификатор pascal. Модификатор cdecl. Модификаторы near, far и huge.

Первые два модификатора, pascal и cdecl, чаще всего используется в сложных приложениях. Microsoft Visual C/C++ позволяет создавать программы, которые с легкостью могут вызывать процедуры, написанные на разных языках. Также возможна связь и в обратном направлении. Например, можно написать программу на Паскале, вызывающую процедуру C++. При подобном смешении языков необходимо учитывать два момента: имена идентификаторов и способ передачи параметров.

Когда Microsoft Visual C/C++ компилирует программу, все глобальные идентификаторы программы (функции и переменные) помещаются в выходной файл с объектным кодом для последующей компоновки. По умолчанию компилятор сохраняет эти идентификаторы, используя те же буквы, которые использовались в описаниях (заглавные, строчные или и те, и другие). Кроме этого, в начале идентификатора добавляется символ подчеркивания (_). Так как встроенный компоновщик Microsoft Visual C/C++ различает (по умолчанию) заглавные и строчные буквы, предполагается, что все внешние идентификаторы, объявленные в программе, сохраняют символ подчеркивания и тот вид, который они имели при объявлении (название и регистр букв).

Pascal

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

Cdecl

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

N ear, F ar, H uge

Эти модификаторы оказывают воздействие на работу с адресами объектов.

Указатель типа near — 16-битовый

Указатель типа far — 32-битовый

Указатель типа huge — 32-битовый

—операции отношения ==, !=, <, >, <=, >= выполняются корректно и предсказуемо над указателями типа huge, но не над указателями типа far;

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

В СП MSC модификатор huge применяется только к массивам, размер которых превышает 64 К. В СП ТС недопустимы массивы больше 64 К, а модификатор huge применяется к функциям и указателям для спецификации того, что адрес функции или указуемого объекта имеет тип huge.

Для вызова функции типа near используются машинные инструкции ближнего вызова, для типов far и huge — дальнего.

43. Тип данных char Другие типы и размеры данных. Преобразование типов данных. Явные преобразования типов при помощи операции приведения типа.

Тип данных char

Этот тип определяет целые числа без знака в диапазоне от 0 до 255. Обычно такое целое размещается в одном байте памяти.

char response;

char intable, latan;

char isma = 'S';

Преобразование типов данных.

Предположим, что выполняется следующая операция, в которой переменные fresult и fvalue имеют тип float, а переменная ivalue — тип int:

fresult = fvalue * ivalue;

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

Давайте посмотрим, что происходит при преобразовании типа float в тип int. Предположим, что описаны переменные ivalue1 и ivalue2 типа int и переменные fvalue и fresult типа float. Рассмотрим следующую последовательность операторов:

Ivalue1 = 3;

ivalue2 = 4;

fvalue = 7.0;

fresult = fvalue + ivalue1/ivalue2;

Операция ivalue1/ivalue2 — не смешанная; она представляет собой деление двух целых чисел, и ее результат 0, так как при выполнении целочисленного деления дробная часть (в этом примере 0.75) отбрасывается. Поэтому значение fresult равно 7.0.

Что будет, если переменную ivalue2 описать как float? В этом случае переменная fresult получит значение с плавающей точкой 7.75, поскольку операция ivalue1/ivalue2 будет иметь смешанный тип. Тогда значение ivalue1 временно преобразуется в число с плавающей точкой 3.0 и результат деления будет равен 0.75. После сложения с fvalue получим 7.75.