русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Условная компиляция


Дата добавления: 2013-12-23; просмотров: 1265; Нарушение авторских прав


Включение текстов из файлов

Макроподстановки

Макрос – это средство замены одной последовательности символов другой (замена в тексте простейшая форма макроса).

Большими возможностями обладают макроопределения с параметрами.

Формат макроподстановки с параметрами:

#define <идентификатор>(<список_параметров>) <текст>

Примеры:

#define max(a, b) a<b?b:a

Вхождение в программу max(x, 10) заменяется на x<10?10:x

#define abs(x) x>=0?x:-x

Вхождение в программу abs(a) заменяется на a>=0?a:-a

Отличие макросов от функций

1. Функции имеют код (за исключением inline-функций) в одном экземпляре, а коды макроса вставляются в программу столько раз, сколько используется макрос, причем подстановка для макроса осуществляется всегда.

2. Функции работают с определенными типами параметров, макрос пригоден для обработки параметров любого типа, допустимых в выражении строки замещения.

Механизм перегрузки и шаблоны функций в Си++ позволяют решать те же задачи.

Ниже представлен пример с использованием макросов. В примере вместо скобок { } используются слова begin/BEGIN и end/END, как в зыке Паскаль, на самом деле в тексте эти слова заменяются на соответствующие скобки. Также представлен пример макроса с параметрами.

#include <stdio.h>

#define begin {

#define end }

#define BEGIN {

#define END }

#define max(a, b) a>b?a:b

int main(int argc, char* argv[])

{

int A[10];

int i;

int x=10, y=5, z;

for(i=0; i<10; i++) begin

A[i]=i*i;

printf("%d ", A[i]);

end

z=max(x, y); // z=x>y?x:y;

printf("z=%d", z);

return 0;

}

 

Директива выполняет простое действие: вставляет текст из одного файла в другой файл в заданном месте. Формат директивы:



#include “(путь_к_файлу)_имя_файла”

#include <(путь_к_файлу)_имя_файла>

Когда используются символы “” файл в первую очередь ищется в текущем каталоге, а затем в системных, в которые установлена среда разработки, а когда <>, то файл ищется в первую очередь в системных каталогах, а затем в текущем. Чаще всего используются включения заголовочных файлов, содержащих заголовки функций и другие общие объявления.

 

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

Первая форма:

#if <целочисленное_выражение1>

[<текст>]

[#elif < целочисленное_выражение2>

<текст>]

[#elif < целочисленное_выражение3>

<текст>]

…..

[#else

<текст>]

#endif

Целочисленное выражение не должно содержать операцию sizeof, приведение типов и константы, определенные через enum. Директива работает так, если целочисленное выражение после #if истинно (отлично от 0), то на компиляцию включается текст после #if, остальные тексты после #elif и #else на компиляцию не попадают. Если после #if выражение ложно (равно 0), то последовательно проверяются выражения после #elif, когда находится выражение истинное (отличное от 0), то на компиляцию попадает один фрагмент после этого #elif. Если не одно #elif не сработало, все целочисленные выражения ложные, то на компиляцию поступает текст после #else до #endif (если директива #else есть).

Ниже представлен пример, в котором на печать выводится else, фрагменты исходного текста, которые не поступают на компиляцию, набраны с синтаксическими ошибками.

#include <stdio.h>

#define _M 0

int main(int argc, char* argv[])

{

#if _M

pr3464572intf("1");

#elif 0

prin4363tf("2");

#elif 0

pri35252ntf("3");

#else

printf("else");

#endif

return 0;

}

Вторая форма:

#ifdef <идентификатор>

[<текст>]

[#elif < целочисленное_выражение2>

<текст>]

[#elif < целочисленное_выражение3>

<текст>]

…..

[#else

<текст>]

#endif

В этой форме первое условие считается истинным, если идентификатор после #ifdef до этого объявлен, как препроцессорный в директиве #define, в этом случае на компиляцию поступает текст после #ifdef, если идентификатор до этого не объявлен, как препроцессорный, то далее условия проверяются, как в первой форме.

Третья форма:

#ifndef <идентификатор>

[<текст>]

[#elif < целочисленное_выражение2>

<текст>]

[#elif < целочисленное_выражение3>

<текст>]

…..

[#else

<текст>]

#endif

В отличие от второй формы первое условие считается истинным, если идентификатор после #ifndef до этого не объявлен, как препроцессорный в директиве #define, а ложном в том случае, если идентификатор объявлен, как препроцессорный, в этом случае далее условия проверяются, как в первой форме.

Вместо директив #ifdef и #ifndef можно использовать более старые формы:

#if defined(<идентификатор>)

#if !defined(<идентификатор>)

defined(<идентификатор>) – может использоваться в качестве ограниченного константного выражения, например, после #elif .

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

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

#include <stdio.h>

#define Pechat

 

int main(int argc, char* argv[])

{

int x=10;

int y=167;

#ifdef Pechat

printf("\nx=%d", x);

#endif

 

#ifdef Pechat

printf("\ny=%d", y);

#endif

printf("\nRez=%d", x+y);

return 0;

}

Также заголовочные файлы должны иметь защиту от повторного включения, например, все стандартные заголовочные файлы имеют защиту от повторного включения. Пример структуры файла stdio.h:

#ifndef _INC_STDIO

#define _INC_STDIO

……..

// Основное содержание файла

…….

#endif /* _INC_STDIO */

 



<== предыдущая лекция | следующая лекция ==>
Замены в тексте | Заранее определенные препроцессорные идентификаторы


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.005 сек.