Модификатор 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.