zastępować zarezerwowane słowa lub symbole innymi,

Podobne dokumenty
Katedra Elektrotechniki Teoretycznej i Informatyki. wykład 12 - sem.iii. M. Czyżak

Co nie powinno być umieszczane w plikach nagłówkowych:

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Wykład. Materiały bazują częściowo na slajdach Marata Dukhana

Podstawy programowania C. dr. Krystyna Łapin

1. Pierwszy program. Kompilator ignoruje komentarze; zadaniem komentarza jest bowiem wyjaśnienie programu człowiekowi.

Laboratorium 3: Preprocesor i funkcje ze zmienną liczbą argumentów. mgr inż. Arkadiusz Chrobot

Podstawy programowania skrót z wykładów:

Wykład VII. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik

#line #endif #ifndef #pragma

Temat 1: Podstawowe pojęcia: program, kompilacja, kod

Programowanie strukturalne i obiektowe

Funkcje. Spotkanie 5. Tworzenie i używanie funkcji. Przekazywanie argumentów do funkcji. Domyślne wartości argumentów

Podstawowe elementy proceduralne w C++ Program i wyjście. Zmienne i arytmetyka. Wskaźniki i tablice. Testy i pętle. Funkcje.

Wstęp do programowania INP003203L rok akademicki 2018/19 semestr zimowy. Laboratorium 3. Karol Tarnowski A-1 p.

Etapy kompilacji. Wykład 7. Przetwarzanie wstępne, str. 1. #define ILE for(i=0; i<ile; i++)...

Stałe, znaki, łańcuchy znaków, wejście i wyjście sformatowane

Funkcja (podprogram) void

1 Podstawy c++ w pigułce.

Wstęp do programowania INP003203L rok akademicki 2018/19 semestr zimowy. Laboratorium 2. Karol Tarnowski A-1 p.

1 Podstawy c++ w pigułce.

Wykład 15. Literatura. Kompilatory. Elementarne różnice. Preprocesor. Słowa kluczowe

Zmienne, stałe i operatory

4. Funkcje. Przykłady

Cwiczenie nr 1 Pierwszy program w języku C na mikrokontroler AVR

Wstęp do programowania. Wykład 1

Preprocesor. natychmiast następuje \n są usuwane następny wiersz zostaje połączony z tym, w którym był znak \ o usuwane są wszystkie komentarze są

Mikrokontroler ATmega32. Język symboliczny

Elementy języka C. ACprogramislikeafastdanceonanewlywaxeddancefloorbypeople carrying razors.

Tablice, funkcje - wprowadzenie

Część 4 życie programu

Programowanie C++ Wykład 2 - podstawy języka C++ dr inż. Jakub Możaryn. Warszawa, Instytut Automatyki i Robotyki

KURS C/C++ WYKŁAD 1. Pierwszy program

Podstawy Informatyki. Inżynieria Ciepła, I rok. Wykład 10 Kurs C++

Wstęp do programowania

Programowanie Obiektowo Zorientowane w języku c++ Przestrzenie nazw

Podstawy programowania. Wykład 9 Preprocesor i modularna struktura programów. Krzysztof Banaś Podstawy programowania 1

tablica: dane_liczbowe

ISO/ANSI C - funkcje. Funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje

Podstawy języka C++ Maciej Trzebiński. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. Praktyki studenckie na LHC IVedycja,2016r.

Podstawy programowania - 1

utworz tworzącą w pamięci dynamicznej tablicę dwuwymiarową liczb rzeczywistych, a następnie zerującą jej wszystkie elementy,

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

1 P roste e t ypy p d a d n a ych c - c ąg ą g d a d l a szy 2 T y T py p z ł z o ł żo ż ne e d a d n a ych c : T BLICE

#include <stdio.h> int main( ) { int x = 10; long y = 20; double s; s = x + y; printf ( %s obliczen %d + %ld = %f, Wynik, x, y, s ); }

Programowanie I. O czym będziemy mówili. Plan wykładu nieco dokładniej. Plan wykładu z lotu ptaka. Podstawy programowania w językach. Uwaga!

Programowanie w C++ Wykład 8. Katarzyna Grzelak. 15 kwietnia K.Grzelak (Wykład 8) Programowanie w C++ 1 / 33

Programowanie w C++ Wykład 9. Katarzyna Grzelak. 14 maja K.Grzelak (Wykład 9) Programowanie w C++ 1 / 30

Wstęp do Informatyki i Programowania Laboratorium: Lista 0 Środowisko programowania

I - Microsoft Visual Studio C++

Wstęp do Programowania, laboratorium 02

Programowanie w C++ Wykład 2. Katarzyna Grzelak. 4 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 44

Język C - podstawowe informacje

Podział programu na moduły

Wykład II Tablice (wstęp) Przykłady algorytmów Wstęp do języka C/C++

KURS C/C++ WYKŁAD 2. char znak; znak = a ; Program 2 #include<stdio.h> void main() { char znak; while( (znak = getchar() )!= t ) putchar(znak); }

C++ wprowadzanie zmiennych

INSTRUKCJE REPETYCYJNE PĘTLE

Wykład I. Programowanie II - semestr II Kierunek Informatyka. dr inż. Janusz Słupik. Wydział Matematyki Stosowanej Politechniki Śląskiej

Języki programowania obiektowego Nieobiektowe elementy języka C++

Programowanie w Turbo Pascal

TABLICE W JĘZYKU C/C++ typ_elementu nazwa_tablicy [wymiar_1][wymiar_2]... [wymiar_n] ;

Na ekranie monitora zostaną wyświetlone w dwu liniach teksty Pierwsza linia Druga linia

Podstawy programowania w języku C++

Algorytmika i Programowanie VBA 1 - podstawy

2 Przygotował: mgr inż. Maciej Lasota

Poprzedni wykład [ ] :

Zajęcia nr 1 Podstawy programowania. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

Pliki wykład 2. Dorota Pylak

Wstęp do informatyki- wykład 11 Funkcje

Programowanie w języku C++ Grażyna Koba

Język C zajęcia nr 11. Funkcje

Języki i metodyka programowania. Typy, operatory, wyrażenia. Wejście i wyjście.

Języki i metodyka programowania. Wprowadzenie do języka C

Wstęp do informatyki- wykład 9 Funkcje

Podstawy programowania w C materiały dla ucznia:

Pytania sprawdzające wiedzę z programowania C++

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 2. Karol Tarnowski A-1 p.

Podstawy programowania (1)

Wstęp do programowania

ALGORYTMY I STRUKTURY DANYCH

Podstawy Informatyki. Kompilacja. Historia. Metalurgia, I rok. Kompilatory C++ Pierwszy program. Dyrektywy preprocesora. Darmowe:

Podstawy programowania, Poniedziałek , 8-10 Projekt, część 1

Ok. Rozbijmy to na czynniki pierwsze, pomijając fragmenty, które już znamy:

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie?

Wstęp do programowania INP001213Wcl rok akademicki 2018/19 semestr zimowy. Wykład 2. Karol Tarnowski A-1 p.

Podstawy Informatyki. Metalurgia, I rok. Wykład 6 Krótki kurs C++

Inżynieria Wytwarzania Systemów Wbudowanych

Abstrakcyjne struktury danych w praktyce

Pytania z języka C/C++ main dyrektywy preprocesora #include 15. #define 16. #define słowa zastrzeżone \n, \t, \f 26.

Podstawy Programowania.

3. Instrukcje warunkowe

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

Język C, tablice i funkcje (laboratorium, EE1-DI)

Język ludzki kod maszynowy

Programowanie komputerowe. Zajęcia 1

Podstawy Programowania C++

Podstawy języka C++ Maciej Trzebiński. Praktyki studenckie na LHC IFJ PAN. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. M. Trzebiński C++ 1/16

Metodyki i Techniki Programowania MECHANIZM POWSTAWANIA PROGRAMU W JĘZYKU C PODSTAWOWE POJĘCIA

Każdy z nich posiada swoje parametry. W przypadku silnika może to być moc lub pojemność, w przypadku skrzyni biegów można mówić o skrzyni

Transkrypt:

Wykład 7 7. Preprocesor i dyrektywy kompilatora 7.1. Makrodefinicje proste 7.2. Makrodefinicje parametryczne 7.3. Usuwanie definicji makra 7.4. Włączanie innych zbiorów do tekstu programu 7.5. Dyrektywy kompilacji warunkowej 7.6. Kompilacja modułów 7.7. Dyrektywa #pragma 7.8. Wybrane operacje na jednostkach leksykalnych Preprocesor języka C++ umożliwia: definiowanie makrodefinicji pozwalających uprościć postać kodu źródłowego programu; dołączanie tekstów plików, np. zbiorów nagłówkowych zawierających prototypy standardowych funkcji bibliotecznych; sterowanie przebiegiem kompilacji. 7.1. Makrodefinicje proste Makrodefinicje proste mają następującą postać: #define identyfikator makro_tekst_lub_wartość Każde wystąpienie identyfikatora w tekście programu zostanie zastąpione ciągiem makro_tekst_lub_wartość. Na końcu makra nie dajemy średnika, gdyż znalazłby się on w jego rozwinięciu. Za pomocą makrodefinicji prostych można: definiować stałe, zastępować zarezerwowane słowa lub symbole innymi, tworzyć identyfikatory typów danych przy użyciu standardowych typów danych, tworzyć skróty poleceń. Przykłady. // definiowanie stałych #define IMIE Adam #define PI 3.14159 #define TRUE 1 // definiowanie słów kluczowych #define BEGIN #define END #define POCZ main() // definiowanie typów danych #define BOOLEAN char #define BYTE unsigned char #define REAL double // tworzenie skrótów poleceń #define WRITE printf #define READ scanf #define ReadKey getch() #define WRITELN printf( \n ) Makrodefinicje umożliwiają zdefiniowanie nowej nazwy dla standardowego typu danych, ale nie realizują tego samego co specyfikator typu typedef, który pozwala zadeklarować nowy typ danych. typedef int * WINT; // deklaracja typu WINT wskaźniki int * Natomiast deklaracja #define WINT int * zastępuje w kodzie źródłowym WINT wyrażeniem int *. Dlatego definicja postaci WINT p1, p2; odpowiada definicji int * p1, p2; Zmienna p1 jest wskaźnikiem na int, natomiast zmienna p2 jest typu int. 7.2. Makrodefinicje parametryczne Do makra można przekazywać parametry. Ogólna postać dyrektywy #define wykorzystującej parametry jest następująca: #define identyfikator(id_par1, id_par2,... ) wyrażenie_makro Należy pamiętać, że w definicji makra nawias otwierający musi następować bezpośrednio po identyfikatorze makrodefinicji. Wywołanie makrodefinicji przypomina wywołanie funkcji. Identyfikatory parametrów zostaną zastąpione nazwami parametrów. Należy jednak pamiętać, że w odróżnieniu od funkcji nie jest sprawdzana zgodność typu parametrów makra i przekazywanych argumentów. WINT p1, p2; // dwie zmienne typu WINT Makrodefinicja DZIEL: Ostatnia definicja odpowiada definicji: WINT p1; // int * p1; WINT p2; // int * p2; Zmienne p1 i p2 są wskaźnikami na int. #define DZIEL(a,b) ((a) / (b)) Wywołanie DZIEL(x,y) W efekcie rozwinięcia otrzymamy tekst ((x) / (y)). Umieszczenie tekstu w nawiasach pozwala ustrzec się od błędów podczas przekazywania wyrażeń.

W przypadku, gdyby zdefiniowano DZIEL(a,b) (a / b) wówczas rozwinięcie wywołania DZIEL(x+1, y+2) prowadziłoby do wyrażenia x+1 / y+2 = x + 1/y + 2. Jest to wyrażenie różne od oczekiwanego. Wywoływanie makrodefinicji Wywołanie makrodefinicji jest podobne do wywołania funkcji. Różnice występują w tych przypadkach, w których wyrażenie będące parametrem wywołania jest obliczane w kilku etapach. #define KWADRAT(a)((a) (a)) int i=5; long w; w = KWADRAT(i++); // w = ((i++) (i++)) Wartość zmiennej i zostanie zwiększona dwurotnie, tzn. i = 7, w = 5 6 zamiast i = 6, jak można by oczekiwać tylko na podstawie wywołania makra. #define MIN(a,b) (a) < (b)? (a) : (b) MIN(x++,y++) zostanie rozwinięte: (x++) < (y++)? (x++) : (y++). Zmienna o mniejszej wartości zostanie zwiększona dwa razy, natomiast zmienna o większej wartości jednokrotnie. x=0 i y=2; (x++) < (y++); // (0) < (2); x++ = 1; y++ = 3; wartość wyrażenia w = (x++) < (y++)? (x++) : (y++) = x =1; następnie x++ = 2; ostatecznie: w=1; x=2; y=3. Wniosek: w odwołaniach do makrodefinicji należy unikać przekazywania parametrów, których wartość jest obliczana wieloetapowo. Przykład 7.1. Wykorzystanie makrodefinicji. #define IMIE "Adam" // makro TRUE FALSE #define boolean(x) ((x)? "TRUE" : "FALSE") // jednoliniowe pseudofunkcje #define abs(x) ( ( (x) >= 0 )? (x) : (-x) ) #define max(x,y) ( ( (x) > (y) )? (x) : (y) ) #define min(x,y) ( ( (x) > (y) )? (y) : (x) ) #define kwadrat(x) ( (x) * (x) ) // testowanie znakow #define mala(c) (c >='a' && c <= 'z') #define duza(c) (c >='A' && c <= 'Z') #define cyfra(c) (c >='0' && c <= '9') // konwersja znakow #define mala_litera(c) (c - 'A'+'a') #define duza_litera(c) (c - 'a'+'a') char zn; double x,y; int ww; clrscr(); printf("\nimie : %s", IMIE); x = -2.0; y = 1.0; printf("\n\nliczba x: %6.4lf", x); printf("\nabs(x) : %6.4lf ",abs(x)); printf("\nkwadrat(x) : %6.4lf ",kwadrat(x)); printf("\n\nliczba y: %6.4lf", y); printf("\nmax(x,y) : %6.4lf ",max(x,y)); //1.0000 printf("\nmin(x,y) : %6.4lf ",min(x,y)); //-2.0000 getch(); clrscr(); zn = 'S'; ww = mala(zn); printf("\nznak %c jest mala litera %s", zn, boolean(ww)); ww = duza(zn); printf("\nznak %c jest duza litera %s", zn, boolean(ww)); ww = cyfra(zn); printf("\nznak %c jest cyfra %s", zn, boolean(ww)); printf("\n\nmala litera %c jest %c", zn, mala_litera(zn)); 7.3. Usuwanie definicji makra Dyrektywa #undef umożliwia usunięcie definicji makra. #undef id_makrodefinicji #define IMIE Adam puts(imie); #undef IMIE // początek plik.h void funkcja1(int); void funkcja2(double); // koniec plik.h // początek mplik.cpp #include plik.h // dołączenie plik.h #define IMIE Tomek puts(imie); 7.4. Włączanie innych zbiorów do tekstu programu Dyrektywa #include pozwala włączyć do aktualnie kompilowanego zbioru zawartość innych zbiorów. Najczęściej są to zbiory nagłówkowe, zawierające makrodefinicje oraz deklaracje funkcji bibliotecznych lub zdefiniowanych w innych modułach programu. Dyrektywa #include <nazwa_zbioru> jest wykorzystywana do włączania zbiorów nagłówkowych związanych ze standardowymi bibliotekami języka. Zbiór będzie poszukiwany w kartotece zawierającej standardowe zbiory systemu, która jest określona za pomocą opcji Options Directories Includedirectories. Dyrektywa #include nazwa_zbioru #include ścieżka_dostępu lub dyrektywa powoduje, że zbiór nagłówkowy jest poszukiwany w aktualnej kartotece (kartotece określonej przez ścieżkę dostępu), a jeżeli nie zostanie znaleziony to jest poszukiwany w kartotece zawierającej standardowe zbiory systemu. void main()... void funkcja1(int)... void funkcja2(double)... // koniec mplik.cpp 7.5. Dyrektywy kompilacji warunkowej Dyrektywy kompilacji warunkowej #if, #elif umożliwiają wykonanie lub nie kompilacji pewnych fragmentów kodu źródłowego w zależności od spełnienia określonych warunków. Składnia dyrektyw kompilacji warunkowej jest podobna do konstrukcji if-else: #if wyr_stałe_1 sekwencja instrukcji kompilowanych jeżeli wyr_stałe_1 #elif wyr_stałe_2 sekwencja instrukcji kompilowanych jeżeli wyr_stałe_2... #elif wyr_stałe_n sekwencja instrukcji kompilowanych jeżeli wyr_stałe_n #else sekwencja instrukcji kompilowanych jeśli żaden z powyższych warunków nie jest prawdziwy

Przetwarzane instrukcje są zawarte między dyrektywą #if i. Wyrażenia stałe użyte w dyrektywach #if oraz #elif muszą mieć wartość całkowitą. Jeśli któreś z wyrażeń wyr_stale_i jest prawdziwe, to odpowiadający mu kod jest analizowany, natomiast fragmenty kodu związane z pozostałymi wyrażeniami są pomijane. Dyrektywy #elif i #else są opcjonalne. Każda dyrektywa powinna zaczynać się od nowej linii. Przykład 7.2. Wykorzystanie dyrektyw warunkowych. #define WYK 4 #pragma argsused // nie wysyłaj ostrzeżenia jeżeli wewnątrz // funkcji nie są wykorzystywane jej argumenty double potega(double x) #if WYK < 0 #error Ujemny wykladnik! // przy próbie kompilacji pojawi się // komunikat o błędzie Error directive Ujemny wykładnik! #elif WYK == 0 return 1; #elif WYK == 1 return x; #elif WYK == 2 return x*x; #else int k=0; double s = 1; for (k=0; k<wyk; k++) s*=x; return s; double x = 2; clrscr(); cout << potega(x) << endl; getch(); Dyrektywy umożliwiające stwierdzenie czy dany identyfikator został już zdefiniowany dyrektywą #define i w zależności od tego wykonanie lub nie kompilacji fragmentu programu. #ifdef IDENT wystąpiła definicja #define IDENT... > #ifndef IDENT nie wystąpiła definicja #define IDENT... > #ifdef WYK cout << WYK = << WYK << endl; Możliwy jest również alternatywny sposób sprawdzania czy dany identyfikator został zdefiniowany. #if defined (IDENT) wystąpiła definicja #define IDENT... > Defined jest operatorem preprocesora, który zwraca wartość 1, jeśli jego argument jest zdefiniowany, oraz wartość 0 w przeciwnym przypadku. Zaletą przedstawionej formy jest to, iż można ją stosować w połączeniu z dyrektywą #elif. #if defined(model1) sp = farcoreleft(); #elif defined(model2) sp = coreleft(); #else #error Blad - Bad memory model Dyrektywa #error przerywa kompilację i wypisuje komunikat Blad Bad memory model, jeśli nie zdefiniowano MODEL1 lub MODEL2. 7.6. Kompilacja modułów Dobrze zaprojektowany zbiór nagłówkowy powinien być zabezpieczony przed wielokrotnym włączeniem go do tekstu programu. // plik.h - zbiór nagłówkowy #ifndef PLIK_H #define PLIK_H < deklaracje pliku plik.h > Jeśli makrodefinicja PLIK_H nie została jeszcze zdefiniowana wówczas kompilator musi przeanalizować wszystkie dyrektywy i instrukcje znajdujące się między #ifndef a. W wyniku przetworzenia wspomnianego obszaru zbadane zostaną wszystkie deklaracje znajdujące się w zbiorze nagłówkowym plik.h oraz zdefiniowane zostanie makro PLIK_H. Przy ponownym włączeniu zbioru plik.h jego zawartość nie będzie analizowana. Sposób wykorzystania dyrektyw kompilacji warunkowej w programach wielomodułowych (prog. główny + 4 moduły) ilustruje kolejny przykład. Przykład. 7.3. Kompilacja programów wielomodułowych. Wariant 1. Dołączanie kodu modułów do programu za pomocą dyrektywy #include. Wariant 2. Tworzenie projektu (zbioru modułów do kompilacji); łączenie kodów wynikowych modułów. /* plik nagłówkowy zawierający deklaracje typów oraz prototypy funkcji */ #define PROT.H void pisz_wynik(double); // prototyp funkcji pisz_wynik double suma1(double, double); void suma2(double, double, double *); void suma3(double, double, double &); /* plik pisz.cpp zawierający definicję funkcji pisz_wynik */ void pisz_wynik(double w) printf("modul 4 "); printf("obliczona suma = %10.2lf\n",w); /* plik mod1.cpp zawierający definicję funkcji suma1 */ double suma1(double x, double y) printf("modul 1\n"); pisz_wynik(x+y); return x+y; /* plik mod2.cpp zawierający definicję funkcji suma2 */ void suma2(double x, double y, double *w) printf("modul 2\n"); pisz_wynik(x+y); *w = x+y;

/* plik mod3.cpp zawierający definicję funkcji suma3 */ void suma3(double x, double y, double &w) printf("modul 3\n"); pisz_wynik(x+y); w = x+y; /* -------------- Program główny GLOWNY.CPP - wariant 1 -------------- */ #include "mod1.cpp" // dołącz kod modułu 1 do programu #include "mod2.cpp" // dołącz kod modułu 2 #include "mod3.cpp" // dołącz kod modułu 3 #include "pisz.cpp" // dołącz kod modułu 4 #include <conio.h> #include <iostream.h> /* Wykorzystywane moduły mod1.cpp mod2.cpp mod3.cpp pisz.cpp oraz plik deklaracyjny prot.h */ double a,b, wynik; clrscr(); cout << "Wprowadz dana 1 "; cin >> a; cout << endl; cout << "Wprowadz dana 2 "; cin >> b; cout << endl; wynik = suma1(a,b); // przekazanie argumentów przez wartość suma2(a,b,&wynik); suma3(a,b,wynik); getch(); // przekazanie argumentów przez wskaźnik // przekazanie argumentów przez referencje /* ------------- Program główny GLOWNY1.CPP - wariant 2 ------------ */ projekt: GLOWNY1.PRJ - łączenie kodów wynikowych modułów // w projekcie pliki *.cpp lub *.obj // skompiluj, połącz pliki typu obj i utwórz kod wykonywalny mod1.cpp mod2.cpp mod3.cpp pisz.cpp glowny1.cpp #include <conio.h> #include <iostream.h> // modul 1- utwórz mod1.obj // modul 2 - utwórz mod2.obj // modul 3 - utwórz mod3.obj // modul 4 - utwórz mod4.obj // program główny - utwórz glowny1.obj /* Wykorzystywane moduły mod1.cpp mod2.cpp mod3.cpp pisz.cpp oraz plik deklaracyjny prot.h */... Wyniki: Wprowadz dana 1 20 Wprowadz dana 2 40 Modul 1 Modul 2 Modul 3 7.7. Dyrektywa #pragma Format dyrektywy: #pragma id_dyrektywy, gdzie id_dyrektywy musi być jednym z identyfikatorów dopuszczalnych przez kompilator. #pragma argsused - wyłącza ostrzeżenie informujące o braku odwołań do parametrów funkcji wewnątrz jej ciała. Parameter <identyfikator> is never used in function <funkcja> int pisz(int x, int y) return x; Parameter y is never used #pragma startup id_funkcji < priorytet > #pragma exit id_funkcji < priorytet > Dyrektywy określają funkcje, które są wywoływane przed wywołaniem funkcji main() lub po jej zakończeniu. Funkcja wskazana w dyrektywie ma postać: void funkcja(void). Parametr priorytet jest opcjonalny i ma wartość z przedziału <64,255>. Im mniejsza wartość tym wyższy priorytet. W przypadku rozpoczęcia programu jako pierwsze wywoływane są funkcje o wyższym priorytecie. W przypadku zakończenia programu funkcje o wyższym priorytecie są wywoływane później. Jeżeli priorytet nie został podany, przyjmowana jest wartość 100. W przypadku kilku dyrektyw bez określonego priorytetu funkcje wymienione w późniejszych dyrektywach mają niższy priorytet. void start1(void) cout << "Funkcja start 1\n"; void start2(void) cout << "Funkcja start 2\n"; // funkcje wywoływane przed main() #pragma startup start1 // wyższy priorytet - wywołana jak pierwsza #pragma startup start2 // niższy priorytet - wywołana jako druga void koniec1(void) cout << "Funkcja koniec 1\n"; void koniec2(void) cout << "Funkcja koniec 2\n"; // funkcje wywoływane po main() #pragma exit koniec1 // wyższy priorytet - wywołana jako druga #pragma exit koniec2 // niższy priorytet - wywołana jako pierwsza

7.8. Wybrane operacje na jednostkach leksykalnych Kontynuacja makrodefinicji w następnym wierszu Jeśli makrodefinicja jest zbyt długa, to można ją kontynuować w nowej linii poprzez umieszczenie na końcu linii znaku \ (backslash). #define NAPIS To jest \ tekst printf(napis); Łączenie jednostek leksykalnych za pomocą znaków ## Istnieje możliwość połączenia dwóch jednostek leksykalnych w jedną za pomocą znaków ##. Preprocesor usuwa znaki ## i łączy jednostki leksykalne. #define NOWY_ID(nazwa1, nazwa2)(nazwa1##nazwa2) void main() int NOWY_ID(i,1); i1 = 2; cout << i1 << endl; // zmienna i1 cout << NOWY_ID("To","jest tekst") << endl; // nowy tekst: To jest tekst Konwersja ciągu znaków do łańcucha za pomocą znaku # Umieszczenie znaku # przed nazwą parametru w ciągu jednostek leksykalnych powoduje przekształcenie tego parametru w łańcuch poprzez dołączenie cudzysłowów na początku i na końcu nazwy parametru. #define LAN(str) #str printf(lan(to jest tekst)"\n"); // rozwijane w: To jest tekst char * s = LAN(to jest lancuch); // rozwijane w: to jest lancuch printf("%s\n", s);