Scrigroup - Documente si articole

     

HomeDocumenteUploadResurseAlte limbi doc
AccessAdobe photoshopAlgoritmiAutocadBaze de dateCC sharp
CalculatoareCorel drawDot netExcelFox proFrontpageHardware
HtmlInternetJavaLinuxMatlabMs dosPascal
PhpPower pointRetele calculatoareSqlTutorialsWebdesignWindows
WordXml


Conversii de tip

c



+ Font mai mare | - Font mai mic



Conversii de tip

Cind intr-o expresiie apar operanzi de mai multe tipuri, ei



se convertesc intr-un tip comun, dupa un numar mic de reguli. In

general, singurele conversii care se fac automat sint acelea

cu sens , de exemplu convertirea unui numar intreg intr-un flotant

in expresii de tipul f + i. Expresiile fara sens, de exemplu

folosirea unui float ca indice de tablou, nu sint permise.

In primul rind, char-i si int-i pot fi amestecati in

expresiile aritmetice: orice char este convertit automat intr-un

int. Aceasta permite o flexibilitate remarcabila in anumite

tipuri de transformari de caractere. Exemplificam cu functia atoi,

care converteste un sir de cifre in echivalentul lui numeric.

atoi(s) /* converteste un sir s in intreg */

char s[];

Asa cum am vazut in Capitolul 1, expresia

s[i]-'0'

reprezinta valoarea numerica a caracterului aflat in s[i] deoarece

valorile lui '0','1', etc formeaza un sir crescator pozitiv si

contiguu.

Un alt exemplu de conversie intre char si int il constituie

functia lower care transforma literele mari din setul de

caractere ASCII in litere mici. Daca intrarea nu este o litera

mare, functia o returneaza neschimbata:

lower(c) /* conversie ASCII litere mari in litere mici */

int c;

Aceasta functie este valabila numai pentru ASCII deoarece pe de

o parte intre literele mari si literele mici exista o distanta

fixata, ca valoare numerica, iar pe de alta parte ambele

alfabete sint contigue - intre A si Z se gasesc numai litere.

Aceasta ultima observatie nu este valabila pentru setul de

caractere EBCDIC (IBM 360/370), asa incit functia lower esueaza

pentru aceste sisteme, ea va converti mai mult decit literele

mari.

Exista o subtilitate in conversia caracterelor in intregi.

Limbajul nu specifica daca o variabila de tip char este o canti-

tate cu semn sau fara semn. Cind un char este convertit intr-un

int, poate el produce un intreg negativ ? Din pacate, aceasta

variaza de la calculator la calculator, reflectind diferen-

tele arhitecturale. Pe anumite calculatoare (de exemplu PDP-11) un

char al carui cel mai din stinga bit este 1 va fi convertit

intr-un intreg negativ ('extensie de semn'. Pe altele, un

char este convertit intr-un int prin adaugarea de zerouri in

partea stinga si astfel el este intodeauna pozitiv.

Definitia lui C asigura ca orice caracter din setul stan-

dard al masinii nu va fi niciodata negativ, asa ca aceste carac-

tere pot fi folosite liber in expresii ca si cantitati pozitive.

Dar modele arbitrare de biti memorate in variabile de tip charac-

ter pot apare drept negative pe anumite calculatoare si

drept pozitive pe altele.

Cea mai comuna aparitie a acestei situatii este cind pentru

EOF se foloseste -1. Sa consideram codul:

char c;

c = getchar();

if (c == EOF)

Pe un calculator care nu face extensie de semn, c este

intodeauna pozitiv deoarece el este un char, dar totusi EOF

este negativ. In consecinta testul esueaza intodeauna. Pentru a

evita aceasta, trebuie sa avem grija atunci cind folosim int in

loc de char pentru orice variabila care primeste o valoare

returnata de getchar.

Adevarata ratiune pentru utilizarea lui int in loc de char

nu este legata cu nimic de posibila extensie de semn. Pur si

simplu, getchar trebuie sa returneze toate caracterele posibile

(astfel incit sa poate fi folosita pentru a citi o intrare arbi-

trara) si in plus, o valoare pentru EOF distincta. Astfel, aceasta

valoare nu poate fi reprezentata ca si un char dar, in

schimb, trebuie memorata ca si un int.

O alta forma utila de conversie de tip automata este

aceea ca expresiile relationale de tipul i > j si expresiile

logice conectate prin && si || se definesc a avea valoarea 1

pentru adevar si 0 pentru fals. Astfel, o asignare:

isdigit = c >= '0' && c <= '9';

pune pe isgit pe 1 daca c este o cifra si pe 0 daca nu. (In

partea de test a lui if, while ,for, etc, 'adevarat' inseamna

'nonzero').

Conversiile aritmetice implicite lucreaza in mare masura cum

ne asteptam. In general, daca un operator ca + sau * care

are doi operanzi (un 'operator binar') are operanzi de tipuri

diferite, tipul 'inferior' este promovat la tipul 'superior' ina-

inte de executia operatiei. Rezultatul insusi este de tipul supe-

rior. Mai precis, pentru fiecare operator aritmetic, se aplica

urmatoarea secventa de reguli de conversie:

char si short se convertesc in int iar float este conver-

tit in double.

Apoi, daca un operand este double , celalalt este conver-

tit in double iar rezultatul este double.

Altfel, daca un operand este long, celalalt este convertit

in long iar rezultatul este long.

Altfel, daca un operand este unsigned, celalalt este

convertit inunsigned, iar rezultatul este unsigned.

Altfel, operanzii trebuie sa fie int, iar rezultatul este

int.

Sa notam ca toti float dintr-o expresie sint convertiti in double;

orice calcul flotant in C este facut in dubla precizie.

Conversiile se fac in asignari; valoarea partii drepte

este convertita la tipul din stinga, care este tipul rezulta-

tului. Un caracter este convertit intr-un int fie cu exten-

sie de semn, fie nu, asa cum s-a descris mai sus. Operatia

inversa, int in char, se comporta bine, pur si simplu, bitii de

ordin superior in exces sint eliminati. Astfel, in:

int i;

char c;

i = c;

c = i;

valoarea lui c ete neschimbata. Acesta este adevarat si cind

extensia de semn este implicita si cind nu este implicita.

Daca x este float iar i este int, atunci:

x = i;

si

i = x;

provoaca amindoua conversii; float in int provoaca trunchierea

oricarei parti fractionare. double este convertit in float prin

rotunjire. Intregii lungi sint convertiti in scurti sau in char

prin pierderea bitilor de ordin superior in exces.

Deoarece argumentul unei functii este o expresie, con-

versia de tip are loc deasemenea si cind argumentele sint

pasate functiei in particular, char si short devin int, iar

float devine double. Iata de ce am declarat argumentul functiei

ca fiind int si double chiar cind functia este apelata cu char

si float.

In final, conversia explicita de tip poate fi fortata in

orice expresie cu o constructie numita 'distribuire'(cast). In

constructia:

(numedetip) expresie

sus. Semnificatia precisa a unei distribuiri este de fapt ca si

daca o expresie ar fi asignata la o variabila de tipul specifi-

cat, care este apoi folosita in locul intregii constructii. De

exemplu, rutina din biblioteca sqrt are nevoie de un argument

double si va produce nonsens daca i se da sa minuiasca altceva.

Astfel, daca n este un intreg:

sqrt((double) n)

il converteste pe n in double inainte de a-l pasa lui sqrt.

(De notat ca distribuirea produce valoarea n in tipul potrivit;

continutul efectiv al lui n nu este alterat ). Operatorul de

distribuire are acceasi pondere ca si alti operatori unari, asa

cum apare si in tabelul recapitulativ de la sfirsitul capitolu-

lui.

Exercitiul 2.2. Scrieti o functie htoi(s) care converteste

un sir de cifre hexazecimale in valoarea sa intreaga echiva-

lenta. Cifrele sint de la 0 la 9, literele de la a la f si de la

A la F.



Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 1096
Importanta: rank

Comenteaza documentul:

Te rugam sa te autentifici sau sa iti faci cont pentru a putea comenta

Creaza cont nou

Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved