Sunteți pe pagina 1din 8

Parametrii liniei de comand in C si C++ Un program executabil (o comand) poate fi lansat n execuie de ctre interpretorul de comenzi al sistemului de operare.

De exemplu, programul salut.exe care afieaz la terminal mesajul Buna ziua! este o comand fr parametrii, lansat n execuie prin: > salut O comand poate avea i parametri, care apar dup numele comenzii i sunt separai prin spaii libere. De exemplu programul salut.exe ar putea avea un parametru ir de caractere, care s specifice un anumit mesaj, fiind lansat n execuie, n acest caz prin: > salut mesaj Un alt exemplu il constituie un program care copiaz un fiier; acesta ar avea doi parametri, desemnnd fiierele surs i destinaie (iruri de caractere ): > copiere sursa.dat dest.dat Parametrii pot fi specificai nu numai la nivelul liniei de comand, ci i din mediul integrat de dezvoltare C, folosind opiunea Parameters din meniul Run. Programul poate avea acces la parametrii liniei de comand, dac funcia main() prezint argumente: void main(int argc, char *argv[]){ } Primul argument, argc (argumentul contor) este un ntreg care reprezint numrul de parametri ai comenzii. Al doilea argument, argv (argumentul vector) este un pointer la un tablou de pointeri la iruri de caractere, care conin argumentele (cte un argument pe ir de caractere). Prin convenie, argv[0] conine ntotdeauna numele programului, astfel nct pentru o comand fr parametri argc=1, iar o comand cu 2 parametri va avea argc=3. argv[1] conine primul parametru,argv[2] pe cel de-al doilea, argv[c-1] va conine ultimul parametru, iar argv[argc] va fi un pointer la un ir vid (NULL). Astfel pentru comanda copiere exemplificat mai sus avem: argv copiere copiere\0 s sursa.dat\0
dest.dat\0 \0 d

Exemplul S se copieze la ieire fiierele date ca parametri ai comenzii. Dac nu avem parametri se copiaz fiierul standard de intrare (stdin). #include <stdio.h> void copy(FILE *, FILE *); main(int argc, char *argv[]) { FILE *pf; if(argc==1) copy(stdin, stdout); else while(--argc) if((pf==fopen(*++argv,r))==NULL) { fprintf(stderr, Nu putem deschide %s\n, *argv); return 1;

} else { copy(pf, stdout); fclose(pf); } return 0; } void copy(FILE *s, FILE *d) { int c; while((c=getc(s))!=EOF) putc(c, d); } 1. Macroinstruciuni pentru funcii cu numr variabil de parametri. Funciile C pot fi apelate cu numr variabil de parametri actuali. (un exemplu l constituie funciile printf() i scanf() ). Programatorul i poate scrie propriile funcii cu numr variabil de parametri, folosind macroinstruciunile din fiierul antet <stdarg.h>. O funcie cu numr variabil de parametri va avea prototipul: tip nume (list_fix_parametri, ); Lista fix de parametri trebuie s fie nevid, deci numrul de parametri va fi mai mare sau egal cu numrul de parametri fici. Parametrii care sunt n numr variabil sunt convertii implicit ca tip, i anume:

toi ntregii la int

toi realii la double Fiierul antet <stdarg.h> conine definiii pentru tipul va_list. Argumentele variabile vor fi accesate printr-o variabil pointer pa, declarat astfel: va_list pa; Iniializarea pointerului de acces la argumentele variabile -pa se face folosind macroinstruciunea va_start() , indicnd adresa ultimului parametru fix lastarg: va_start(pa, lastarg); Pentru parcurgerea listei de argumente variabile se va folosi macroinstruciunea va_arg(), care actualizeaz pointerul de acces la argumente pa, pentru a indica urmtorul argument int sau double, i ntoarce ca rezultat argumentul curent din lista de parametri variabili: vint=va_arg(pa, int); sau vreal=va_arg(pa, double); Oprirea procesului repetitiv se face folosind informaiile despre parametrii fici (n vrful stivei se va afla pointerul la format). Dup ultimul parametru variabil extras se apeleaz macroinstruciunea: va_end(pa); Exemplul: Scriei o funcie care afieaz un numr variabil de iruri de caractere (cel mult max). #include <stdio.h> #include <stdarg.h> int printvar(int max, ); void main(void)

{ printvar(3,Ion,Vasile,Mihai); printf(\n); printvar(5,marti,joi,luni,vineri,duminica); printf(\n); } void printvar(int max,) { va_list pa; int narg=0; char *siruri[10]; va_start(pa,max); while(narg < max) { siruri[narg]=va_arg(pa, char*); printf(%s \n, siruri[narg++]); } va_end(pa); } Extragerea argumentelor variabile, poate fi fcut, i cu alte funcii, n loc de va_arg(). n acest scop se folosesc funciile: vprintf(), vfprintf() i vsprintf(). Acestea au prototipurile: int vprintf(char * format, va_list pa);

afieaz, sub controlul formatului, la ieirea standard, un numr variabil de argumente, accesate prin pointerul pa ntoarce numrul de octei afiai (rezultat negativ la eroare) Exemplu: #include <stdio.h> #include <stdarg.h> int printvar(char* fmt, ); void main(void) { fmt1[]=%s %s %s\n; printvar(fmt1,Ion,Vasile,Mihai); } void printvar(char* fmt,) { va_list pa; va_start(pa,fmt); vprintf(fmt,pa); va_end(pa); } int vfprintf(FILE * fis, char * format, va_list pa);

afieaz, sub controlul formatului, n fiierul fis, un numr variabil de argumente, accesate prin pointerul pa ntoarce numrul de octei afiai (rezultat negativ la eroare) Exemplu: #include <stdio.h> #include <stdarg.h> #define NUMEFIS fis.dat void printvar(FILE* f, char* fmt, ); void main(void) { FILE* f1; fmt1[]=%s %s %s\n; f1=fopen(NUMEFIS, w);

printvar(f1,fmt1,Ion,Vasile,Mihai); fclose(f1); } void printvar(FILE* f, char* fmt,) { va_list pa; va_start(pa,fmt); vfprintf(f, fmt, pa); va_end(pa); } int vsprintf(char * sir, char * format, va_list pa);

afieaz, sub controlul formatului, n irul de caractere sir, un numr variabil de argumente, accesate prin pointerul pa Exemplu: #include <stdio.h> #include <stdarg.h> int printvar(char* s, char* fmt, ); void main(void) { fmt1[]=%s %s %s\n; char s[100]; printvar(s, fmt1, Ion,Vasile,Mihai); printf(%s,s); } void printvar(char* s, char* fmt,) { va_list pa; va_start(pa,fmt); vsprintf(s,fmt,pa); va_end(pa); } Exemplul : Scriei o funcie cu numr variabil de parametri, care simuleaz funcia printf(), acceptnd parametri variabili de tip int, double sau ir de caractere. #include <stdio.h> #include <stdarg.h> void printvar(char* fmt,) { va_list pa; char *p, *psir; int i; double d; va_start(pa,fmt); for (p=fmt; *p; p++) { if(*p!=%){ putchar(*p); continue; } switch(*++p) { case d: i=va_arg(pa, int); printf(%d,i); break; case f: d=va_arg(pa, double); printf(%lf,d);

} va_end(pa);

break; case s: for (psir=va_arg(pa,char*);*psir;psir++) putchar(*psir); break; default: putchar(*p); break; }

2. Probleme propuse. 1. Scriei un program care evalueaz o expresie dat prin linia de comand sub form polonez invers. Fiierul executabil are numele expresie, iar termenii i operatorii apar ca parametri. De exemplu: expresie 3 5 12 + * desemneaz expresia (3 + 5) * 12 care va fi evaluat ca 96. 2. Scriei un program care afieaz ultimele n linii ale fiierului de intrare. Programul poate avea un parametru n, specificat sub forma: ultime n In caz c programul este lansat fr parametri, se consider n mod implicit c n=10. 3. Scriei un program care calculeaz i afieaz cmmdc a mai multor numere naturale. Numerele sunt date:

n fiierul standard de intrare, caz n care programul este lansat n execuie fr parametri: cmmdc n linia de comand, ca argumente: cmmdc 36 48 18 72 54 ntr-un fiier de intrare, a crui nume apare ca argument al liniei de comand sub forma: cmmdc nume.dat

Preprocesorul. Preprocesarea este o faz premergtoare compilrii. Comenzile preprocesorului se numesc directive . Principalele funcii ale preprocesorului se refer la:

Definirea de constante simbolice Definirea de macroinstruciuni Includerea de fiiere Compilarea condiional Directivele preprocesorului: ncep n coloana 1 prin # se continu pe linia urmtoare cu \ pot fi incluse unele n altele

1. Definirea de constante simbolice: #define PI 3.14159265 #define MAX 100 2. Substituirea textual (definirea de macroinstruciuni) 1. 2. Sunt posibile dou alternative: substituie textual simpl substituie cu argumente

#define NUME text #define NUME(arg1, arg2,,argn) text Expandarea in-line a macrourilor este mai rapid dect apelul de funcie, dar prezint dezavantajul creterii dimensiunii programului n cazul unor substituiri repetate. Substituirea textual nu se efectueaz:

n interiorul irurilor de caractere /* aici nu se face! */

char mesaj[]=MAX este 100; n interiorul identificatorilor

int MAXIM=25; /* nici aici nu se face!

*/

Dac numele apare i n textul extins, atunci dezvoltarea se face o singur dat i nu n mod recursiv. Astfel: #define MAX MAX 100 nu se expandeaz dect o singur dat. Un nume existent poate fi folosit pentru definirea altui macro. Astfel pentru substituiile: #define UNU 1 #define DOI (UNU+UNU) nu putem inversa ordinea directivelor. n cazul definiiilor de macrouri cu argumente, n partea de text se pun argumentele ntre paranteze. Este greit definirea: #define PATRAT(x) x*x deoarece PATRAT(y+1) ar genera y+1*y+1, n timp ce: #define PATRAT(x) (x)*(x) genereaz pentru PATRAT(y+1) textul (y+1)*(y+1). Dac n textul de nlocuire un argument este precedat de #, la expandare va apare ntre ghilimele. Astfel pentru macrodefiniia: #define afisare(expr) printf(#expr =%g\n, expr( afisare(x/y) genereaz printf(x/y=%g\n, x/y) Vom da acum cteva macrodefiniii utile n lucrul cu bii:

setarea bitului n din x la 1

#define SET(x,n) ((x)|=(1<<(n))) punerea bitului n din x pe 0

#define RESET(x,n) ((x)&=~(1<<(n)))

testul bitului n din x Numrul de elemente al unui tablou se poate calcula cu macroinstruciunea:

#define TEST(x,n) ((x)&(1<<(n))) #define NELEM(A) )sizeof(A) / sizeof(A[0]) Pentru o substituie textual care ocup mai multe linii, la sfritul fiecrei linii care se continu se pune \ . Astfel: #define SWAP(A,B) {\ long t; \ (t)=(A);\ (A)=(B);\ (B)=(t);\ } Ca restricii menionm:

macrourile nu se pot apela din alt limbaj de programare nu exist pointeri la macrouri nu toate funciile pot fi convertite n macrouri. 3. Includerea de fiiere. Directiva de includere copiaz fiierul text menionat n textul programului, n punctul n care

apare. Fiierul inclus se poate afla n acelai director cu textul programului, situaie n care directiva de includere are forma: #include nume Dac fiierul inclus se afl ntr-un director special, pentru a dirija cutarea ctre acest director se folosete directiva: #include <nume> Un fiier inclus poate include la rndul lui alte fiiere. Includerea de fiiere surs se folosete ca mecanism de legare a programelor mari. n programele C se include de obicei fiiere antet (cu extensia .h); acestea se afl ntr-un director cu numele INCLUDE al mediului de programare C i conin declaraii de prototipuri ale unor funcii de bibliotec, definiri de tipuri, etc. Astfel fiierul antet <stdio.h> conine prototipurile tuturor funciilor folosite n operaiile de intrare / ieire. 4. Compilarea condiionat. Compilarea condiional ne permite ca dintr-un text dat s selectm numai anumite pri care s fie compilate. O serie de directive ne permit s efectum verificri condiionale asupra unor expresii constante sau asupra valori definite. Un identificator devine definit dac apare ntr-o directiv #define nume, sau poate fi fcut nedefinit prin #undef nume. Putem testa dac un simbol este sau nu definit i n funcie de aceasta putem insera text (secvene de instruciuni), care s fie compilat, conform uneia din variantele: Dac expresie are valoare diferit de 0 se compileaz textul cuprins ntre #if i #endif #if expresie text #endif

Dac simbolul NUME este definit (nedefinit), atunci se compileaz textul cuprins ntre #if i #endif. #if defined NUME . text. #endif #ifdef NUME text #endif #ifndef NUME . text #endif

O form complet cuprinde ambele alternative ( diferit de zero / zero simbol definit / nedefinit) n funcie de care se compileaz text_1 sau text_2 #if expresie #ifdef NUME text_1 . text_1 #else #else text_2 text_2 #endif #endif Sunt posibile i selecii multiple cu #ifdef, #elif, #else, #endif. Compilarea condiional se folosete pentru evitarea includerii multiple a unui fiier. #ifndef STDIO_H #include <stdio.h> #define _STDIO_H #endif 5. Probleme propuse. 1. 2. Definii o macroinstruciune care interschimb dou valori de orice tip. Definii macroinstruciuni pentru transformarea literelor mici n litere mari i invers.

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