Documente Academic
Documente Profesional
Documente Cultură
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:
{ 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
afieaz, sub controlul formatului, n fiierul fis, un numr variabil de argumente, accesate prin
pointerul pa
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 + *
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:
substituie cu argumente
/* aici nu se face!
*/
n interiorul identificatorilor
*/
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:
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.