Sunteți pe pagina 1din 32

Programarea calculatoarelor

Limbajul C

CURS 10
Pointeri la funcii Fiiere text

Pointeri la funcii
Problem: funcie care s poat apela o funcie cu nume necunoscut, dar cu prototip i efect cunoscut. Exemple:
Funcie care s sorteze un vector tiind funcia de comparare a dou elemente ale unui vector. Funcie care s determine o rdcin real a oricrei ecuaii (neliniare). Funcie "listf" care poate afia (lista) valorile unei alte funcii cu un singur argument, ntr-un interval dat i cu un pas dat.

int main () { listf (sin, 0., 2*M_PI, M_PI/10.); listf (exp,1., 20., 1.); return 0; }
Programarea calculatoarelor

Observaii
Prin convenie, n limbajul C, numele unei funcii nensoit de o list de argumente (chiar vid) este interpretat ca un pointer ctre funcia respectiv (fr a se folosi operatorul de adresare '&')! "sin" este adresa funciei "sin(x)" n apelul funciei "listf". O eroare de programare care trece de compilare i se manifest la execuie este apelarea unei funcii fr paranteze; compilatorul nu apeleaz funcia i consider c programatorul vrea s foloseasc adresa funciei! Exemplu: if ( test ) break; // gresit, echiv. cu if (1) break; if ( test() ) break; // iesire din ciclu daca funcia test intoarce true

Programarea calculatoarelor

Declarare pointeri la funcii


Declararea unui argument formal (sau unei variabile) de tip pointer la o funcie are forma urmtoare: tip (*pf) (lista_arg_formale) unde: pf este numele argumentului (variabilei) pointer la funcie tip este tipul rezultatului funciei

Definirea funciei "listf": void listf (double (*fp)(double), double min, double max, double pas) { double x, y; for (x=min; x<=max; x=x+pas) { y=fp(x); // sau: y=(*fp)(x); printf ("\n%20.10lf %20.10lf, x, y); } }
Programarea calculatoarelor

Observaii
Parantezele sunt importante, deoarece absena lor modific interpretarea declaraiei: Declaraie funcie cu rezultat pointer, nu pointer la funcie!! tip * f (lista_arg_formale) Pentru a face programele mai explicite se pot defini nume de tipuri pentru tipuri pointeri la funcii, folosind declaraia typedef. typedef double (* ftype) (double); void listf (ftype fp, double min, double max, double pas) { double x, y; for (x=min; x<=max; x=x+pas) { y = fp(x); printf ("\n%20.10lf %20.10lf, x,y); } }
Programarea calculatoarelor

Funcii callback
O funcie C transmis, printr-un pointer, ca argument unei alte funcii F se numete i funcie callback, pentru c ea va fi apelat napoi de funcia F. De obicei, funcia F este o funcie de bibliotec, iar funcia C este parte din aplicaie. Funcia F poate apela o diversitate de funcii, dar toate cu acelai prototip, al funciei C.
Programarea calculatoarelor

Exemplu
program cu meniu de opiuni; operatorul alege una din funciile realizate de programul respectiv:
#include<stdio.h> #include<stdio.h> typedef void (*funPtr) (); // funcii ptr. operatii realizate de program void unu () { printf ("unu\n"); } void doi () { printf ("doi\n"); } void trei () { printf ("trei\n"); }
Programarea calculatoarelor

Exemplu - continuare
// selectare i apel funcie int main () { funPtr tp[ ]= {unu,doi,trei}; // vector de pointeri la funcii short option=0; do { printf(Optiune (1/2/3):); scanf ("%hd", &option); if (option >=1 && option <=3) tp[option-1](); // apel funcie (unu/doi/trei) else break; } while (1); return 0; }

Programarea calculatoarelor

Exemplu - observaie
Secvena echivalent (cu switch) este : do { printf(Optiune (1/2/3):); scanf ("%hd", &option); switch (option) { case 1: unu(); break; case 2: doi(); break; case 3: trei(); break; } } while (1);
Programarea calculatoarelor

Directive preprocesor
sunt interpretate ntr-o etap preliminar compilrii (traducerii) textului C, de un preprocesor nu se foloseste caracterul ; pentru terminarea unei directive! #define ident text inlocuiete toate apariiile identificatorului ident prin irul text #define ident (a1,a2,...) text definete o macroinstructiune cu argumente #include fiier include n compilare coninutul fiierului sursa fiier #if expr compilare condiionat de valoarea expresiei expr #if defined ident compilare condiionat de definirea unui identificator (cu #define) #endif terminarea unui bloc introdus prin directiva #if
Programarea calculatoarelor

Fiier
Colecie de date memorate pe un suport extern (floppy, harddisk, etc) identificat printr-un nume. Entiti ale sistemului de operare: numele lor respect conveniile sistemului, fr legtur cu un limbaj de programare anume Coninutul:
texte (ex. programe surs) numere alte informaii binare: programe executabile, numere n format binar, imagini sau sunete codificate numeric s.a.

Numrul de elemente ale unui fiier este variabil (poate fi nul). Se folosesc pentru
date iniiale sau rezultate mai numeroase pstrarea permanent a unor date de interes pentru anumite aplicaii
Programarea calculatoarelor

Operarea cu fiiere
De obicei "fiier" = fiier disc (pe suport magnetic sau optic) Noiunea de fiier este mai general i include orice flux de date (stream) din exterior spre memorie sau dinspre memoria intern spre exterior. Stream (flux de date, canal) sinonim cu file (fiier): pune accent pe aspectul dinamic al transferului de date Programatorul se refer la un fiier printr-o variabil; tipul acestei variabile depinde de limbajul folosit i chiar de funciile utilizate (n C). Asocierea dintre numele extern (un ir de caractere) i variabila din program se face la deschiderea unui fiier, printr-o funcie standard.
Programarea calculatoarelor

Tipuri de fiiere n C
Fiiere text
conin o succesiune de linii, separate prin NewLine fiecare linie are 0 sau mai multe caractere tipribile i/sau tab

Fiiere binare
conin o succesiune de octei

Programarea calculatoarelor

Fiiere text
Caracter terminator de linie: fiierele Unix/Linux: un singur caracter terminator de linie \n fiierele Windows i MS-DOS: caracterele \r i \n (CR,LF) ca terminator de linie Un fiier text poate fi terminat printr-un caracter terminator de fiier (Ctrl-Z = EOF = -1) nu este obligatoriu acest terminator Sfritul unui fiier disc poate fi detectat i pe baza lungimii fiierului (numr de octei), memorat pe disc. Se realizeaz conversia automat din/n format extern (ir de caractere) n/din format intern (binar virgul fix sau virgul mobil)
Programarea calculatoarelor

Fiiere binare
Pot conine
numere n reprezentare intern (binar) articole (structuri de date) fiiere cu imagini grafice, n diverse formate, etc

Citirea i scrierea se fac fr conversie de format. Pentru fiecare tip de fiier binar este necesar un program care s cunoasc i s interpreteze corect datele din fiier (structura articolelor). Este posibil ca un fiier binar s conin numai caractere, dar funciile de citire i de scriere pentru aceste fiiere nu cunosc noiunea de linie; ele specific un numr de octei care se citesc sau se scriu la un apel al funciei fread sau fwrite.
Programarea calculatoarelor

Operarea cu fiiere
1. se definete o variabil de tip FILE * pentru accesarea fiierului; FILE * un tip structur definit n stdio.h conine informaii referitoare la fiier i la tamponul de transfer de date ntre memoria central i fiier (adresa, lungimea tamponului, modul de utilizare a fiierului, indicator de sfrit, de poziie n fiier) 2. se deschide fiierul pentru un anumit mod de acces, folosind funcia de biblioteca fopen, care realizeaz i asocierea ntre variabila fiier i numele extern al fiierului 3. se prelucreaz fiierul - citire/scriere cu funciile specifice 4. se nchide fiierul folosind funcia de biblioteca fclose.
Programarea calculatoarelor

Deschiderea unui fiier


FILE *fopen(const char *numefiier, const char *mod); Deschide fiierul cu numele dat pentru acces de tip mod Returneaz pointer la fiier sau NULL dac fiierul nu poate fi deschis Valoarea returnat este memorat n variabila fiier, care a fost declarat (FILE *) pentru accesarea lui. numefis: numele fiierului mod: ir de caractere (ntre 1 i 3 caractere):
"r" - readonly , este permis doar citirea dintr-un fiier existent "w" - write, creaz un nou fiier, sau dac exist deja, distruge vechiul coninut "a" - append, deschide pentru scriere un fiier existent (scrierea se va face n continuarea informaiei deja existente n fiier, deci pointerul de acces se plaseaz la sfritul fiierului) + = permite scrierea i citirea din acelasi fiier - actualizare (ex: "r+", "w+", "a+"). "t" sau "b" = tip fiier ("text", "binary"), implicit este "t
Programarea calculatoarelor

Nume fiier extern


Poate include urmtoarele:
Numele unitii de disc sau partiiei disc ( ex: A:, C:, D:, E:) "Calea" spre fiier: succesiune de nume de fiiere catalog (director), separate printr-un caracter ('\' n MS-DOS i MSWindows, sau '/' n Unix i Linux) Numele propriu-zis al fiierului Extensia, care indic tipul fiierului i care poate avea ntre 0 i 3 caractere n MS-DOS.

Sistemele MS-DOS i MS-Windows nu fac deosebire ntre litere mari i litere mici, n cadrul numelor de fiiere Atenie! pentru separarea numelor de cataloage dintr-o cale se vor folosi:
"\\", pentru a nu se considera o secven de caractere "Escape" sau caracterul /. char *numef = "C:\\WORK\\T.TXT"; char *numef = c:/work/t.txt;
Programarea calculatoarelor

nchiderea unui fiier


int fclose(FILE *fp);
nchide fiierul i elibereaz zona tampon n caz de succes ntoarce 0. altfel, ntoarce EOF.

Atenie!
nchiderea unui fiier disc este absolut necesar pentru fiierele n care s-a scris ceva! Poate lipsi dac s-au fcut doar citiri din fiier!
Programarea calculatoarelor

Exemplu
#include <stdio.h> int main ( ) { FILE * f; // pentru referire la fiier // deschide un fiier text ptr citire f = fopen ( c:\\t.txt", "rt ); printf ( f == NULL ? "Fiier negasit" : " Fiier gasit"); if (f) // dac fiier existent fclose(f); // nchide fiier return 0; }
Programarea calculatoarelor

Prelucrarea fiierelor text


se poate face fie la nivel de linie, fie la nivel de caracter:
int fgetc (FILE *fp) ntoarce urmtorul caracter din fp ca un unsigned char convertit la int, sau EOF dac s-a ntlnit sfritul de fiier sau n caz de eroare. char *fgets (char *s, int n, FILE *fp) citete maxim n-1 caractere sau pn la '\n' inclusiv, i le depune n s, adaug la sfrit '\0' i returneaz adresa irului. La eroare ntoarce valoarea NULL. int fputc(int c,FILE *fp) scrie caracterul cu codul ascii c n fiier int fputs(char *s,FILE *fp) scrie irul n fiier, fara caracterul '\0'. La eroare ntoarce EOF.
Programarea calculatoarelor

Exemplu: citire i afiare linii dintr-un fiier


#include<stdio.h> #include<stdlib.h> int main() { FILE *fp; char s[80]; if ( (fp=fopen("c:\\test.c","r")) == NULL ) { printf ( "Nu se poate deschide la citire fiierul!\n ); exit (1); } while ( fgets(s,80,fp) != NULL ) printf ( "%s", s); fclose (fp); return 0; }
Programarea calculatoarelor

Exemplu: scriere sub form de litere mici caracterele dintr-un fiier n alt fiier
numele sursei i destinaiei transmise n linia de comand. #include<stdio.h> #include<ctype.h> int main(int argc, char** argv){ FILE * f1, * f2; int ch; f1= fopen (argv[1], "r"); f2= fopen (argv[2], "w"); if ( f1==0 || f2==0) { puts (" Eroare la deschidere fiiere \n"); return 1;} while ( (ch=fgetc(f1)) != EOF) // citeste din f1 fputc ( tolower(ch),f2); // scrie n f2 fclose(f1); fclose(f2); return 0; } Lansarea n execuie a programului: copiere fiier_sursa.dat fiier_dest.dat
Programarea calculatoarelor

Intrri/ieiri cu conversie de format


Datele numerice pot fi scrise n fiiere disc n format intern, binar (mai compact) transformate n iruri de caractere (cifre zecimale, semn .a): fiier text ocup mai mult spaiu Formatul ir de caractere necesit i caractere separator ntre numere, dar poate fi citit cu programe scrise n orice limbaj sau cu orice editor de texte sau cu alt program utilitar de vizualizare fiiere!

int fprintf (FILE *fp, const char *format,...) identic cu printf cu deosebirea c scrie ntr-un fiier. int fscanf (FILE *fp, const char *format,...) realizeaz citirea cu format dintr-un fiier; analog scanf Exemplu: int a; float b; fscanf ( fp, %d%f ,&a, &b); fprintf ( fp, a= %d \t b=%f \n, a, b);
Programarea calculatoarelor

Testare sfrit de fiier


int feof(FILE *fp) testeaz dac s-a ajuns la end-of-file al fiierului referit de fp returneaz 0 dac nu s-a detectat sfrit de fiier la ultima operaie de citire, respectiv o valoare nenul (adevarat) pentru sfrit de fiier. Atenie! Se va scrie n fiierul de ieire i 1 - rezultatul ultimului apel al funciei fgetc: while ( ! feof(f1)) fputc(fgetc(f1),f2); Soluia preferabil pentru ciclul de citire-scriere caractere este testarea rezultatului funciei de citire: while ( (ch=fgetc(f1)) != EOF) fputc ( ch, f2);

Programarea calculatoarelor

Exemplu
ntr-un fiier de tip text sunt pstrate valorile reale ale unei msuratori sub forma:
nr_msuratori val1 val2 val3 ...

A) S se scrie programul care afieaz numrul de msurtori i valorile respective. B) Se vor aduga la fiier noi msuratori pn la introducerea valorii 0.
Programarea calculatoarelor

Rezolvare
# include <math.h> # include <stdio.h> # include <stdlib.h> # include <ctype.h> # define MAX 100

void afiseaza(double *mas,int nrm){ int i; for (i=0; i<nrm; i++) printf ("Masuratoarea %d = %6.2e\n", i+1, mas[i]); }
void loadmas (FILE *fp, int *nrm, double *mas){ int i=0; fscanf (fp,"%d", nrm); if (*nrm>MAX) *nrm = MAX; for ( ; i<*nrm; i++) fscanf (fp, "%lf", &mas[i]); Programarea calculatoarelor }

Rezolvare
int main(){ FILE *fp; double masur[MAX], mas_noua=1; char nume_fis[12]; int nr_mas; printf ("nume fisier:"); gets (nume_fis); if ( (fp = fopen(nume_fis, "r+") ) == 0 ){ printf ("nu exista fisierul\n"); exit (1); } loadmas (fp,&nr_mas,masur); afiseaza (masur,nr_mas); fclose(fp); if ( (fp = fopen(nume_fis, a") ) == 0 ){ printf ("nu exista fisierul\n"); exit (1); }
Programarea calculatoarelor

Rezolvare
printf ("\nmasuratori noi:\n); while( nr_mas++<MAX-1){ scanf(%lf,&mas_noua); if(mas_noua) fprintf (fp, "%lf\n", mas_noua); else break; } fclose(fp); if ( (fp = fopen(nume_fis, "r+") ) == 0 ){ printf ("nu exista fisierul\n"); exit (1); } fprintf (fp, "%d", --nr_mas); fclose (fp); return 0; }
Programarea calculatoarelor

Exerciii
Program pentru numrarea liniilor i cuvintelor dintr-un fiier text printr-o singura parcurgere. Cuvintele sunt iruri de orice caractere separate ntre ele prin (oricte) spaii albe. Hint: Se poate folosi funcia de biblioteca "strtok".

Programarea calculatoarelor

Rezolvare tema
//converteste de la sir de caractere la nr real dubla precizie

double convf (char *s) { double val=0.0, putere; int i=0,semn; while ( isspace(s[i]) ) i++; semn = (s[i]=='-')?-1:1; if (s[i]=='+ || s[i]=='- ) i++; for ( val=0.0; isdigit(s[i]); i++) val = 10*val + s[i]-'0;
Programarea calculatoarelor

Rezolvare tema
if (s[i]=='.') { i++; for (putere=1.0; isdigit(s[i]); i++) { val = val + (s[i]-'0)/putere; putere *= 10; } } /*sfirsit parte zecimala*/ val *= semn; return val; }
Programarea calculatoarelor

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

  • Grile Mcs
    Grile Mcs
    Document8 pagini
    Grile Mcs
    A_N_D_A_89
    Încă nu există evaluări
  • Grile Chirurgie Pediatrica Marie Curie
    Grile Chirurgie Pediatrica Marie Curie
    Document9 pagini
    Grile Chirurgie Pediatrica Marie Curie
    Elena-Dana Oprea
    100% (1)
  • Curs 13
    Curs 13
    Document55 pagini
    Curs 13
    Radu Guran
    Încă nu există evaluări
  • Favorite Desserts Cookbook Final 03
    Favorite Desserts Cookbook Final 03
    Document31 pagini
    Favorite Desserts Cookbook Final 03
    Codruţa Emanuela Maria Vîrşescu
    Încă nu există evaluări
  • Calea Acidului Glucuronic
    Calea Acidului Glucuronic
    Document1 pagină
    Calea Acidului Glucuronic
    carmen_radulescu_14
    Încă nu există evaluări
  • NEUROVIROZE
    NEUROVIROZE
    Document9 pagini
    NEUROVIROZE
    Codruţa Emanuela Maria Vîrşescu
    Încă nu există evaluări
  • Reflexe Osteotendinoase
    Reflexe Osteotendinoase
    Document3 pagini
    Reflexe Osteotendinoase
    Codruţa Emanuela Maria Vîrşescu
    Încă nu există evaluări
  • Subiecte Sem 2 Biochimie
    Subiecte Sem 2 Biochimie
    Document35 pagini
    Subiecte Sem 2 Biochimie
    Codruţa Emanuela Maria Vîrşescu
    Încă nu există evaluări
  • NEUROVIROZE
    NEUROVIROZE
    Document9 pagini
    NEUROVIROZE
    Codruţa Emanuela Maria Vîrşescu
    Încă nu există evaluări
  • LEHUZIA
    LEHUZIA
    Document25 pagini
    LEHUZIA
    Codruţa Emanuela Maria Vîrşescu
    Încă nu există evaluări
  • Curs Neuromuscular
    Curs Neuromuscular
    Document47 pagini
    Curs Neuromuscular
    Camelia Lențoiu
    Încă nu există evaluări
  • Comele Si HIC
    Comele Si HIC
    Document19 pagini
    Comele Si HIC
    Stancu Oana Ruxandra
    Încă nu există evaluări
  • Reflexe Osteotendinoase
    Reflexe Osteotendinoase
    Document3 pagini
    Reflexe Osteotendinoase
    Codruţa Emanuela Maria Vîrşescu
    Încă nu există evaluări
  • Listata - Radu Vladareanu-Obstetrica Si Ginecologie Clinica
    Listata - Radu Vladareanu-Obstetrica Si Ginecologie Clinica
    Document518 pagini
    Listata - Radu Vladareanu-Obstetrica Si Ginecologie Clinica
    Adriana Micle
    100% (4)
  • Incompatibilități RH
    Incompatibilități RH
    Document40 pagini
    Incompatibilități RH
    Codruţa Emanuela Maria Vîrşescu
    Încă nu există evaluări
  • Fisurile Labiale Si Palatine
    Fisurile Labiale Si Palatine
    Document7 pagini
    Fisurile Labiale Si Palatine
    Codruţa Emanuela Maria Vîrşescu
    Încă nu există evaluări
  • Astmul Bronsic
    Astmul Bronsic
    Document25 pagini
    Astmul Bronsic
    silvia_buru
    Încă nu există evaluări
  • Invaginatie de Intestin
    Invaginatie de Intestin
    Document28 pagini
    Invaginatie de Intestin
    teodora4you
    Încă nu există evaluări
  • Diagnostic TB Nasta
    Diagnostic TB Nasta
    Document9 pagini
    Diagnostic TB Nasta
    Codruţa Emanuela Maria Vîrşescu
    Încă nu există evaluări
  • Fiziologia Şi Fiziopatologia Respiraţiei
    Fiziologia Şi Fiziopatologia Respiraţiei
    Document14 pagini
    Fiziologia Şi Fiziopatologia Respiraţiei
    Martoiu Maria
    Încă nu există evaluări
  • Epitelial Curs 1
    Epitelial Curs 1
    Document23 pagini
    Epitelial Curs 1
    Codruţa Emanuela Maria Vîrşescu
    Încă nu există evaluări
  • Sta Zele
    Sta Zele
    Document34 pagini
    Sta Zele
    Grigore Alexandra
    Încă nu există evaluări
  • Tromboza Infarct
    Tromboza Infarct
    Document63 pagini
    Tromboza Infarct
    Grigore Alexandra
    Încă nu există evaluări
  • 1 Hematopoieza
    1 Hematopoieza
    Document13 pagini
    1 Hematopoieza
    Andu Teo Dana
    Încă nu există evaluări
  • C3 Hormoni
    C3 Hormoni
    Document43 pagini
    C3 Hormoni
    Codruţa Emanuela Maria Vîrşescu
    Încă nu există evaluări
  • Antidiareice
    Antidiareice
    Document2 pagini
    Antidiareice
    Rachid Issa
    100% (2)
  • Microtubulii 2 Umfcd
    Microtubulii 2 Umfcd
    Document13 pagini
    Microtubulii 2 Umfcd
    Codruţa Emanuela Maria Vîrşescu
    Încă nu există evaluări
  • Histologie-Lp8 Hematopoieza
    Histologie-Lp8 Hematopoieza
    Document36 pagini
    Histologie-Lp8 Hematopoieza
    lari_83
    Încă nu există evaluări
  • Curs 4
    Curs 4
    Document30 pagini
    Curs 4
    Robert Shaw
    Încă nu există evaluări
  • Ter More Glare A
    Ter More Glare A
    Document34 pagini
    Ter More Glare A
    Codruţa Emanuela Maria Vîrşescu
    Încă nu există evaluări