include

Transkrypt

include
Katedra Elektrotechniki Teoretycznej i
Informatyki
wykład 12 - sem.III
M. Czyżak
Język C - preprocesor
Dyrektywy preprocesora
Preprocesor C i C++ (cpp) jest programem, który przetwarza tekst
programu przed przekazaniem go kompilatorowi.
Można sterować zachowaniem preprocesora stosując odpowiednie
polecenia zwane dyrektywami preprocesora.
Język C - preprocesor
Dyrektywy preprocesora
#include … - dyrektywa włączająca tekst innego pliku źródłowego w
miejscu jej wystąpienia w pliku podlegającym aktualnie przetwarzaniu
#if
… - dyrektywa kompilacji warunkowej
#elif … - działa podobnie jak else if w języku C
#endif … - oznacza koniec bloku kompilacji warunkowej
#define - definiuje stałe i makroinstrukcje (pseudofunkcje)
#undef
- usuwa definicje stałej lub makra
#ifdef … - znaczy to samo co #if defined(…)
#ifndef
- znaczy to samo co #if !defined(…)
#error … - generuje błąd wraz z opisem
Język C - preprocesor
Dyrektywy kompilacji warunkowej #if, #else, #elif i #endif
#if wyrażenie1
sekwencja instrukcji 1
#elif wyrażenie2
sekwencja instrukcji 2
#elif wyrażenie3
sekwencja instrukcji 3
.................
#elif wyrażenieN
sekwencja instrukcji N
#endif
W standardzie ANSI C dyrektywy #if i #elif można zagnieżdżać do co
najmniej 8 poziomów, a w C99 do co najmniej 63.
Język C - preprocesor
Przykład. Użycie dyrektyw #if, #else, #elif i #endif
#define POLSKA 0
#define FRANCJA
#define USA
1
3
#define AKTYWNY_KRAJ
USA
#if AKTYWNY_KRAJ==USA
char waluta[ ]="dolar";
#elif AKTYWNY_KRAJ==FRANCJA
char waluta[ ]="euro";
#else AKTYWNY_KRAJ==POLSKA
char waluta[ ]="zloty";
#endif
Język C - preprocesor
Dyrektywy kompilacji warunkowej #define i #undef
Dyrektywy #define i #undef
Dyrektywa #define definiuje makro, a dyrektywa usuwa
poprzednio zdefiniowaną nazwę makra.
Dyrektywy #define ma postać #define makro, a dyrektywa
#undef ma postać
#undef
makro.
#define N 5
#define M 5
double tab[N][M]
#undef N
#undef M
// Od tego miejsca N i M nie są zdefiniowane
Język C - preprocesor
Dyrektywy preprocesora
Dyrektywy #ifdef i #ifndef (cz.1)
Dyrektywy te oznaczają odpowiednio " jeśli zdefiniowano" i
" jeśli nie zdefiniowano". Ogólna postać dyrektywy #ifdef to
#ifdef
nazwa_makra
sekwencja instrukcji
#endif
Jeśli nazwa_makra została wcześniej zdefiniowana, wówczas
kompilowany jest kod określony jako sekwencja instrukcji.
Język C - preprocesor
Dyrektywy preprocesora
Dyrektywy #ifdef i #ifndef (cz.2)
Ogólna postać dyrektywy #ifndef (oznacza - jeśli nie
zdefiniowano) ma formę nastepujacą:
#ifndef
nazwa_makra
sekwencja instrukcji
#endif
Jeśli nazwa_makra została nie została wcześniej zdefiniowana przy
użyciu dyrektywy #define, wówczas kompilowany jest kod
określony jako sekwencja instrukcji.
Język C - preprocesor
Dyrektywy preprocesora
Dyrektywy #ifdef i #ifndef (cz.3)
#include <stdio.h>
#define
STUDENT
1
int main() {
#ifdef
STUDENT
printf(" Witaj\n");
#else
printf("Witajcie");
#endif
#ifndef STUDENT
printf("\n STUDENT nie zostal zdefiniowany");
return 0;}
Język C - preprocesor
Dyrektywy preprocesora
Operator defined
Operator ten umożliwia sprawdzenie czy istnieje definicja danej nazwy
makra. Ogólna postać stosowania tego operatora to:
defined nazwa_makra
Jeśli nazwa_makra została zdefiniowana, wyrażenie to ma wartość
logiczną prawda, jeżeli nie to ma wartość fałsz.
Operator ten można użyć następująco:
#if defined FINAL
printf("Wersja finalna\n");
Do operatora defined można też stosować operator negacji ! , wtedy
wyrażenie z operatorem defined ma postać !defined.
Język C - preprocesor
Dyrektywy preprocesora
Dyrektywa #line (cz.1)
Dyrektywa #line zmienia zawartość stałych __LINE__ oraz
__FILE__ będących predefiniowanymi identyfikatorami kompilatora.
Stała __LINE__ zawiera numer aktualnie kompilowanego wiersza kodu.
Stała __FILE__ zawiera nazwę aktualnie kompilowanego pliku
źródłowego. Dyrektywa jest stosowana w następującej postaci
#line numer "nazwa pliku",
gdzie numer to dowolna dodatnia liczba całkowita, a nazwa pliku to
dowolna poprawna nazwa pliku. numer staje się nową wartością
__LINE__ a nazwa pliku staje się nową wartością __FILE__.
Język C – preprocesor
Dyrektywy preprocesora
Przykład. Zastosowanie #line, __LINE__ i __FILE__.(cz.1)
#include <stdio.h>
#include <conio.h>
int main(int argc, char* argv[])
{ printf("Linia programu:%d\n", __LINE__);
printf("Nazwa pliku :%s\n", __FILE__);
#line 30
"Plik1"
printf("Linia programu:%d\n", __LINE__);
printf("Nazwa pliku :%s\n", __FILE__);
getch();
return 0; }
Język C – preprocesor
Dyrektywy preprocesora
Przykład. Zastosowanie #line, __LINE__ i __FILE__.(cz.2)
Wynik działania programu
Linia programu:5
Nazwa pliku :C:\Documents and Settings\Administrator\My
Documents\Unit1_01122010.cpp
Linia programu:30
Nazwa pliku :Plik1
Język C – preprocesor
Dyrektywy preprocesora
Dyrektywa #pragma
Dyrektywa o postaci #pragma nazwa_dyrektywy pozwala
przekazywać kompilatorowi różnego rodzaju polecenia. W języku
C99 dodano operator _Pragma umożliwiający umieszczenie pragmy
w inny sposób
_Pragma("dyrektywa")
Przy użyciu pragmy można wprowadzić polecenia dla konkretnego
kompilatora, jeżeli dany kompilator nie pragmy umieszczonej w
tekście programu to ją pomija.
Język C – preprocesor
Dyrektywy preprocesora
Przykład. Wybrane dyrektywy #pragma dla kompilatora Borland Builder
C++.( cz.1).
#pragma argsused
Pragma ta jest dozwolona tylko między definicjami funkcji i wpływa na
następną definicję funkcji. Wyłącza ona komunikat:
"Parameter name is never used in function func-name"
#pragma hdrstop
Dyrektywa ta kończy listę plików nagłówkowych, które mogą być
prekompilowane. Pozwala to zredukować miejsce na dysku używane
przez prekompilowane nagłówki.
Język C – preprocesor
Dyrektywy preprocesora
Przykład. Wybrane dyrektywy #pragma dla kompilatora Borland Builder
C++ . ( cz.2).
#pragma startup function-name <priority>
#pragma exit function-name <priority>
Pragma startup określa funkcję, która jest wywoływana jako
pierwsza przed main(), a pragma exit, funkcję która jest
wywoływana przed zakończeniem programu przez funkcję _exit().
<priority> może być liczbą z przedziału <64,256>. Funkcje o
wyższym priorytecie są wywoływane jako pierwsze przy starcie i jako
ostatnie przy wyjściu. Funkcja ta musi być wcześniej zdefiniowana i
mieć nagłówek o postaci void fun (void);
Język C – preprocesor
Dyrektywy preprocesora
Przykład. Proste zastosowanie #pragma startup
#include <stdio.h>
#include <conio.h>
void fun(void)
{ printf("Wywolanie
funkcji fun\n"); }
#pragma startup fun
100
int main(int argc, char* argv[])
{ printf(" Funkcja main()");
getch();
return 0; }
Wynik działania programu
Wywolanie
funkcji fun
Funkcja main()
Język C – preprocesor
Operatory preprocesora
Operator #
Operator ten nazywany jest operatorem tworzenia łańcuchów.
Przekształca on poprzedzany argument na tablicę znakową.
Przykład. Przekształcenie programu przy użyciu operatora #.
Program realizowany
#include <stdio.h>
#include <stdio.h>
#define UtworzLan(s) #s
#define UtworzLan(s) #s
int main(){
int main(){
printf(UtworzLan(Lubie C));
printf("Lubie C");
return 0; }
return 0; }
Język C – preprocesor
Operatory preprocesora
Operator ##
Operator ten to operator sklejania łańcuchów.
Przykład. Przekształcenie programu przy użyciu operatora ##.
#include <stdio.h>
#include <stdio.h>
#define PolaczLan(a,b) a##b
#define PolaczLan(s) a##b
int main(){
int main(){
int xy=10;
int xy=10;
printf("%d",PolaczLan(x,y));
printf("%d",xy);
return 0; }
return 0; }
Język C – preprocesor
Komentarze
W języku ANSI C występuje jeden rodzaj komentarza. Jest to komentarz
wielowierszowy rozpoczynający się parą znaków /* i kończący parą */.
Kompilator pomija cały tekst znajdujący się między tymi parami znaków.
Komentarze takie nie mogą być zagnieżdżane( nie można umieszczać
jednego komentarza wewnątrz drugiego). Komentarze takie mogą być
umieszczane w programie prawie w każdym miejscu, z wyjątkiem wnętrza
słowa kluczowego i identyfikatora.
Przykład.
/*
to jest komentarz poprawny */
swi /* komentarz niepoprawny */tch (ch) {
case
1:printf("war1"); break;
case 2:printf("war2"); }
Język C – preprocesor
Komentarze
W standardzie C99 istnieje dodatkowo komentarz jednowierszowy w
stylu C++ rozpoczynający się parą znaków // i rozciągający się do końca
wiersza. Komentarz taki może być umieszczany wewnątrz komentarza
wielowierszowego.
Przykład.
a)
// komentarz jednowierszowy
b) /*
// komentarz zagnieżdżony jednowierszowy
..................................
*/
Język C
Predefiniowane makra
W języku ANSI C istnieje pięć predefiniowanych nazw makr:
__LINE__, __FILE__, __DATE__, __TIME__, __STDC__.
Makra
__LINE__ i
Makro __DATE__
__FILE__ zostały przedstawione poniżej.
zawiera łańcuch w postaci miesiąc/dzień/rok
reprezentujący datę translacji pliku źródłowego na plik obiektowy.
Makro __TIME__
zawiera godzinę kompilacji programu w postaci
godzina:minuta:sekunda .
Makro __STDC__
zawiera informację o zgodności kompilatora ze
standardem C, jeśli jest równe 1, to kompilator jest zgodny ze
standardem.