68964

Препроцесор та коментарії

Лекция

Информатика, кибернетика и программирование

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

Украинкский

2014-09-28

48.5 KB

0 чел.

Лекція № 9

Тема: Препроцесор та коментарії

План

  1.  Директиви препроцесора
  2.  Коментарії

Директиви препроцесора

Директиви препроцесора це інструкції препроцесору С. Предпроцесор C це текстовий процесор, який маніпулює текстом початкового файлу на першій фазі компіляції. Хоча компілятор викликає препроцесор на своїй першій стадії, його можна викликати і окремо для обробки тексту без компіляції.

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

Препроцесор З розпізнає наступні директиви:

          #define        #if            #line   

          #elif          #ifdef         #undef   

          #else          #ifndef   

          #endif         #include   

Знак номера (#) повинен бути першим нерозділовим символом на рядку, що містить директиву, між символом номера і першою буквою директиви можуть з'являтися розділові символи. Деякі директиви містять аргументи або значення. Будь-який текст, який слідує за директивою (окрім аргументу або значення, який є частиною директиви) повинен бути поміщений в дужки коментаря (/* */).

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

Директива #define зазвичай використовується для організації зв'язку змістовних ідентифікаторів з константами, ключовими словами і часто використовуваними операторами і виразами. Представляючі константи ідентифікатори називаються "Оголошеними константами". Представляючі оператори або вирази константи називаються "макросами".

Після визначення ідентифікатора його не можна перевизначити для іншого значення, якщо не видалити первинне визначення. Проте, можна перевизначити ідентифікатор тим же самим визначенням. Отже, одне визначення може з'явитися в програмі кілька разів.

Директива #undef видаляє визначення ідентифікатора. Після видалення визначення ідентифікатор можна перевизначити іншим значенням. Директиви #define і #undef розглядаються відповідно в Розділах 8.2.2 і 8.2.3.

Практично можна виділити два типи макросів. "Об'єктні" макроси не приймають аргументів, а "функціональні" визначені таким чином, що приймають аргументи, і виглядають і діють подібно до викликів функцій. Макроси не генерують дійсні виклики функцій, тому програма працюватиме швидше, якщо замінити виклики функцій макросами. Проте, макроси можуть створити свої проблеми, якщо не підійти до їх визначення і використання зі всією ретельністю. У визначенні макросів з аргументами можливо доведеться скористатися дужками для встановлення належного порядку проведення обчислень у виразах. Крім того, макроси можуть некоректно обробити вирази з побічними ефектами. Додаткову інформацію можна побачити в прикладах Розділу 8.2.2, "Директива #define".

Є три специфічні оператори препроцесора: один представлений знаком номера (#), інший подвоєним знаком номера (##), а третій словом defined. "Рядковий" оператор (#), який передує імені формального параметра макро, примушує препроцесор укласти відповідний дійсний аргумент в рядкові дужки цитат. Оператор "вставки лексем" (##) дозволяє здійснити злиття лексем, заданих як дійсні аргументи, у форму іншої лексеми. Ці два оператори використовуються в контексті директиви #define і описані в Розділах 8.2.2.1 і 8.2.2.2.

І, нарешті, оператора defined спрощує написання складених виразів в деяких директивах макро. Він використовується при умовній компіляції і тому розглянутий в Розділі 8.4.1 "Директиви #if, #elif, #else і #endif".

Директива #define

     

Синтаксис: #define ідентифікатор текст-замены   

                #define ідентифікатор(список-параметров)   

                    текст-замены

 

Директива #define замінює всі появи "ідентифікатор" в початковому файлі на "текст-замены". Ідентифікатор замінюється тільки тоді, коли він формує лексему. (Лексеми описані в розділі "Елементи мови З" і "Короткому огляді синтаксису".) Наприклад, ідентифікатор не буде замінений, якщо він з'являється в рядку або як частина довшого ідентифікатора.

Якщо після ідентифікатора слідує список параметрів, то директива #define замінить кожну появу ідентифікатор(список-параметров) на версію аргументу текст-замены в якій формальні параметри замінені на дійсні аргументи.

Аргумент "текст-замены" складається з ряду лексем, таких як ключові слова, константи або повні оператори. Один або декілька розділових символів повинні відокремлювати текст-замены від ідентифікатора (або від закриваючої дужки списку параметрів). Ці розділові символи не вважаються частиною тексту-заміни, також як і будь-які розділові символи, які слідують за останньою лексемою тексту. Текст, що займає більш за один рядок, може бути продовжений на наступному рядку, якщо до символу переходу на новий рядок помістити знак зворотного ділення (\).

Аргумент текст-замены може бути порожнім. Вибір цієї опції видаляє всі появи ідентифікатора з початкового файлу. Проте, ідентифікатор все ще вважається визначеним і дає значення 1 при його перевірці директивою #if (розглядається в Розділі 8.4.1).

#define stringer(x) printf(#x "\n")   

  

Умовна компіляція

Даний розділ описує синтаксис і використання директив, які управляють "умовною компіляцією". Ці директиви дозволяють подавити компіляцію частини початкового файлу, перевіряючи постійний вираз або ідентифікатор. Результат перевірки визначає, які блоки тексту будуть передані в компілятор і які блоки тексту будуть видалені з початкового файлу при препроцесорній обробці.

Директиви #if, #elif, #else і #endif

#if граничное-постоянное-вираз   

[блок-текста]   

[#elif граничное-постоянное-вираз   

  [блок-текста]   

[#elif граничное-постоянное-вираз   

  [блок-текста]   

[#else   

  [блок-текста]   

#endif   

Директива #if разом з директивами #elif, #else і #endif управляють компіляцією частини початкового файлу. Кожна директива #if в початковому файлі повинна мати відповідну закриваючу директиву #endif. Між директивами #if і #endif може з'явитися будь-яке число директив #elif, але допускається наявність тільки однієї директиви #else. Якщо є директива #else, то вона повинна бути останньою директивою перед #endif.

Препроцесор вибирає одну із заданих появ блоку тексту для подальшої обробки. Цей блок може бути будь-якою послідовністю тексту. Він може займати декілька рядків. Зазвичай блок тексту це текст програми, який має значення для компілятора або препроцесора.

Препроцесор обробляє вибраний блок тексту і передає його компілятору. Якщо блок тексту містить директиви препроцесора, то препроцесор виконає ці директиви.

Всі блоки тексту, не вибрані препроцесором, віддаляються з оброблюваного файлу. Отже, ці блоки тексту не компілюються.

Препроцесор вибирає окремий блок тексту обчислюючи вираз граничної константи, який слідує за кожною директивою #if або #elif, поки результатом виразу граничної константи не буде "істина" (не нуль). Вибирається весь текст (включаючи ті, що починаються з # інші директиви препроцесора) до відповідного #elif, #else або #endif.

Якщо значенням всіх виразів граничних констант буде "брехня", чи ні директиви #elif, то препроцесор вибере блок тексту після пропозиції #else. Якщо пропозиції #else немає, то блок взагалі не вибирається.

Кожен вираз граничної константи відповідає правилам Розділу 5.2.10. Ці вирази не можуть містити виразів sizeof, приведення типа або констант, що перераховують. Проте, вони можуть містити оператора препроцесора defined в спеціальному постійному виразі, що має наступний синтаксис:

    

defined(ідентифікатор)

 

Це постійний вираз матиме значення "істина" (не нуль), якщо заданий ідентифікатор визначений, інакше - "брехня" (0). Ідентифікатор, визначений як порожній текст, вважається визначеним.

Директиви #if, #elif, #else і #endif можуть бути вкладені в інші директиви #if. Кожна вкладена директива #else, #elif або #endif належить до найближчої до неї директиви #if.

Приклад 1

У даному прикладі директиви #if і #endif управляють компіляцією одного з трьох викликів функції. Виклик функції credit компілюється, якщо визначений ідентифікатор CREDIT. Якщо визначений ідентифікатор DEBIT, то компілюється виклик функції debit. Якщо не визначений жоден з ідентифікаторів, то компілюється виклик printerror. Звернете увагу на те, що CREDIT і credit це різні ідентифікатори в мові C.

          #if defined(CREDIT)   

               credit();   

          #elif defined(DEBIT)   

               debit();   

          #else   

               printerror();   

          #end   

Директиви #ifdef і #ifndef

Синтаксис:

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

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

  

Директиви #ifdef і #ifndef виконують ті ж функції, що і директива #if з defined(ідентифікатор). Директиви #ifdef і #ifndef можна використовувати скрізь, де допустиме використання #if. Ці директиви реалізовані тільки для забезпечення сумісності з попередніми версіями мови. Переважно використовувати постійний вираз defined(ідентифікатор) з директивою #if.

Коли препроцесор виявляє директиву #ifdef, він перевіряє, чи визначений ідентифікатор. Якщо це так, те значення умови "істина" (не нуль), і "брехня" (0) інакше.

Директива #ifndef перевіряє умову, протилежну умові #ifdef. Якщо ідентифікатор не визначений (або його визначення видалене за допомогою #undef), то умова "істина", і "брехня" (0) інакше.

Коментарії

Коментарій – це текст, який ігнорується при компіляції (інтерпретації)

В мові С є два типи коментаріїв:

- однорядковий;

- багаторядковий.

Однорядковий коментарій створюється за допомогою символів //. Наприклад

int a=5; // a++;

printf("a = %i",a);

На екран буде виведено 5, оскільки текст a++ - коментарій.

Багаторядковий коментар створюється за допомогою комбінації символів /*…*/.


 

А также другие работы, которые могут Вас заинтересовать

45967. Искусственное и естественное старение корпусов 10.81 KB
  Для уменьшения влияния внутренних напряжений применяютестественное или искусственное старение либо вылеживание деталей послеизготовления заготовок.
45968. Сварочное производство: контактная и диффузионная сварка, сварка взрывом и трением. Пайка металлов 94.69 KB
  Отработаны и внедрены технологические процессы сварки различных алюминиевых магниевых и титановых сплавов а так же черных металлов и нержавеющих сталей. Все операции технологических процессов сварки проходят под контролем ОТК и ВП МО для изделий В и ВТ с обязательным подтверждением марки свариваемых материалов стилоскопированием или спектральным анализом на современном импортном и отечественном оборудовании. Продолжительность процесса сварки составляет около 5мин. Сварные швы полученные в результате диффузионной сварки при высоком...
45969. Механическая обработка металлов. Станки для обработки металлов резанием. Технологические возможности способов резания: точения, сверления, протягивания, фрезерования, шлифования, хонингования 95.99 KB
  Технологические возможности способов резания: точения сверления протягивания фрезерования шлифования хонингования. Обработка резанием это процесс получения детали требуемой геометрической формы точности размеров взаиморасположения и шероховатости поверхностей за счет механического срезания с поверхностей заготовки режущим инструментом материала технологического припуска в виде стружки рис. К инструменту прикладывается усилие резания равное силе сопротивления материала резанию и сообщается перемещение относительно заготовки со...
45970. Резьбовые соединения. Основные виды, конструктивные формы, расчетные зависимости 31.5 KB
  Различают резьбы цилиндрические и конические. В зависимости от назначения применяемые резьбы можно разбить на три группы: крепежная. Крепежная и крепежноуплотняющая резьбы как правило имеют треугольный профиль обеспечивающий высокую прочность резьбы и наиболее благоприятные условия от самоотвинчивания. Резьбы треугольного профиля подразделяют на два основных типа: 1.
45971. Шпоночные и шлицевые соединения. Типы, основные параметры соединений. Расчеты на прочность 31 KB
  Шпоночными называют разъемные соединения составных частей изделия с применением шпонок. Шпоночные соединения могут быть неподвижными и подвижными и служат обычно для предотвращения относительного поворота ступицы и вала при передаче вращающего момента. Шпоночные соединения широко применяют во всех отраслях машиностроения.
45972. Ременные передачи. Разновидности. Типы ремней и конструкции шкивов. Расчет основных параметров ременной передачи 27.5 KB
  По форме различают плоские клиновые поликлиновые и круглые ремни. Плоские ремни в поперечном сечении имеют форму прямоугольника шириной значительно превосходящей толщину. Клиновые ремни в сечении представляют собой трапецию. Эти ремни благодаря клиновому взаимодействию со шкивами характеризуются повышенному взаимодействию повышенной тяговой способностью.
45973. Цилиндрические зубчатые передачи 126 KB
  Кроме того различают индексы относящиеся: w к начальной окружности; b к основной окружности; к окружности вершин зубьев; f к окружности впадин зубьев. Параметры относящиеся к делительной окружности дополнительного индекса не имеют. 3 называют кривую которую описывает точка В прямой NN перекатываемой без скольжения по окружности с диаметром db. Производящая прямая NN является касательной к основной окружности и нормалью ко всем производимым ею эвольвентам.
45974. Редукторы - продукция материально-технического назначения 38 KB
  Наибольшее распространение в промышленности получили планетарные и цилиндрические моторредукторы выполненные по соосной схеме взаимного расположения электродвигателя и выходного вала. А также червячные моторредукторы с расположением электродвигателя под 90град. К моторредукторам общемашиностроительного применения относят: цилиндрические моторредукторы планетарные моторредукторы спироидные моторредукторы червячные и цилиндрическочервячные моторредукторы волновые моторредукторы моторредукторы специального назначения. Облсть...
45975. Конструкция и назначение червячных передач. Кинематический и прочностной расчеты 29.5 KB
  Червячные передачи это передачи за счет зацепления витков червяка и зубьев червячного колеса. При вращении червяка его витки входят в зацепление с зубьями червячного колеса. Расстояние между одноименными точками боковых сторон смежных витков червяка измеренное параллельно оси называют шагом червяка р. Делительный диаметр червяка dx = qm.