Sunteți pe pagina 1din 12

76

Directive de preprocesare

Directivele de preprocesare sunt comenzi date unei componente software specific


limbajului C denumit preprocesor i care acioneaz asupra programului surs naintea
compilrii acestuia.
Directivele de preprocesare ocup o linie de cod i nu se ncheie cu ';'.

#define
Directiva #define permite definirea unor constante sau macrouri. Sintaxa sa este:
#define nume valoare
Rolul ei este de a defini o constant sau o macroinstruciune numit nume i care
este nlocuit n fiierul n care este inclus, prin valoare.

Exemple:
#define MAX_WIDTH 100
char str1[MAX_WIDTH];
char str2[MAX_WIDTH];
Se definesc dou iruri str1 i str2 avnd o lungime de 100 caractere.

#define getmax(a,b) a>b?a:b


int x=5, y;
y = getmax(x,2);
Dup execuie y va avea valoarea 5.

#undef
#undef ndeplinete o funcie invers celei realizate de #define. Ea elimin din lista
de constante predefinite pe cea al crei nume este precizat ca parametru al directivei
#undef:
#define MAX_WIDTH 100
char str1[MAX_WIDTH];
#undef MAX_WIDTH
#define MAX_WIDTH 200
77

char str2[MAX_WIDTH];

#ifdef, #ifndef, #if, #endif, #else i #elif


Aceste directive permit eliminarea unor pri din codul programului dac o anumit
condiie nu este ndeplinit.
#ifdef servete la impunerea compilrii unei secvene de cod numai dac o
constant care este specificat ca parametru a fost anterior definit (indiferent de valoarea
acesteia). Utilizare:

#ifdef name
// secven de cod
#endif

Exemplu:

#ifdef MAX_WIDTH
char str[MAX_WIDTH];
#endif

n cazul dat, linia char str[MAX_WIDTH]; este pstrat n codul care va fi supus
compilrii n cazul n care constanta MAX_WIDTH a fost anterior definit, indiferent de
valoarea sa.
#ifndef opereaz invers: codul cuprins ntre directiva #ifndef i directiva #endif
este compilat numai n cazul n care constanta specificat nu a fost anterior definit.

Exemplu:

#ifndef MAX_WIDTH
#define MAX_WIDTH 100
#endif
char str[MAX_WIDTH];
78

n exemplul dat, n cazul n care constanta MAX_WIDTH nu a fost nc definit se


execut codul care realizeaz definirea sa. n caz contrar se folosete valoarea anterior
definit. deoarece directiva #define nu va fi executat.

#if, #else i #elif (elif = else if) servesc la specificarea unei secvene de cod
care va fi compilat n funcie de ndeplinirea unei condiii. Condiia care poate fi scris
trebuie s poat fi evaluat ca valoare constant.
De exemplu:

#if MAX_WIDTH>200
#undef MAX_WIDTH
#define MAX_WIDTH 200

#elsif MAX_WIDTH<50
#undef MAX_WIDTH
#define MAX_WIDTH 50

#else
#undef MAX_WIDTH
#define MAX_WIDTH 100
#endif

char str[MAX_WIDTH];

Se poate observa faptul c directivele nlnuite #if, #elsif i #else se ncheie cu


#endif.

#error
Aceast directiv provoac abandonarea compilrii dac se produce eroarea
specificat ca parametru.

Exemplu:
#ifndef __cplusplus
#error A C++ compiler is required
79

#endif

n exemplul dat compilarea este abandonat dac constanta __cplusplus nu este


definit.

#include
La ntlnirea acestei directive, preprocesorul o nlocuiete cu fiierul specificat.
Exist dou moduri de specificare a fiierului de inclus:

#include "file"
#include <file>

Singura diferen dintre cele dou forme este faptul c ele specific directoare
diferite n care preprocesorul caut fiierul de inclus. n primul caz, cel n care numele
fiierului este ncadrat ntre ghilimele, fiierul este cutat n acelai director n care este
fiierul care conine directiva. n cazul n care nu este acolo, fiierul este cutat n
directorul implicit n care sunt cutate fiierele antet standard.
Dac numele fiierului este inclus ntre caractere < >, fiierul este cutat direct n
directorul destinat pstrrii fiierelor antet standard.

#pragma
Aceast directiv este folosit pentru a specifica unele opiuni suplimentare
necesare procesului de compilare. Aceste opiuni sunt specifice compilatorului folosit, deci
pentru folosirea lor trebuie consultat documentaia acestuia.

Algoritmi fundamentali

Realizarea unei activiti pe baza unei desfurri precizate i folosind ingrediente


predefinite reprezint elemente de cunoatere uman comune tuturor civilizaiilor studiate.
O reet dintr-o carte de bucate bine scris reprezint un bun exemplu n acest sens i
poate fi dat ca exemplu de algoritm de rezolvare a unei probleme.
80

La baza oricrui program de calculator realizat pentru soluionarea unei probleme


st o activitate similar scrierii unei reete. Ultimele dou decenii de dezvoltare a
informaticii au adus nouti remarcabile n ceea ce privete instrumentele de care
dispunem (C++, Java etc) dar n ceea ce privete realizarea algoritmilor de rezolvare a
problemelor practic nu prea au aprut nouti.
Programarea calculatoarelor pune puine probleme celor ce sunt capabili s
realizeze algoritmul problemei de care se ocup. La realizarea unui algoritm un
programator face apel la un ansamblu de tehnici de manipulare a datelor nsuite n
activitile realizate deja, dar i la un numr de metode de rezolvare consacrate, reunite
sub numele de algoritmi fundamentali.

1. Algoritmul Divide et impera


Metoda Divide et impera presupune mprirea repetat a unei probleme n dou
sau mai multe subprobleme de acelai tip, rezolvarea acestora i apoi combinarea
soluiilor rezultate.
Exemplu de aplicare: Algoritmul de cutare binar
Scriei funcia prezent() de gsire a unei valori x ntr-un ir v[] ordonat cresctor.
Funcia va returna poziia lui a n ir dac acesta este prezent i -1 dac lipsete.

int prezent(int x, int v[], int n)


{
int mini, maxi, mijloc;
mini = 0;
maxi = n - 1;
while (mini <= maxi)
{
mijloc = (mini + maxi) / 2;
if (x < v[mijloc])
maxi = mijloc - 1;
else if (x > v[mijloc])
mini = mijloc + 1;
else
return mijloc; // Gasit!
}
return -1; // Absent!
}
81

2. Algoritmi de sortare
Ordonarea unor masive mari de date reprezint una primele activiti n care au fost
folosite calculatoarele. Exist muli algoritmi de sortare, fiecare cu avantajele,
dezavantajele i variantele sale.
Metoda bulelor (bubble sort) const n compararea elementelor succesive, dou
cte dou, i inversarea lor dac nu respect ordinea dorit. Procedeul continu prin
reluarea prelucrrii irului de valori pn cnd toate elementele acestuia respect ordinea
dorit.

Exemplu: Scriei un program care citete un ir de n valori ntregi i le ordoneaz


cresctor.

#include <iostream>
using namespace std;

void ordon(int [], int);

void main()
{
int n, a[20], i;
cout << "n = "; cin >> n;
for(i=0; i<n; i++)
{
cout << "a[" << i << "]= ";
cin >> a[i];
}
ordon(a, n);
cout << "Sirul ordonat:" << endl;
for(i=0; i<n; i++)
cout << "a[" << i << "]= " << a[i] << endl;
82

void ordon(int a[], int n)


{
int i, aux, fanion, k;
k=0;
do
{
fanion = 0;
for(i = 0; i < n-1-k; i++)
{
if(a[i] > a[i+1])
{
aux = a[i];
a[i] = a[i+1];
a[i+1] = aux;
fanion = 1;
}
}
k++;
}
while (fanion);
}

Dac se analizeaz cu atenie modul de derulare a sortrii, se pot realiza variante


mai rapide de sortare (vezi http://lwh.free.fr).

3. Algoritmi de interclasare
Interclasarea este intercalarea elementelor a dou sau mai multe iruri ordonate
cresctor.
#include <iostream>
using namespace std;

void inter(int a[], int b[], int rez[], int na, int nb);

void main()
{
int na, nb, a[20], b[20], c[40], i;
cout << "na = "; cin >> na;
for(i=0; i<na; i++)
{
83

cout << "a[" << i << "]= ";


cin >> a[i];
}
cout << "nb = "; cin >> nb;
for(i=0; i<nb; i++)
{
cout << "b[" << i << "]= ";
cin >> b[i];
}
inter(a, b, c, na, nb);
cout << "Sirul rezultat:" << endl;
for(i=0; i<na+nb; i++)
cout << "c[" << i << "]= " << c[i] << endl;
}

void inter(int a[], int b[], int rez[], int na, int nb)
{
int i=0, j=0;
do
{
if(i < na && j < nb)
if(a[i]<= b[j])
{
rez[i+j] = a[i];
i++;
}
else
{
rez[i+j] = b[j];
j++;
}
else
if(i < na)
{
rez[i+j] = a[i];
i++;
}
else
{
rez[i+j] = b[j];
j++;
}
}
while(i + j < na + nb);
}
84

4. Algoritmi de iniializare
Realizarea unui set de date de test sub forma unui ir de valori, de obicei aleatoare,
sau a unei matrice revine frecvent n aplicaii.

Exemple:
a. Iniializarea unui ir cu valori aleatoare produse prin apelul funciei rand().

#include <stdlib.h>
#include <iostream>
#include <time.h>
using namespace std;

void main( void )


{
int i;
int a[20];

// Pornesc generatorul de numere aleatoare cu o


// valoare returnata de time().
srand( (unsigned)time( NULL ) );

// Creez cele 20 de valori aleatoare.


for( i = 0; i < 20;i++ )
{
a[i] = rand();
cout << a[i] << endl;
}
}

b. Iniializarea unei matrice unitare. O astfel de matrice are toate elementele nule
cu excepia celor de pe diagonala principal. Elementele de pe diagonala
principal au proprietatea de a avea indicele de linie egal cu cel al coloanei.

#include <iostream>
using namespace std;

void unitate(double a[][10], int n);

void main( void )


{
85

int n, i, j;
double a[10][10];
cout << "n= "; cin >> n;

// Initializez matricea unitate


unitate(a, n);
for(i = 0; i < n; i++)
{
for(j = 0; j<n; j++)
cout << a[i][j] << " ";
cout << endl;
}
}

void unitate(double a[][10], int n)


{
int i, j;
for(i = 0; i < n; i++)
for(j = 0; j<n; j++)
if(i == j) // elem. e pe diag. princ.
a[i][j] = 1.0;
else
a[i][j] = 0.0;
}

5. Algoritmi de calcul cu mulimi


a. Algoritmul de verificare a relaiei de incluziune:
#include <iostream>
using namespace std;

int includ(int a[], int b[], int na, int nb);

int main(void)
{
int t1[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int t2[3] = {4, 5, 6};
if (includ(t1, t2, 10, 3))
cout << "t1 contine t2" << endl;
return 0;
}

int includ(int a[], int b[], int na, int nb)


{
86

int i, j;
i = 0;
do
{
if(a[i] == b[0])
for(j = 1; j < nb; j++)
{
if(a[i+j] != b[j])
break;
};
if(j == nb)
return 1;
i++;
}
while (i < na - nb);
return 0;
}

b. Algoritmul de calcul a intersectiei a doua multimi:

#include <iostream>
using namespace std;

void inters(int a[],int b[],int rez[],int na,int nb,int &nrez);

void main(void)
{
int t1[10] = {2, 4, 6, 8, 9, 10, 15, 15, 15, 17};
int t2[10] = {1, 4, 5, 8, 11, 15, 15, 16, 18, 19};
int t[10], n, i;
// Se efectueaza intersectia multimile t1 si t2 :

inters(t1, t2, t, 10, 10, n);

// Afiseaza rezultatul :
for( i = 0; i < n; i++ )
{
cout << t[i] << " ";
}
cout << endl;
}

void inters(int a[],int b[],int rez[],int na,int nb, int &nrez)


{
int i, j;
i = j = nrez = 0;
87

do
{
if(a[i] < b[j])
i++;
else
if(a[i] > b[j])
j++;
else
{
rez[nrez] = a[i];
i++; j++; nrez++;
}
}
while(i < na && j < nb);
}