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);

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

}
va_end(pa);

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.

Sunt posibile dou alternative:


substituie textual simpl

#define NUME text


2.

substituie cu argumente

#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

char mesaj[]=MAX este 100;

/* aici nu se face!

*/

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

#define TEST(x,n) ((x)&(1<<(n)))


Numrul de elemente al unui tablou se poate calcula cu macroinstruciunea:
#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.

Definii o macroinstruciune care interschimb dou valori de orice tip.

2.

Definii macroinstruciuni pentru transformarea literelor mici n litere mari i invers.

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