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++ - коментарій.

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


 

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

19190. Упругое рассеяние в системе центра масс. Связь между сечением рассеяния и прицельным параметром 171 KB
  Лекция 2 Упругое рассеяние в системе центра масс. Связь между сечением рассеяния и прицельным параметром. Вычисление сечения рассеяния в лабораторной системе координат по известному сечению рассеяния в системе центра масс. Рассмотрим процесс упругого рассеяния в сис
19191. Сечение рассеяния в кулоновском и обратноквадратичном потенциале 136.5 KB
  Лекция 3 Сечение рассеяния в кулоновском и обратноквадратичном потенциале. Кулоновский потенциал взаимодействия имеющий вид Ur = /r где  = q1q2 – один из немногих потенциалов для которого можно вычислить аналитически дифференциальное сечение рассеяния. На его приме
19192. Упругое рассеяние иона на атоме при экранированном кулоновском потенциале взаимодействия 206 KB
  Лекция 4 Упругое рассеяние иона на атоме при экранированном кулоновском потенциале взаимодействия. Функция экранирования. Линдхардовское сечение рассеяния для экранированного кулоновского потенциала. Аппроксимация аналитическими выражениями. Рассмотрим процессы
19193. Ядерная и электронная тормозная способность и их связь с удельными потерями энергии при движении ионов в твердом теле 250 KB
  Лекция 5 Ядерная и электронная тормозная способность и их связь с удельными потерями энергии при движении ионов в твердом теле. Расчет тормозных способностей ионов для кулоновского и экранированного кулоновского потенциалов взаимодействия. Расчет тормозных способнос
19194. Расчет траекторных пробегов ионов в твердом теле и распределение внедренных ионов по глубине образца 285 KB
  Лекция 6 Расчет траекторных пробегов ионов в твердом теле и распределение внедренных ионов по глубине образца. Коэффициент отражения и зарядовый состав отраженных ионов. Под пробегом будем понимать путь который проходит ион в твердом теле до полной остановки. Перед в
19195. Расчет коэффициента распыления в модели Зигмунда. Эмпирические формулы расчета коэффициента распыления 167 KB
  Лекция 7 Расчет коэффициента распыления в модели Зигмунда. Эмпирические формулы расчета коэффициента распыления. Энергетическое и угловое распределение распыленных частиц. Ионное травление. Расчет скорости ионного травления. Профиль ионной имплантации при учете расп
19196. Отраженные и вторичные электроны электрон-электронной эмиссии. Энергетический спектр и угловые характеристики 154 KB
  Лекция 8 Отраженные и вторичные электроны электронэлектронной эмиссии. Энергетический спектр и угловые характеристики. Расчет удельных потерь энергии и траекторного пробега. В методах элементного и структурного анализа обычно используются электронные пучки с энерг...
19197. Сечение ударной электронной ионизации. Оже-электроны. Систематика Оже-переходов. Переходы Костера-Кронига 214.5 KB
  Лекция 9 Сечение ударной электронной ионизации. Ожеэлектроны. Систематика Ожепереходов. Переходы КостераКронига. Излучательные переходы. Классификация линий характеристического рентгеновского излучения. Вероятности рентгеновской флуоресценции и Ожепереходов. П
19198. Взаимодействие рентгеновского излучения с твердым телом (фотоэффект, эффект Комптона) 353 KB
  Лекция 10 Взаимодействие рентгеновского излучения с твердым телом фотоэффект эффект Комптона. Сечение фотоэффекта и его связь с линейным коэффициентом поглощения рентгеновского излучения. Расчет массового коэффициента поглощения для полиатомных образцов. Полезно