Notatki
Transkrypt
Notatki
Programowanie 2. Język C++. Wykład 8. 8.1 8.1.1 8.1.2 8.2 8.3 8.4 8.5 Instrukcje preprocesorowe ...................................................................................................................... 1 Instrukcja #define ................................................................................................................................ 1 Instrukcje #pragma ................................................................................................................................ 2 Polecenie _asm ...................................................................................................................................... 3 Polecenie __declspec .......................................................................................................................... 4 Definiowanie makr .................................................................................................................................. 5 Programy wieloplikowe, instrukcja #include ......................................................................................... 7 8.1 Instrukcje preprocesorowe Instrukcje dla preprocesora (instrukcje preprocesorowe) zaczynają się od znaku #. Instrukcje wykonywane są przez preprocesor, przed etapem kompilacji. Lista instrukcji preprocesorowych. #define #error #import #undef #elif 8.1.1 #if #include #using #else #ifdef #line #endif #ifndef #pragma Instrukcja #define Składnia: #define identyfikator token-string Preprocesor w kaŜdym miejscu występowania w programie stringu identyfikator zamieni go na string tokenstring. Przykład 1. Instrukcje #define, #ifdef, #else, #endif, #undef (w09-01-define-undef.cpp). #include <iostream> using namespace std; #define PI 3.14 void main() { #ifdef PI cout << "PI = " << PI << endl; #else cout << "Liczba PI nie jest zdefiniowana \n"; #define PI 3.143 #endif //PI #ifndef LiczbaE cout << "LiczbaE nie jest zdefiniowana \n"; #define LiczbaE 2.71 #else cout << "LiczbaE jest zdefiniowana \n"; cout<<"LiczbaE = " << LiczbaE <<endl; #endif //LiczbaE cout << "LiczbaE = " << LiczbaE << endl; #undef PI // cout << "PI= "<< PI << endl; } 1 Programowanie 2. Język C++. Wykład 8. Przykład 2. Instrukcje #define, #ifndef, #endif (w09-02-ifndef-define.cpp). #include <iostream> using namespace std; // void funkcja() { cout << "*** funkcja() *** #ifndef _funkcja_ #define _funkcja_ void funkcja() { #endif #ifndef _funkcja_ #define _funkcja_ void funkcja() { #endif // void funkcja() { " << endl; } cout << "*** funkcja() *** " << endl; } cout << "*** funkcja() *** " << endl; } cout << "*** funkcja() *** " << endl; } void main() { funkcja(); } 8.1.2 Instrukcje #pragma Instrukcje #pragma określają parametry specyficzne dla sprzętu (hardware), systemu operacyjnego i samego kompilatora. Lista instrukcji #pragma. alloc_text fp_contract optimize auto_inline function pack bss_seg hdrstop pointers_to_members1 check_stack include_alias pop_macro code_seg init_seg1 push_macro comment inline_depth region, endregion component inline_recursion runtime_checks conform1 intrinsic section const_seg make_public setlocale data_seg managed strict_gs_check deprecated message unmanaged fenv_access omp vtordisp1 float_control once warning 2 Programowanie 2. Język C++. Wykład 8. Przykład 1. UŜycie instrukcji #pragma warning (w09-03-pragma-warning-disable.cpp) #include <iostream> using namespace std; #pragma warning( disable : 4101) void { main() int x; // zmienna nie jest zainicjowana } 8.2 Polecenie _asm Słowo kluczowe _asm pozwala zagnieŜdŜać w kodzie C/C++ kod napisany w assemblerze. Przykład 1. Implementacja funkcji w assemblerze (w09-04-asm.cpp). #include <iostream> using namespace std; // Nie pojawi się komunikat: 'warning C4035: no return value' // #pragma warning( disable : 4035) int XRazy_DwaDoPotegiY( int X, int Y); void main() { cout << "3 razy (2 do potegi 4) = } " << XRazy_DwaDoPotegiY( 3, 4) << endl; int XRazy_DwaDoPotegiY( int mnoznik, int wykladnik ) { __asm { mov eax, mnoznik mov ecx, wykladnik shl eax, cl } } // Opis: // mov eax, mnoznik // mov ecx, wykladnik // shl eax, cl ; pobranie wartosci mnoznika ; pobranie wykladnika potegi ; EAX = EAX * ( 2 do potegi CL ) 3 Programowanie 2. Język C++. Wykład 8. 8.3 Polecenie __declspec Polecenie __declspec określa, Ŝe dany typ danych jest przechowywany jako specyficzny atrybut klasy Microsoft (Microsoft-specific storage-class), tzn. typ określony za pomocą specyficznych dla Microsoft modyfikatorów. Przykładami specyficznych atrybutów Microsoft są dllexport, dllimport, naked, noalias, nothrow, property, restrict, selectany, thread, uuid. Przykładem specyficznych atrybutów klasy w standardzie ANSI C/C++, są typy danych z modyfikatorami static i extern. Przykład 1. Program z biblioteką dynamiczną (w09-05-dll-ka.zip). 1. Utworzyć projekt ‘win32 Console Application’, nazwa: dodaj-> wybrać opcje: pusty projekt. 2. Dodać do projektu plik dodaj.cpp 3. W opcjach konfiguracyjnych projektu, w polu ‘Configuration type’ wybrać: Dynamic library (.dll). Plik dodaj.cpp __declspec(dllexport) int { Dodaj(long x, long y,long *z) *z=x+y; return 0; } 4. 5. 6. 7. 8. Skompilować projekt dodaj. Utworzyć projekt ‘win32 Console Application’, nazwa: dodajtest-> wybrać opcje: pusty projekt. Dodać do projektu pliki dodajtest.cpp, dodajtest.h Wkopiować do katalogu projektu dodajtest plik dodaj.lib utworzony w projekcie dodaj. W opcjach konfiguracyjnych projektu dodajtest, wybrać Linker -> Input-> w polu ‘Additional Dependecies’ dopisać: dodaj.lib. Plik dodajtest.h #ifndef __Dodaj_h__ #define __Dodaj_h__ __declspec(dllimport) int Dodaj(long x,long y, long *z); #endif __Dodaj_h__ // __Dodaj_h__ 4 Programowanie 2. Język C++. Wykład 8. Plik dodajtest.cpp #include "dodajtest.h" #include <iostream> using namespace std; void main() { long x,y,z; cout << "Wpisz pierwszy skladnik: "; cin >> x; cout << endl; cout << "Wpisz drugi skladnik: "; cin >> y; cout<<"\n Wywolanie funkcji Dodaj()" << endl <<endl; Dodaj(x,y,&z); cout<<"Suma wpisanych liczb = "<< z << endl; } 9. Skompilować projekt dodajtest. 10. Wkopiować do katalogu projektu dodajtest (tam gdzie znajduje się plik dodajtest.exe) plik dodaj.dll utworzony w projekcie dodaj. 11. Uruchomić aplikacje dodajtest. 8.4 Definiowanie makr Przykład 1. Instrukcja #define (w09-06-naEkran.cpp). #include <iostream> using namespace std; #define _NaEkran(x) \ cout << #x << " = \t" << x << endl; void main() { int x = 5; long y = 73898l; _NaEkran(x); _NaEkran(y); _NaEkran("Tekst"); int *p_x = &x; _NaEkran(p_x); _NaEkran(*p_x); } 5 Programowanie 2. Język C++. Wykład 8. Przykład 2. Definicja i wywołanie makra (w09-07-makroKwadratArgumentu.cpp). #include <iostream> using namespace std; #define KWADRAT_ARG(a) ( (a) * (a) ) #define KWADRAT(a) a * a void main() { long x = 5; long y = KWADRAT_ARG(x); long z = KWADRAT(x); cout << "y = cout << "z = " << y << endl; " << z << endl; long a = 5, b = 7; y = KWADRAT_ARG(a+b); z = KWADRAT(a+b); // 25 // 25 // 12*12 = 144 // 5 + 7 * 5 + 7 = 47 cout << "y = " << y << endl; cout << "z = " << z << endl; } Przykład 2. UŜycie makr __FILE__, __DATE__, __TIME__ (w09-08-LineFileDataTime.cpp). #include <iostream> using namespace std; #define _Wstaw_(x) \ if (! (x)) \ { \ cout << "Blad!! cout << " W linii cout << " W pliku cout << " W kompilowane dniu cout << " O godzinie } " " " " " << << << << << #x << "!" << endl; \ __LINE__ << endl; \ __FILE__ << endl; \ __DATE__ << endl; \ __TIME__ << endl; \ void main() { int x = 5; cout << "_Wstaw_(x==5). \n"; _Wstaw_(x==5); cout << "_Wstaw_(x!=5). \n"; _Wstaw_(x != 5); } 6 Programowanie 2. Język C++. Wykład 8. 8.5 Programy wieloplikowe, instrukcja #include Przykład 1. Program z jednym plikem cpp, dwoma plikami nagłówkowymi (w09-09-define-1cpp-3h.zip). Utworzyć projekt ‘win32 Console Application’, nazwa: ca. Dodać do projektu plik ca.cpp, trzy pliki nagłówkowe funkcja1.h, funkcja2.h, funkcja3.h. Plik ca.cpp #include <iostream> using namespace std; #include "funkcja1.h" #include "funkcja2.h" #include "funkcja3.h" void main () { funkcja1(); funkcja2(); } Plik funkcja1.h #ifndef __funkcja1_h #define __funkcja1_h void funkcja1() { cout << " *** funkcja1() *** " << endl; } #endif // __funkcja1_h Plik funkcja2.h #ifndef __funkcja2_h #define __funkcja2_h void funkcja2() { cout << " *** funkcja2() *** " << endl; } #endif // __funkcja2_h Plik funkcja3.h (funkcja nie będzie kompilowana) #ifndef __funkcja2_h #define __funkcja2_h void funkcja2() { cout << " *** funkcja2() *** " << endl; } #endif // __funkcja2_h 7