Ц Препроцесори
Претпроцесори су програми који обрађују изворни код пре него што почне стварна компилација. Они нису део процеса компилације, али раде одвојено, дозвољавајући програмерима да модификују код пре компилације.
- То је први корак кроз који пролази Ц изворни код када се конвертује у извршну датотеку.
- Главни типови директива за претпроцесор су Макрои Условна компилација укључивања датотека и друге директиве као што је #ундеф #прагма итд.
- Ове директиве се углавном користе за замену датог дела Ц кода другим Ц кодом. На пример, ако напишемо '#дефине ПИ 3.14', онда је ПИ замењен са 3.14 од стране претпроцесора.
Типови Ц претпроцесора
Сви горе наведени предпроцесори могу се класификовати у 4 типа:
Макрои
Макрои се користе за дефинисање константи или креирање функција које су замењене претпроцесором пре превођења кода. Два претпроцесора #дефине и #ундеф се користе за креирање и уклањање макроа у Ц.
#дефине вредност токена
#ундеф токен
где је након претходне обраде токен биће проширен на своје вредност у програму.
Пример:
C #include // Macro Definition #define LIMIT 5 int main (){ for ( int i = 0 ; i < LIMIT ; i ++ ) { printf ( '%d n ' i ); } return 0 ; }
Излаз
0 1 2 3 4
У горњем програму пре почетка компилације реч ЛИМИТ се замењује са 5. Реч 'ЛИМИТ' у макро дефиницији назива се макро шаблон и '5' је проширење макроа.
Напомена Не постоји тачка-зарез (;) на крају макро дефиниције. Макро дефиницијама није потребна тачка и зарез за крај.
Има и неких Унапред дефинисани макрои у Ц који су корисни у пружању различитих функционалности нашем програму.
Макро дефинисан претходно може бити недефинисан коришћењем #ундеф претпроцесора. На пример у горњем коду
C #include // Macro Definition #define LIMIT 5 // Undefine macro #undef LIMIT int main (){ for ( int i = 0 ; i < LIMIT ; i ++ ) { printf ( '%d n ' i ); } return 0 ; }
Излаз:
./Solution.c: In function 'main': ./Solution.c:13:28: error: 'MAX' undeclared (first use in this function) printf('MAX is: %dn' MAX); ^ ./Solution.c:13:28: note: each undeclared identifier is reported only once for each function it appears inМакрои са аргументима
Такође можемо пренети аргументе макроима. Ови макрои раде слично функцијама. На пример
# дефинисати фоо(а б) а + б
#дефине фунц(р) р * рХајде да ово разумемо помоћу програма:
C#include// macro with parameter #define AREA(l b) (l * b) int main (){ int a = 10 b = 5 ; // Finding area using above macro printf ( '%d' AREA ( a b )); return 0 ; }
ИзлазArea of rectangle is: 50Објашњење: У горњем програму макро ПОВРШИНА (л б) је дефинисан за израчунавање површине правоугаоника множењем његовог дужина (л) и ширина (б) . Када ОБЛАСТ (а б) назива се шири на (а * б) а резултат се израчунава и штампа.
Молимо погледајте Врсте макроа у Ц за више примера и типова.
Укључивање датотеке
Укључивање датотека вам омогућава да у тренутни програм укључите екстерне датотеке (библиотеке датотека заглавља итд.). Ово се обично ради помоћу #инцлуде директива која може укључивати и системске и кориснички дефинисане датотеке.
Синтакса
Постоје два начина за укључивање датотека заглавља.
#инцлуде
#инцлуде 'филенаме'Тхе ' <' и '>' заграде реци компајлеру да потражи датотеку у стандардни именик док двоструки наводници ('') реци компајлеру да тражи датотеку заглавља у директоријуму изворне датотеке.
Пример:
C// Includes the standard I/O library #includeint main () { printf ( 'Hello World' ); return 0 ; }
ИзлазHello WorldЦондитионал Цомпилатион
Условна компилација омогућава вам да укључите или искључите делове кода у зависности од одређених услова. Ово је корисно за креирање кода специфичног за платформу или за отклањање грешака. Постоје следеће условне директиве препроцесора: #иф #ифдеф #ифндеф елсе #елиф и #ендиф
Синтакса
Општа синтакса условних предпроцесора је:
#иф
// неки код
#елиф
// још неки код
#елсе
// Још мало кода
#ендифДиректива #ендиф се користи за затварање директива отварања #иф #ифдеф и #ифндеф.
Пример
C#include// Defining a macro for PI #define PI 3.14159 int main (){ // Check if PI is defined using #ifdef #ifdef PI printf ( 'PI is defined n ' ); // If PI is not defined check if SQUARE is defined #elif defined(SQUARE) printf ( 'Square is defined n ' ); // If neither PI nor SQUARE is defined trigger an error #else #error 'Neither PI nor SQUARE is defined' #endif // Check if SQUARE is not defined using #ifndef #ifndef SQUARE printf ( 'Square is not defined' ); // If SQUARE is defined print that it is defined #else printf ( 'Square is defined' ); #endif return 0 ; }
ИзлазPI is defined Square is not definedОбјашњење: Овај код користи условне директиве препроцесора ( #ифдеф #елиф и #ифндеф ) да проверите да ли су одређени макрои ( ПИ и СКУАРЕ ) су дефинисани. Пошто је ПИ дефинисан, програм штампа ' ПИ је дефинисан ' затим проверава да КВАДРАТ није дефинисан и штампа ' Квадрат није дефинисан '.
Друге директиве
Осим примарних предпроцесорских директива, Ц такође обезбеђује друге директиве за управљање понашањем компајлера и отклањањем грешака.
#прагма:
Пружа специфична упутства компајлеру да контролише његово понашање. Користи се за онемогућавање поравнања скупова упозорења итд.
Синтакса
#прагма директива
Неке од #прагма директива се разматрају у наставку:
- #прагма стартуп: Ове директиве нам помажу да наведемо функције које су потребне за покретање пре покретања програма (пре него што контрола пређе на маин()).
- #прагма излаз : Ове директиве нам помажу да наведемо функције које су потребне за покретање непосредно пре изласка из програма (непосредно пре него што се контрола врати из маин()).
Пример
C#includevoid func1 (); void func2 (); // specifying funct1 to execute at start #pragma startup func1 // specifying funct2 to execute before end #pragma exit func2 void func1 () { printf ( 'Inside func1() n ' ); } void func2 () { printf ( 'Inside func2() n ' ); } int main (){ void func1 (); void func2 (); printf ( 'Inside main() n ' ); return 0 ; }
ИзлазInside main()Горњи код ће произвести излаз као што је горе наведено када се покрене на ГЦЦ компајлерима док је очекивани излаз био:
Очекивани излаз
Inside func1() Inside main() Inside func2()Ово се дешава зато што ГЦЦ не подржава #прагма покретање или излаз. Међутим, можете користити доњи код за очекивани излаз на ГЦЦ компајлерима.
C#includevoid func1 (); void func2 (); void __attribute__ (( constructor )) func1 (); void __attribute__ (( destructor )) func2 (); void func1 () { printf ( 'Inside func1() n ' ); } void func2 () { printf ( 'Inside func2() n ' ); } int main () { printf ( 'Inside main() n ' ); return 0 ; }
ИзлазInside func1() Inside main() Inside func2()У горњем програму користили смо неке специфичне синтаксе тако да се једна од функција извршава пре главне функције, а друга после главне функције.
Креирај квиз