Capitolul 4.2. Functii care returneaza non-intregi

Vezi subiectul anterior Vezi subiectul urmator In jos

Capitolul 4.2. Functii care returneaza non-intregi

Mesaj  zooky la data de Mier Mar 18, 2009 12:18 pm

Pina acum, nici unul din programele noastre nu a continut vreo declaratieasupra tipului unei functii. Aceasta deoarece implicit o functie este declarata prin aparitia ei intr-o expresie sau instructiune, ca in:

while (getline(line, MAXLINE) > 0)

Daca un nume care nu a fost declarat apare intr-o expresie si este urmat de o paranteza stinga, el este declarat din context ca fiind un nume de functie. Mai mult, implicit se presupune ca o functie returneaza un int. Deoarece char se transforma in int in expresii, nu e nevoie sa declaram functiile care returneaza char. Aceste prezumtii acopera majoritatea cazurilor, inclusiv toate exemplele noastre de pina acum.
Dar ce se intimpla daca o functie trebuie sa returneze o valoare de alt tip ? Multe functii numerice, ca sqrt, sin, cos returneaza double; alte functii specializate returneaza alte tipuri. Pentru a ilustra modul lor de folosire vom scrie si vom folosi o functie atof(s) care converteste sirul s in echivalentul lui in dubla precizie; atof este o extensie a lui atoi , pentru care am scris in Capitolul 2 si in Capitolul 3; ea minuieste un semn optional si un punct zecimal, precum si prezenta sau absenta atit a partii intregi cit si a partii fractionare.(Aceasta nu este o rutina de conversie de intrari de inaltacalitate; ar lua mult mai mult spatiu decit ne-am propus noi sa folosim).
In primul rind, atof insasi trebuie sa declare tipul valoarii pe care ea o returneaza, deoarece el nu este int. Deoarece float este convertit in double in expresii, nu are nici un rost sa spunem ca atof returneaza un float; putem la fel de bine sa facem uz de precizie suplimentara, sa declaram ca ea returneaza double. Numele tipului precede numele functiei, ca in:

double atof(s) /* converteste sirul s in double */
char s[];
{
double val, power;
int i, sign;
for (i = 0;s[i]== ' ' || s[i]== '\n' || s[i]== '\t';i++)
; /* sare spatiile albe (blanc, tab, linie noua) */
sign = 1;
if (s[i] == '+' || s[i] == '-') /* semnul */
sign = (s[i++] == '+') ? 1 : -1;
for (val = 0; s[i] >= '0' && s[i] <= '9'; i++)
val = 10 * val + s[i] - '0';
if (s[i] == '.')
i++;
for (power = 1; s[i] >= '0' && s[i] <= '9'; i++) {
val - 10 * val + s[i] - '0';
power *= 10;
}
return(sign * val / power);
}


In al doilea rind, si la fel de important, rutina apelanta trebuie sa specifice ca atof returneaza o valoare non-int. Declaratia este arata in urmatorul calculator primitiv de birou (adevarat simplu pentru bilantul de verificare de conturi de carti ?!) care citeste un numar pe linie, precedat optional de un semn si-l aduna la toate numerele anterioare, tiparind suma dupa fiecare intrare.

define MAXLINE 100
main() /* calculator rudimentar de birou */
{
double sum, atof();
char line[MAXLINE];
sum = 0;
while (getline(line, MAXLINE) > 0)
printf("\t%.2f\n", sum += atof(line));
}

Declaratia

double sum, atof();

spune ca sum este un double si ca atof este o functie care returneaza o valoare double. Ca mnemonica, ea sugereaza ca sum si atof(...) sint amindoua valori flotante in dubla precizie.
In afara faptului cind atof este declarata explicit in ambele locuri, limbajul C presupune ca ea returneaza un intreg si raspunsurile primite de dumneavoastra vor fi de neinteles. Daca atof insasi si apelul ei din main au tipuri inconsistente in acasi fisier sursa, acest lucru va fi depistat de catre compilator. Dar daca (si asta e mai probabil) atof se compileaza separat, nepotrivirea nu va fi detectata si atof va returna un double pe care main il va trata ca intreg rezultind raspunsuri imprevizibile (lint prinde si aceste erori). Dat atof, putem scrie in principiu atoi (conversie de sir in intreg) astfel:

atoi(s) /* conversie sir s la intreg */
char s[];
{
double atof();
return(atof(s));
}

Sa remarcam structura declaratiilor si a instructiunii return.
Valoarea expresiei din:

return (expresie)

este intodeauna convertita in tipul functiei inainte ca rezultatul sa aiba loc. Deci valoarea lui atof, un double este convertita automat in int, cind apare intr-o instructiune return, deoarece functia atoi returneaza un int. (Conversia unei valori flotante intr-un intreg trunchiaza orice parte fractionara, asa cum am vazut in Capitolul 2).

Exercitiul 4.2. Extindeti functia atof astfel incit ea sa minuiasca si notatia stiintifica de forma 123.45e-6 in care un numar flotant poate fi urmat de e sau E si optional de un exponent cu semn.
avatar
zooky
Moderator
Moderator

Numarul mesajelor : 147
Data de inscriere : 15/03/2009
Varsta : 24
Localizare : Cernatesti City

Vezi profilul utilizatorului http://e-learning.forumhit.ro

Sus In jos

Vezi subiectul anterior Vezi subiectul urmator Sus


 
Permisiunile acestui forum:
Nu puteti raspunde la subiectele acestui forum