Sunteți pe pagina 1din 51

III.

Proiectarea i dezvoltarea sistematic a programelor de mari dimensiuni


1. Programarea calculatoarelor de la teorie la practic 2. Stilul de programare 3. Metoda detalierilor n pai succesivi 4. Exemplu de program 5. Concluzii 6. Preprocesorul 7. Funcii cu numr variabil de argumente

Programarea calculatoarelor
de la teorie la practic
Predarea disciplinelor de programare se bazeaz n foarte mare msur pe exemple de programe. Succesul unui curs de programare depinde, n final, i de modul n care au fost alese exemplele din acel curs. Majoritatea exemplelor prezint studenilor programul direct n forma lui final, trecnd peste detaliile de realizare ale acestuia.

Programarea calculatoarelor
de la teorie la practic
Activitatea de programare nu se restrnge la contemplarea unor programe gata fcute, ci presupune conceperea de noi programe. Este greit impresia c programarea necesit doar cunoaterea unui limbaj de programare, trecerea de la idei la program realizndu-se pe baz de intuiie. Un curs de programare adevrat trebuie s prezinte metode de proiectare i implementare, iar exemplele selectate trebuie s ilustreze un stil de programare i s scoat n eviden stadiile prin care trece un program n procesul dezvoltrii sale.

Stilul de programare
Elemente caracteristice
Unul dintre elementele care contribuie la realizarea eficient a programelor de calitate este stilul de programare. Stilul de programare se poate caracteriza prin : aspectul general al programului; claritatea i lizibilitatea programului; structurarea i modularizarea programului n conformitate cu funciile i operaiile care se implementeaz; robusteea programului : calitatea sa de a continua chiar i la apariia unor erori; mentenabilitatea programului : uurina cu care poate fi modificat i mbuntit ulterior.

Stilul de programare
Prghii de aciune
1. Organizarea programului: definirea subprogramelor (funciilor) n conformitate cu principalele activiti i operaii desprinse din problema care urmeaz a fi rezolvat. 2. Organizarea datelor: trebuie s concorde cu structura obiectelor din realitatea problemei care se rezolv. 3. Comunicarea ntre subprograme: se recomand s se realizeze n special prin mecanismul parametri-argumente i numai n mod excepional prin alte variante. 4. Testarea i tratarea prin program a unor categorii de erori, de exemplu cele de intrare/ieire. Unele limbaje, inclusiv C, permit astfel de operaii ceea ce determin mbuntirea robusteii programelor.

Stilul de programare
Prghii de aciune
5. Alegerea numelor simbolice (identificatorilor) din program astfel nct s se fac o legtur direct cu semnificaia entitii respective n problema de rezolvat. n acest fel se poate uura urmrirea i nelegerea programului. 6. Utilizarea comentariilor: reprezint cea mai simpl metod de documentare a programelor, util chiar i autorilor programului, dac l reanalizeaz dup un anumit timp. n practica programrii se utilizeaz linii de comentarii distincte prin care se descriu funciile programului, funcia fiecrui subprogram, datele de intrare i cele de ieire, indicaii de utilizare a programului etc. De asemenea, se obinuiete ca prelucrrile mai importante sau mai dificile din program s fie nsoite de comentarii explicative.

Stilul de programare
Prghii de aciune
7. Formatul liber de redactare al liniilor surs. Aceast facilitate, prezent n majoritatea limbajelor de programare moderne, permite punerea n concordan a textului programului cu organizarea i semnificaia sa. Utilizarea indentrii duce la creterea lizibilitati i clariti programului. Indentarea reprezint deplasarea spre dreapta a unui bloc de date sau de instruciuni, care aparine unei structuri, fa de marginea stng a elementelor structurii nconjurtoare.

Metoda detalierilor n pai succesivi


(Step Wise Refinement SWR)
Cu ct problema este mai complex, trecerea de la enunul problemei la program este mai dificil. n aceste situaii este util ca att elaborarea algoritmului ct i scrierea programului s se fac treptat, printr-un proces de detaliere succesiv n mai muli pai : Pasul 1 : Se scrie funcia principal(main) utiliznd, pe ct posibil, apeluri de funcii corespunztoare operaiilor de baz care se disting n aceast faz. Se descriu structurile de date aferente programului. Funciile apelate din funcia principal se definesc doar la modul generic (prototip urmat de /*comentarii*/). Paii 2, 3, ... : Se dezvolt funciile apelate direct din funcia principal (pasul 2), apoi funciile apelate din acestea din urm (pasul 3) .a.m.d., pn la elaborarea, n amnunt, a ntregului program.

Metoda detalierilor n pai succesivi


(Step Wise Refinement SWR) Metoda detalierilor n pai succesivi este o metod de proiectare-programare descendent (top-down). Metoda SWR pornete de la general i dezvolt detaliile din aproape n aproape. n principiu, n fiecare pas se dezvolt funciile care au aprut (fiind doar enunate) n pasul anterior. Dac operaiile implementate n pasul curent sunt suficient de complexe, este posibil s fie enunate noi funcii care vor fi dezvoltate (detaliate) n pasul urmtor.

Exemplu de program
Enunul problemei
S se scrie un program pentru realizarea unui top al melodiilor. Persoanele care particip la alctuirea topului se mpart n 4 categorii, dup sex si vrst (mai tineri de 20 de ani i peste 20 de ani). Fiecare persoan nominalizeaz, n ordine, 5 melodii preferate, identificate prin titlu. Datele privind persoanele participante la realizarea topului se citesc de pe mediul de intrare sau dintr-un fiier. Datele pentru o persoan vor fi de forma: nume prenume sex(m sau f) vrsta melodie1 melodie2 melodie3 melodie4 melodie5

Exemplu de program
Enunul problemei
S se afiseze: 1. Lista melodiilor n ordinea popularitii lor. 2. Listele cstigtorilor (cei care au ghicit melodiile cstigatoare), i anume: 4 liste separate cuprinznd numele si prenumele persoanelor care au menionat pe prima pozitie a preferinelor una dintre cele mai solicitate 3 melodii la categoria lor.

Program exemplu
Pasul 1
#include <stdio.h> #include <stdlib.h> #include <string.h> #define NMEL 5 typedef struct pers{ char * nume; char * prenume; char sex; int varsta; char * melodii[NMEL]; } persoana;

Program exemplu
Pasul 1
typedef struct m { char * titlu; int punctaj; } melodie; persoana * citire(int *np){ // citeste datele din intrare si le pune intr-o lista } void afisare_test(persoana *plista, int np){ // afisararile de test sunt foarte importante, pentru a descoperii // eventualele greseli in faza incipienta }

Program exemplu
Pasul 1
melodie * top_melodii(persoana *plista, int np){ // creaza o lista cu melodiile si voturile aferente fiecarei melodii // ordoneaza lista de melodii descrescator, functie de nr. voturilor // afiseaza lista de melodii } void castigatori(melodie *ptop, persoana *plista, int np){ // se apeleaza functia afiseaza_castigatori pentru cele 4 categorii // metoda are avantajul de a modifica foarte usor parametrii listelor // de exemplu vom putea imparti in 3 grupe de varsta lista // corespunzatoare fiecarui sex doar apeland de 6 ori functia // afiseaza_castigatori }

Program exemplu
Pasul 1
int main() { int npers; melodie * top; persoana * lista=NULL; /* lista persoanelor */ lista=citire(& npers); //citeste datele si le pune in lista afisare_test(lista, npers); top=top_melodii(lista, npers); //topul ordonat al melodiilor castigatori(top, lista, npers); //afiseaza cele 4 liste return 0; }

Program exemplu
Pasul 2
void afisare_test(persoana *plista, int n){ int i,j; for( i=0; i<n; i++ ){ printf("\n persoana %d", i); printf("\n Nume: %s Prenume: %s sex:%c v:%d \n", plista[i ].nume, plista[ i ].prenume, plista[ i ].sex, plista[i ].varsta); for( j=0; j<NMEL; j++ ) printf("%s ",plista[ i ].melodii[ j ]); } }

Program exemplu
Pasul 2
melodie *creaza_lista_melodii(persoana *plista,int n, int *nm){ // creaza o lista cu melodiile si voturile aferente fiecarei melodii } void sorteaza_lista_melodii(melodie *ptop, int nm){ // creaza o lista ordonata descrescator, functie de numarul voturilor, // din lista de melodii primita ca parametru } void afiseaza_top(melodie *ptop,int nm){ // afiseaza lista de melodii primita ca parametru }

Program exemplu
Pasul 2
melodie * top_melodii(persoana *plista, int np){ melodie *ptop; int nmelodii; // creaza o lista cu melodiile si voturile aferente fiecarei melodii ptop=creaza_lista_melodii(plista, np, & nmelodii); // ordoneaza lista de melodii descrescator, functie de nr.voturi sorteaza_lista_melodii(ptop, nmelodii); // afiseaza lista de melodii afiseaza_top(ptop, nmelodii); return ptop; }

Program exemplu
Pasul 2
void afiseaza_castigatori(persoana *plista,int np,melodie * ptop, char sx, int v1, int v2) { // se parcurge lista de persoane plista si se afiseaza // persoanele cu sexul sx si varsta cuprinsa intre v1 si v2, // adica plista[i].sex==sx si v1<=lista[i].varsta<=v2 (pseudocod) }

Program exemplu
Pasul 2
void castigatori(melodie *ptop, persoana *plista, int np) { afiseaza_castigatori(plista,np,ptop,'f',1,19); afiseaza_castigatori(plista,np,ptop,'f', 20,150); afiseaza_castigatori(plista,np,ptop,'m',1,19); afiseaza_castigatori(plista,np,ptop,'m', 20,150); /* o alta metoda consta in parcurgerea listei de persoane o singura data, si crearea in acest timp a celor 4 liste mai mici, pe care sa le afisam ulterior*/ }

Concluzii
1. Dezvoltarea programelor const ntr-o succesiune de pai de rafinare. La fiecare pas o operaie complex este descompus ntr-un numr de operaii mai simple. Fiecare rafinare la nivelul unei operaii poate fi nsoit de o rafinare a structurilor de date aferente, datele fiind cele care realizeaz interaciunea dintre (sub)operaii. Rafinarea descrierii operaiilor i a structurilor de date trebuie s se realizeze n paralel. 2. Gradul de modularitate obinut va determina uurina sau dificultatea cu care programul va putea fi adaptat la modificrile i extensiile ulterioare, inclusiv la schimbarea mediului de execuie (limbaj de programare, sistem de operare, platform hardware).

Concluzii
3. Pe parcursul rafinrilor succesive vor fi folosite mai multe notaii. Este recomandabil ca notaia iniial, care deriv din natura problemei de rezolvat, s fie meninut ct mai mult cu putin. Direcia n care va evolua notaia, pe parcursul rafinrilor, depinde, n ultim instan, de limbajul de programare n care va fi scris programul n variant final. Notaia final se identific cu limbajul de programare ales pentru implementarea programului. De aceea, limbajul de programare trebuie s permit exprimarea ct mai clar i natural a structurilor de date i de control care apar n procesul de proiectare.

Concluzii
4. Fiecare pas de rafinare implic luarea unui numr de decizii pe baza unor criterii de performan. Printre aceste criterii se numr : viteza de execuie, spaiul de memorie necesar rulrii, claritatea codului, uniformitatea structurilor etc. Programatorul trebuie s fie consecvent n ceea ce privete luarea acestor decizii, trebuie s cntreasc cu atenie toate aspectele i s fie pregtit s revin asupra unor decizii anterioare, chiar dac aceasta nseamn s reia proiectarea de la nceput.

Preprocesorul
Preprocesarea este o faz care precede compilarea. Preprocesorul limbajului C este relativ simplu i n principiu execut substituii de texte. Prin intermediul lui se realizeaz: - Includeri de fiiere surs (antet); - Macrodefiniii; - Compilare condiionat. Directivele de preprocesare au caracterul # la nceput de linie.

Preprocesorul
Includerea de fiiere antet
O directiv #include este nlocuit n timpul preprocesrii cu coninutul integral al fiierului specificat, care se insereaz n locul ei. Forma directivei include este #include "nume_de_fisier" sau #include <nume_de_fisier> Diferena ntre cele dou moduri de scriere este urmtoarea: dac numele fiierului de inclus este dat ntre ghilimele, preprocesorul caut fiierul pornind de la directorul curent. Dac fiierul nu e gsit, sau dac numele este dat ntre paranteze unghiulare, cutarea fiierului se face n continuare dup reguli definite de implementarea compilatorului de C. Un fiier inclus poate conine la rndul su directive #include.

Preprocesorul
Includerea de fiiere antet
Utilizarea directivei #include e o modalitate de a utiliza aceleai declaraii n cazul programelor care sunt mprite pe mai multe fiiere. Dac se modific un fiier inclus, trebuie recompilate toate fiierele care l includ pe acesta, direct sau indirect. Un fiier antet poate conine: definiii de tipuri, declaraii de funcii, declaraii de variabile, definiii de constante, macrodefiniii, alte directive de includere. Un fiier antet bine proiectat nu trebuie s conin definiii de funcii i definiii de date! n principiu un fiier antet poate fi inclus de ctre mai multe module diferite ale aceleiai aplicaii. Dac fiierul antet conine o definiie de funcie sau o definiie de variabil global, prin includerea multipl se realizeaz definirea multipl a acestor entiti, fapt care constituie o eroare.

Preprocesorul
Macrodefiniii
Definirea constantelor simbolice prin directiva #define este un caz particular de macrodefiniie. n general, o macrodefiniie (un macro) are la baz tot operaia de substituie. Un macro are o definiie i poate fi apelat de un numr oarecare de ori. La definirea unui macro se specific de fapt textul care urmeaz a se substitui la fiecare apel al su. Acest text poate fi variabil, n funcie de anumii parametri.

Preprocesorul
Macrodefiniii
Forma general a unei macrodefiniii este: #define nume(p1, p2, ...,pn) text_de_substituit nume = numele macroului p1, p2,... , pn = parametrii macroului text_de_substituit = textul cu care este nlocuit macroul la fiecare apel O definiie poate folosi definiii anterioare. Textul de nlocuit este restul liniei surs; dac se dorete continuarea definiiei pe mai multe linii, la sfritul liniei care urmeaz s fie continuat, se scrie caracterul /. n cazul unei macrodefiniii cu parametri, ntre numele macroului i paranteza deschis nu trebuie s existe spaii .

Preprocesorul
Macrodefiniii
Exemplu: Un macro pentru calculul maximului a dou numere. #define MAX(x,y) ((x)>(y) ? (x) : (y)) Un exemplu simplu de apel al acestui macro este: float a,b,c; c=MAX(a,b); La preprocesare, linia c=MAX(a,b); se nlocuieste cu c=((a) > (b) ? (a) : (b)); Un alt exemplu de apel al macro-ului MAX: int i,j,k; k=MAX(i + j, i - j); La preprocesare, linia k=MAX(i + j, i - j); va fi nlocuit cu k=(i + j) > (i - j) ? (i + j) : (i - j))

Preprocesorul
Macrodefiniii
Exist i anumite pericole legate de utilizarea necorespunztoare a macrodefiniiilor, care pot avea efecte secundare ascunse. Exemple: MAX(i++, j++) va incrementa de dou ori valoarea variabilei care e mai mare, pentru c expandarea macro-ului se face n felul urmtor: (i++) > (j++) ? (i++) : (j++) Macroul de ridicare a unui numr la ptrat #define PATRAT(x) x*x d rezultate eronate n cazul n care este apelat de exemplu pentru x+1: PATRAT(x+1) este expandat n x+1*x+1, ceea ce, avnd n vedere precedena operatorilor, nu calculeaz ptratul expresiei (x+1). Pentru a fi corect un macro de ridicare la ptrat ar trebui scris utiliznd paranteze: #define PATRAT(x) (x)*(x)

Preprocesorul
Macrodefiniii. Exemple
Transformarea unui caracter din liter mic n liter mare: #define UPPER(c) ((c)-a+A) Definirea unui ciclu infinit: #define FOREVER for(;;) Interschimbarea a dou numere ntregi: #define SCHIMBA(X,Y) { int t; t=X; X=Y; Y=t; } Apelul SCHIMBA(a,b) este substituit cu secvena: { int t; t=a; a=b; b=t; } Variabila t exist numai n interiorul instruciunii compuse generat de preprocesor!

Preprocesorul
Macrodefiniii. Exemple
Macrodefiniiile permit parametrizarea unei operaii cu un nume de tip, ceea ce se poate folosi ca o facilitate de realizare a unor funcii generice primitive. Macro-ul de interschimbare a dou elemente poate fi rescris astfel nct s fie parametrizat i cu tipul elementelor: #define SWAP(TIP, X, Y) { TIP t; t=X; X=Y; Y=t; } Macrodefiniia SWAP se poate apela cu parametri de orice tip pe care este definit operaia =. int a, b; SWAP(int, a, b); float x, y; SWAP(float, x, y);

Preprocesorul
Macrodefiniii. Exemple
Macro pentru alocarea dinamic a unui bloc de memorie de n elemente de un anumit tip: #define ALOCA(tip, n) (tip *)malloc(sizeof(tip)*n) void main(void) { int *ip; float *fp; ip=ALOCA(int, 10); fp=ALOCA(float, 10); } Macroexpandarea poate fi oricnd suspendat cu directiva: #undef nume Numele respectiv nu mai este expandat n continuarea fiierului. Definirea unui macro nu se ncheie, de obicei, cu ;.

Preprocesorul
Compilare condiionat
Permite s se aleag dintr-un text general prile care se compileaz mpreun. Se realizeaz folosind construciile #if, #ifdef i #ifndef Se noteaz cu expr o expresie constant (valoarea poate fi evaluat de preprocesor la ntlnirea ei). #if expr text #endif Dac expr are valoarea adevrat atunci text se supune preprocesrii, altfel se continu cu ceea ce urmeaz dup #endif.

Preprocesorul
Compilare condiionat
#if poate avea i ramur de else: #if expr text1 #else text2 #endif Directivele de preprocesare (compilare condiionat) i textul care urmeaz s fie inclus sau nu n programul pentru compilare se dau pe linii de text separate.

Preprocesorul
Compilare condiionat
n interiorul unei directive #if, expresia defined(nume) are valoarea 1 dac nume a fost deja definit de o directiv define, sau 0 n caz contrar. Exemplu: includerea o singur dat a coninutul unui fiier antet antet1.h: #if !defined(ANTET1) #define ANTET1 /* continutul fisierului antet1.h */ #endif

Preprocesorul
Compilare condiionat
Prima includere a fiierului antet1.h definete numele ANTET1. n cazul n care ar mai exista includeri ulterioare, chiar i indirect, prin alte fiiere, preprocesorul vede c numele e deja definit i sare direct la #endif. Aceast facilitate este util n situaii n care un fiier antet ar fi altfel inclus de mai multe ori, direct sau indirect, ca n urmtoarea situaie de exemplu: Se consider un fiier antet a.h i un fiier antet b.h care conine o directiv de includere a lui a.h. Dac un alt fiier main.c conine directive de includere a ambelor fiiere a.h i b.h, rezult c fiierul a.h va fi inclus de dou ori. Aceast includere dubl poate conduce la erori datorit redefinirii unor variabile i constante coninute n a.h.

Preprocesorul
Compilare condiionat
Directivele #ifdef i #ifndef testeaz dac un nume este sau nu este definit. Reluarea exemplului anterior: #ifndef ANTET1 #define ANTET1 /* continutul fisierului antet1.h */ #endif

Preprocesorul
Compilare condiionat
Includerea de fiiere diferite n funcie de anumite variabile sistem: #if SYSTEM==SYSV #define ANTET "sysv.h" #elif SYSTEM==BSD #define ANTET "bsd.h" #elif SYSTEM==MSDOS #define ANTET "msdos.h" #else #define ANTET "default.h" #endif #include ANTET

Preprocesorul
Compilare condiionat
Exemplu - Definirea de tipuri mutual recursive: se consider dou tipuri structurate T1 i T2, fiecare dintre acestea conine un cmp de tip pointer la cellalt tip. typedef struct { T2 a; int b;} *T1; typedef struct { T1 a; int b;} *T2; Se pune problema ordinii corecte n care trebuie s fie definite aceste tipuri. Dac T1 este definit naintea lui T2, compilatorul nu l cunoate pe T2 cnd ntlnete definiia lui T1, care are un cmp (a) de acest tip.

Preprocesorul
Compilare condiionat
Problema exist i invers: dac T2 ar fi definit naintea lui T1. Pentru a rezolva problema referirilor reciproce, se utilizeaz declaraii incomplete de structuri, astfel: typedef struct t_T1 * T1; typedef struct t_T2 * T2; struct t_T1 { T2 a; int b; }; struct t_T2 { T1 a; int b; };

Preprocesorul
Compilare condiionat
Cazul: T1 i T2, sunt definite n fiiere separate t1.h i t2.h: /* fisierul t1.h */ #if !defined(tip_T1) #define tip_T1 typedef struct t_T1 *T1; #include "t2.h" struct t_T1 { T2 a; int b; }; #endif

Preprocesorul
Compilare condiionat
/* fisierul t2.h */ #if !defined(tip_T2) #define tip_T2 typedef struct t_T2 *T2; #include "t1.h" struct t_T2 { T1 a; int b; }; #endif /* fisierul main.c */ #include "t1.h" #include "t2.h" void main() { ----------}

Funcii cu numr variabil de argumente


Este posibil definirea unor funcii care s se apeleze cu un numr variabil de argumente. Funciile de bibliotec printf i scanf sunt din aceast categorie: int scanf(char *format, ...); int printf(char *format, ...); n acest caz, la definirea funciei, lista de parametri conine doar enumerarea primilor parametri, cei care sunt fici, iar ceilali parametri sunt specificai prin puncte de suspensie: ... . Funciile de acest gen folosesc i interpreteaz de obicei informaia transmis prin argumentele obligatorii pentru a ti cte argumente exist efectiv n apel i care sunt tipurile acestora, n maniera n care printf i scanf interpreteaz formatul.

Funcii cu numr variabil de argumente


Referirea valorilor argumentelor variabile nu se poate face n mod direct, deoarece aceste argumente nu au nite nume corespondente n lista parametrilor. Problema numrului variabil de argumente i a corespondenei tipurilor acestora cu tipurile parametrilor, trebuie s fie tratat de ctre programator; compilatorul nu dispune de nici o informaie pentru a verifica apelurile. Exist un set de funcii (de fapt macrodefiniii) declarate n stdarg.h relative la listele cu un numr variabil de argumente. n acest sens avem tipul va_list i funciile va_start, va_arg i va_end. Tipul va_list descrie un pointer ctre lista de argumente. n funcia definit de programator se va declara o variabil local de acest tip, necesar pentru adresarea argumentelor.

Funcii cu numr variabil de argumente


Funcia va_start primete ca argumente variabila de tip va_list i numele ultimului parametru fix al funciei. Ea realizeaz iniializarea variabilei de tip va_list cu adresa primului argument variabil. va_start(va_list ap, ultim_fix); Funcia va_arg ntoarce valoarea argumentului urmtor, dintre cei variabili: tip_par va_arg(va_list ap, tip_par); La primul apel, va_arg returneaz primul argument dintre cei variabili, apoi la fiecare nou apel returneaz urmtorul argument. Tipul argumentului se specific prin tip_par. Se aplic conversii implicite pentru transferul valorilor din partea variabil, valorile transferate fiind ntotdeauna extinse la tipurile int i double. Funcia va_end realizeaz operaiile necesare ncheierii funciei i trebuie apelat nainte de revenirea din funcie.

Funcii cu numr variabil de argumente - Exemplu


S se scrie o funcie care poate primi un numr oarecare de argumente de tipuri diferite, ale cror valori le afieaz. Primul parametru al funciei este un parametru fix, de tip ir de caractere, cu rolul de a descrie tipurile parametrilor care urmeaz, aprox. n maniera formatului din printf. Fiecare caracter din acest ir specific tipul unui parametru. Caracterele i tipurile permise sunt: d = ntreg, r = real, c = caracter, s= ir. De exemplu, dac irul este ddrcd, nseamna c funcia va avea 5 parametri, dintre care primii doi de tip ntreg, urmtorul real, urmtorul caracter i ultimul ntreg. Funcia func din secvena urmtoare realizeaz acest lucru:

Funcii cu numr variabil de argumente - Exemplu


#include <stdio.h> #include <stdarg.h> void func(char *msg, ...) { char c; int va_d; char va_c; double va_r; char * va_s; int count=0; va_list ap; va_start(ap, msg);

Funcii cu numr variabil de argumente - Exemplu


while((c=*msg++)!='\0') switch(c) { case 'd': va_d=va_arg(ap, int); count++; printf("Parametrul nr %d este de tip intreg" " si are valoarea %d \n", count, va_d); break; case 'r': va_r=va_arg(ap, double); count++; printf("Parametrul nr %d este de tip real" " si are valoarea %lf \n", count, va_r); break;

Funcii cu numr variabil de argumente - Exemplu


case 'c': va_c=va_arg(ap, char); count++; printf("Parametrul nr %d este de tip caracter" " si are valoarea %c \n", count, va_c); break; case 's': va_s=va_arg(ap, char *); count++; printf("Parametrul nr %d este sir de caractere" " si are valoarea %s \n", count, va_s); break; default: printf("Tipul specificat este eronat !\n"); break; } va_end(ap); }

Funcii cu numr variabil de argumente - Exemplu


Funcia func definit anterior poate fi apelat ca n secvena urmtoare: int main(void) { int n=7; double x=5.5; func("ddrd", 5, n, x, 5+1); /* corect */ func("cds", 'x',34,"abc"); /* corect */ func("cds","abc",5.5, 33); /* rezultate eronate ! */ return 0; } Primele dou forme de apel sunt corecte. Al treilea apel d rezultate eronate, pentru c argumentele nu sunt de tipurile ateptate.

S-ar putea să vă placă și