Scrigroup - Documente si articole

     

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


Expresii in C

c



+ Font mai mare | - Font mai mic



Expresii in C

In aceasta sectiune vom trece in revista propunerile limbajului C in ceea ce proveste posibilitatea de a utiliza expresii. Toate limbajele de programare acorda o atentie speciala notiunii de expresie deoarece, in ultima analiza, orice transformare a datelor de intrare ale unui program este realizata prin intermediul uneia sau a mai multor expresii. Asa cum vom descoperi pe parcurs, C este un limbaj mult mai flexibil decat alte limbaje in materie de definire si utilizare a expresiilor. Ceea ce este foarte limpede in acest moment este faptul ca expresiile sunt realizate cu ajutorul elementelor atomice numite date si operatori. Datele pot fi reprezentate cu ajutorul constantelor sau prin intermediul variabilelor. Ajungem, evident, la problema tipurilor de date suportate de C.



1 Cinci tipuri de date de baza in C

In C exista cinci tipuri de date de baza: caracter (char), intreg (int), virgula mobila (float), virgula mobila dubla precizie (double) si fara nici o valoare (void).

Toate celelalte tipuri de date din C se bazeaza pe cele cinci tipuri de baza.

Dimensiunea reprezentarii si domeniul valoric corespunzator pentru tipurile de date de baza pot sa difere, in functie de tipul procesorului si de modul de implementare a limbajului C. In toate cazurile, insa, un caracter se reprezinta pe un octet. Chiar daca de multe ori un intreg se reprezinta pe doi octeti, nu se poate conta pe aceasta observatie daca dorim ca programele scrise sa fie portabile. De fapt, insusi standardul ANSI C, stipuleaza doar domeniul de cuprindere minimal al fiecarui tip de date, nu si marimea sa in octeti.

Formatul exact al valorilor in virgula mobila depinde de modul lor de introducere. Intregii corespund, in general, marimii normale a unui cuvant pe calculatorul respectiv.   

Valorile de tip char sunt, in general, utilizate pentru a memora valori definite de setul de caractere ASCII. Valorile care ies din acest domeniu sunt tratate in mod diferit de compilatoare.

Domeniul valoric pentru float si double va depinde de metoda folosita pentru a reprezenta numere in virgula mobila. Standardul ANSI C indica domeniul valoric pentru virgula mobila de la 1E-37 pana la 1E+37. Evident, vor exista deosebiri atat in ceea ce priveste ordinul de marime cat si in ceea ce priveste precizia intre cele doua specii de virgula mobila. Numarul minim de cifre din punct de vedere al preciziei este precizat in Tabelul

ATipul void declara explicit ca o functie nu returneaza nici o valoare sau creaza pointeri generici.

Tip de data

Dimensiune reprezenatre in biti

Domeniul valoric minimal

char

unsigned char

signed char

int

unsigned int

signed int

Similar cu int

short int

Similar int

unsigned short int

signed short int

Similar cu short int

long int

signed long int

Similar cu long int

unsigned long int

float

6 zecimale exacte

double

10 zecimale exacte

long double

10 zecimale exacte

Tabelul 2 Tipurile de date definite prin standardul ANSI C

2 Modificarea tipurilor de baza

Exceptand tipul void, tipurile de baza pot fi precedate de diversi specificatori de conversie. Un specificator de conversie se utilizeaza pentru a modifica tipul de baza in ideea de adaptare mai precisa la diferite situatii. Dupa cum rezulta si din Tabelul 2, lista specificatorilor de conversie este:

signed

unsigned

long

short

In mod evident, diferenta intre intregii cu semn si intregii fara semn consta in modul in care se interpreteaza bitul de pe pozitia cea mai semnificativa. Daca, de exemplu, indicati un intreg cu semn, compilatorul genereaza cod care presupune ca bitul cel mai semnificativ va fi utilizat ca bit de semn (0 daca numarul este pozitiv, 1 daca numarul este negativ). Sa mai mentionam faptul ca, in general, pentru reprezentarea intregilor negativi se foloseste codul complementar (complementul fata de 2).

Detalii referitoare la caracteristicile codului complementar se pot obtine consultand lucrari de specialitate in care se dezbate problema codificarii datelor numerice in sistemele de calcul. In acest sens se poate consulta lucrarea [4] care face o introducere accesibila in problematica mai sus mentionata.

3 Nume de identificatori in C

In C/C++ numele variabilelor, functiilor, etichetelor si ale altor diverse obiecte definite de catre utilizator sunt numite identificatori. Acesti identificatori pot sa aiba unul sau mai multe caractere. Primul caracter trebuie sa fie obligatoriu o litera sau o liniuta de subliniere; urmatoarele pot fi litere, cifre sau liniuta de subliniere.

Exemple de identificatori:

Corecti

Incorecti

numar_de pagini

1_valoare_returnata

_limita1

ok!

ok_

switch..conversie

Standardul ANSI C stipuleaza ca identificatorii pot avea orice lungime. Totusi, nu toate caracterele sunt obligatoriu semnificative. Daca identificatorul este implicat intr-un proces de editare de legaturi externe, vor conta cel mult sase caractere. Acesti identificatori, denumiti nume externe, includ numele functiilor si ale variabilelor globale care apartin mai multor fisiere. Daca fisierul nu este utilizat intr-un proces de editare de legaturi externe, atunci vor fi semnificative cel mult 31 de caractere. Acest tip de identificator este denumit nume intern si include, de exemplu, nume de variabile locale. De remarcat faptul ca in C++ nu exista limite ale lungimii unui identificator si toate caracterele sunt semnificative. Aceasta diferenta incepe sa conteze in momentul in care doriti sa convertiti un program din C in C++.

Pare evident, dar facem precizarea ca un identificator C nu poate fi identic cu un cuvant-cheie si nu trebuie sa aiba acelasi nume ca o functie din biblioteca C sau C++.

4 Variabile C

Asa cum s-a aflat si in alte imprejurari, o variabila este numele unei locatii de memorie utilizata pentru a pastra o valoare care poate fi modificata de program.

Inainte de a fi utilizate in program, variabilele trebuie declarate. Declararea unei variabile in C are forma:

<Tip> <Lista_de_variabile>;

<Tip> trebuie sa fie un tip de data valid (predefinit sau definit de utilizator) precedat, eventual, de un specificator de conversie.

<Lista_de_variabile> poate consta dintr-un nume de identificator sau mai multe nume de identificatori separate prin virgula.

Exemple de declaratii de variabile:

int nr_pag;

char opt,ch;

unsigned i, j;

Variabilele se pot declara in trei moduri: in interiorul functiilor, in cadrul definitiei parametrilor functiei si in afara oricarei functii. Prin urmare, este vorba despre variabile locale, parametri formali si variabile globale.

5 Variabile locale in C

Variabilele declarate in interiorul unei functii sunt numite variabile locale. O parte din literatura C/C++ numeste aceste variabile automatice. Tinand cont de asemanarea evidenta cu variabilele locale din Pascal, de exemplu, vom folosi termenul de variabila locala.

Afirmatia cea mai importanta referitor la variabilele locale este urmatoarea:

"Variabilele locale sunt accesibile doar instructiunilor care sunt in interiorul blocului in care sunt declarate variabilele".

Alt amanunt important si specific limbajului C este faptul ca:

"Variabilele locale exista cat timp se executa blocul de cod in care sunt declarate".

Altfel spus, o variabila locala este creata la inceperea executiei blocului sau si este distrusa la incheierea executiei acestui bloc.

Blocul de cod cel mai uzual in care se declara variabile este functia.

Deoarece notiunea de functie este centrala pentru fizionomia unui program C, prezentam, in continuare, o viziune asupra unui program C care include si notiunea de functie.

Directive preprocesor

Declaratii globale

Declaratie functie_1

Declaratie functie_n

int main

Implementare functie_1

Implementare functie_n

Totodata sa precizam faptul ca sintaxa de declarare a unei functii (prototip in C++), conform standardului ANSI C este :

<Tip returnat> <Nume functie> (<Lista de parametri formali>)

Toata aceasta constructie sintactica se mai numeste si <Antet functie>.

In C clasic declararea unei functii permitea doar specificarea tipului returnat, problema eventualilor parametri asteptati de functie avand o rezolvare aparte, pe care nu mai insistam deoarece standardul ANSI C ca si standardul ANSI C++ descurajeaza, respectiv interzice utilizarea caii clasice.

In C++ declararea unei functii se face apeland la prototipuri.

In sfarsit, implementarea unei functii inseamna o constructie sintactica de tipul:

<Antet functie>

Referindu-ne la standardul ANSI C/ANSI C++ putem spune ca:

<Nume functie> este un identificator valid.

<Tip returnat> specifica tipul de data asociat cu numele functiei.

<Lista de parametri formali> consta din o serie de perechi de denumiri, separate intre ele prin virgula, unde prima denumire specifica un tip de data iar cea de-a doua este numele parametrului formal.

Parametrii formali care apar in antetul unei functii, in principiu, trebuie sa corespunda ca tip cu parametrii actuali care apar la apelul unei functii.Cand un parametru actual trimis unei functii nu se potriveste exact, ca tip, cu parametrul formal corespunzator, compilatorul incearca o conversie convenabila. De exemplu, o data de tip int trimisa unei functii care asteapta o data de tip float este convertita la tipul float. Prezentam, in continuare, cateva exemple.

void f1(void)

void f2(void)

Variabila x este declarata atat in f1 cat si in f Variabila x din f1 nu are nici o influenta asupra variabilei x din f2 deoarece fiecare variabila este cunoscuta doar in blocul de cod gazda. Din obisnuinta si din respect fata de traditie, majoritatea programatorilor declara variabilele folosite de o functie imediat dupa acolada deschisa a functiei si inainte de orice instructiune executabila. De fapt, se pot declara variabile in orice bloc de cod, obtinandu-se chiar efecte benefice pentru calitatea codului rezultat. Astfel putem avea:

void fexemplu(void)

Din exemplul de mai sus retinem doar faptul ca, in situatia in care numarul preluat de la tastatura (cu ajutorul rutinei de uz general scanf ) este mai mare decat zero, atunci devine activ blocul de cod in care se declara variabila nume. Aceasta variabila este distrusa la iesirea din acest bloc de cod.

Prin urmare, un avantaj potential: variabilei nume i se aloca memorie numai daca se activeaza blocul de cod, ceea ce inseamna economie de memorie.

Este absolut evident faptul ca se declara intr-un bloc de cod una sau mai multe variabile strict necesare in acest bloc de cod; in acest mod prevenim, intr-o oarecare masura, aparitia unor efecte secundare. Mai semnalam o diferenta importanta intre modul de declarare a variabilelor locale in C fata de C++.

In C trebuie declarate toate variabilele locale la inceputul blocului in care intentionam sa le definim, inainte de orice instructiune executabila. In C++ nu mai exista aceasta restrictie. Astfel ca secventa de cod C:

void f(void)

este considerata gresita de un compilator C si perfect acceptabila de catre un compilator C++.

Deoarece variabilele locale sunt create si distruse la fiecare intrare, respectiv iesire din blocul in care au fost declarate, continutul lor se pierde odata cu parasirea blocului. Acest lucru este important sa se stie cand apelam o functie. La apelarea ei sunt create variabilele locale iar la incheierea ei acestea sunt distruse, deci variabilele locale nu pastreaza valorile lor intre apelari. Putem determina compilatorul sa pastreze aceste valori utilizand specificatorul de stocare static asupra caruia vom reveni.

6 Parametrii formali

Daca o functie urmeaza sa foloseasca argumente, ea trebuie sa declare variabilele pe care le accepta ca valori ale argumentelor. Aceste variabile sunt denumite parametri formali ai functiei. Variabilele in cauza se comporta ca oricare alta variabila locala din acea functie.

7 Variabile globale

Variabilele globale, spre deosebire de cele locale, sunt cunoscute in tot programul si pot fi utilizate de catre orice zona a codului. Totodata, ele isi pastraza valoarea tot timpul executiei programului. Variabilele globale se creaza prin declarare in afara oricarei functii. Orice expresie are acces la ele, indiferent de tipul blocului de cod in care se afla expresia. De semnalat faptul ca o variabila globala este vizibila in orice bloc de cod al programului cat timp in respectivul bloc de cod nu a fost declarata o variabila cu acelasi nume, de acelasi tip. In caz afirmativ, in blocul de cod este prioritara referirea la variabila locala.

Stocarea variabilelor globale este facuta de compilator intr-o zona de memorie, special alocata. Variabilele globale sunt utile atunci cand mai multe functii ale aceluiasi program folosesc aceleasi date. Utilizarea excesiva a variabilelor globale ar trebui evitata deoarece:

Ocupa memoria pe tot timpul executiei programului, nu doar cand sunt necesare;

Daca o functie utilizeaza o variabila globala in locul uneia locale, atunci functia isi pierde din generalitate, bazandu-se pe ceva exterior logicii ei;

Variabile globale multe inseamna efecte secundare necunoscute si nedorite.

8 Modelatori de acces

In C exista doi modelatori de acces (const si volatile) care introduc restrictii suplimentare asupra modului de apelare sau modificare a variabilelor. Acesti modelatori trebuie sa preceada specificatorul de tip si numele tipului de data la care se refera.

Variabilele de tip const nu pot fi modificate de programele in care sunt declarate. Acestor variabile li se permite, totusi, sa primeasca o valoare initiala. Compilatorul poate sa plaseze variabilele de acest tip in ROM (Read Only Memory). Evident, aceste variabilele de tip const pot fi utilizate in constructia unor expresii. Tehnic vorbind, modelatorul const poate fi utilizat si pentru a proteja obiectele trimise ca argumente unei functii, de modificari in interiorul acelei functii. Multe functii din biblioteca standard a limbajului utilizeaza const in declaratiile lor de parametri. Ca un exemplu, functia strlen() are urmatorul prototip:

size_t strlen( const char * s);

Modelatorul volatile informeaza compilatorul ca valoarea unei variabile poate fi modificata pe cai nedeclarate explicit de program. Aceasta inseamna ca este posibil urmatorul scenariu: "Adresa unei variabile este transmisa unei rutine rezidente in memoria sistemului, aceasta rutina fiind abilitata sa modifice valoarea variabilei". Evident, pentru programatori acesta este un mecanism extrem de practic si interesant. Modelatorul volatile poate fi combinat cu modelatorul const facandu-se plauzibil scenariul: "Valoarea unei variabile poate fi modificata de conditii externe, fiind protejata de modificari accidentale in programul in care este declarata".

9 Specificatori de clase de stocare

Limbajul C admite patru specificatori de clase de stocare:

extern

static

register

auto

Acesti specificatori indica compilatorului modul in care trebuie sa stocheze variabilele la care se refera. Cadrul sintactic general de utilizare a specificatorilor de clase de stocare este:

<Specificator_de_stocare> <Tip> <Nume_variabila>;

extern

Deoarece C/C++ permit sectiunilor separate ale unui program sa fie compilate independent si sa li se editeze legaturile impreuna, trebuie sa existe o modalitate de a comunica tuturor fisierelor variabilele globale necesare programului. Scenariul caruia trebuie sa ii facem fata este urmatorul: "Cum putem informa toate fisierele care compun un program C despre variabilele globale utilizate?". Solutia este urmatoarea : Se declara variabilele globale intr-un fisier, care este de preferat sa contina si functia principala a programului, aceleasi variabile declarandu-se si in toate fisierele care folosesc variabilele globale, insotite de specificatorul extern.

static

Variabilele de tip static sunt variabile permanente in interiorul functiei sau fisierului in care se gasesc. Spre deosebire de variabilele globale, ele nu sunt cunoscute in afara functiei sau fisierului, dar isi pastreaza valoarea intre doua apelari. Aceasta caracteristica este folositoare la scrierea de functii generice si de biblioteca , utilizabile de alte programe. Specificatorul static are efecte diferite asupra variabilelor locale si globale.

Variabile locale statice

Aplicat unei variabile locale, specificatorul static informeaza compilatorul de dorinta de a i se asocia variabilei un loc de stocare permanenta, similar celui asociat unei variabile globale. Diferenta esentiala intre variabilele locale statice si o variabila globala se refera la faptul ca variabila locala statica ramane cunoscuta doar blocului in care a fost declarata. Altfel spus, o variabila locala statica este o variabila care isi pastreaza valoarea intre apelurile functiei in care a fost declarata.

Variabile globale statice

Aplicand specificatorul static unei variabile globale, cerem compilatorului sa creeze o variabila globala care este cunoscuta doar in fisierul in care a fost declarata. Aceasta inseamna ca, desi variabila este globala, rutine din alte fisiere nu au acces la ea si nu ii pot modifica continutul.

register

Specificatorul de stocare register se aplica, prin traditie, doar variabilelor de tip int si char. Totusi standardul ANSI C ii da definitia astfel incat poate fi folosit pentru orice tip de variabila. Initial, register cerea compilatorului sa pastreze valoarea unei variabile intr-un registru din CPU, nu in memoria RAM, unde variabilele sunt stocate, de regula. Scopul unei astfel de cereri: spor de viteza in timpul operatiilor asupra variabilei. Actualmente, definitia specificatorului register a fost mult extinsa, acesta putand fi aplicat oricarui tip de variabila. Standardul ANSI C stipuleaza, simplu, ca register este o indicatie data compilatorului ca obiectul vizat va fi utilizat preferential din punct de vedere al vitezei.

Specificatorul se poate aplica doar variabilelor locale si parametrilor formali. Prin urmare, nu sunt permise variabile globale de tip register.

auto

Specificatorul auto este, practic, nefolosit, fiind reclamat doar de motive de compatibilitate intre codul C si codul C++.

10 Initializarea variabilelor

Forma generala a initializarii unei variabile respecta sintaxa:

<Tip> <Nume_variabila> = <Constanta>;

Exemple:

char ch='A';

int media=0;

float bilant=0;

AVariabilele globale si cele statice locale sunt initializate doar la inceputul executiei programului. Variabilele locale (cu exceptia celor de tip static, sunt initializate de fiecare data cand este intalnit blocul in care sunt declarate.

AVariabilele locale care nu sunt initializate au valori necunoscute inainte de prima atribuire. Variabilele globale si locale de tip static neinitializate sunt initializate din oficiu cu zero.

Evident, trebuie sa discutam in continuare despre problema reprezentarii constantelor in programele C.

Constante C

Constantele se refera la valori fixe pe care programul nu poate sa le modifice. Constantele pot fi de oricare din tipurile fundamentale de date. Modul in care se reprezinta in program fiecare constanta depinde de tipul sau.

Constantele de tip caracter sunt incluse intre ghilimele simple. 'A' si '%' sunt exemple de constante de tip caracter. C defineste si caractere multioctet, in mediile care nu utilizeaza limba engleza. O situatie asemanatoare se intalneste si in Delphi.

Constantele de tip intreg sunt specificate ca numere fara parte fractionara. De exemplu, 3 si -15 sunt exemple de constante intregi.

Constantele in virgula mobila cer punctul zecimal urmat de partea zecimala a numarului. 0.75 este un exemplu de constanta care apeleaza la virgula mobila. Limbajul C permite si notatia stiintifica, cunoscuta si in alte limbaje.

De asemenea, C stabileste pentru o constanta numerica cel mai scurt tip de date compatibil care o poate pastra. Astfel ca, -10 este implicit un int, 60.000 este unsigned int iar 120.000 este un long int. Tipul constantei numerice poate fi specificat si explicit ca in exemplele din Tabelul 3.

Tip de data

Exemplu de constanta

int

long int

100000, 23000L, -45L

short int

unsigned int

10000U, 900U, 45000

float

120.15F 3.75e-5F

double

long double

1000.25L

Tabelul 3 Exemple de constante numerice

Dupa cum se vede, constantele in virgula mobila sunt asimilate implicit tipului double.

Constante hexazecimale si octale

Deoarece exista numeroase situatii in care avem nevoie de referiri la sistemele de numeratie octal si hexazecimal, C permite utilizarea constantelor octale si hexazecimale astfel:

O constanta octala incepe cu 0 (zero).

Exemplu:

int octala=017; /*In zecimal 15 */

O constanta hexazecimala incepe cu 0x.

Exemplu:

int hexa =0x100; /*In zecimal 256*/

Constante de tip sir

C admite, cum era si firesc si constanta de tip sir de caractere. O constanta sir este o succesiune de caractere delimitata de ghilimele. A nu se confunda sirurile de caractere cu caracterele. 'a' si "a" sunt constante de tipuri diferite( distictie care, in Pascal, nu este operata sintactic, vorbind.

Constante de tip backslash caracter

Incadrarea constantelor de tip caracter intre apostrofuri functioneaza pentru majoritatea caracterelor afisabile. Insa, altele, putine la numar, sunt imposibil de introdus de la tastatura (constanta BEL, de exemplu). In acest scop C introduce constante speciale, de tip backslash caracter. C admite mai multe coduri backslash, cum rezulta si din Tabelul 4. Pentru a se asigura portabilitatea programelor sunt indicate codurile backslash in locul codurilor lor ASCII.

Codul

Semnificatia

b

backspace

f

form feed (=Salt la pagina noua)

n

CR+LF

r

CR

t

tab orizontal

ghilimele

apostrof

Null

backslash

v

tabulare verticala

a

alerta

N

constanta in octal; N este constanta

xN

constanta in hexazecimal; N este constanta

Tabelul 4 Coduri backslash in C   

11 Operatori in C

C dispune de foarte multi operatori. De fapt, C acorda acestora o importanta mult mai mare in comparatie cu alte limbaje. C defineste, in esenta, patru clase de operatori: aritmetici, relationali, logici si de actiune la nivel de bit. Pentru anumite sarcini, C are operatori suplimentari.

Operatorul de atribuire

Operatorul de atribuire poate fi folosit, in C, in cadrul oricarei expresii valide, lucru care nu este permis in majoritatea limbajelor de programare (inclusiv Pascal), care trateaza operatorul de atribuire ca pe un caz de instructiune speciala. Sintaxa de aplicare a operatorului de atribuire in C este:

<Nume_variabila> = <Expresie>;

unde <Expresie> poate fi o constanta sau o constructie legala de complexitatea ceruta in context. Atentie, se foloseste "=" in loc de ":=". Membrul stang al atribuirii trebuie sa fie o variabila sau un pointer, nu o functie sau o constanta.

Conversii de tip la atribuire

Cand variabilele de un anumit tip sunt amestecate cu variabile de alt tip, au loc conversii de tip. Intr-o instructiune de atribuire, regula de conversie este simpla: valoarea din membrul drept (al expresiei) al instructiunii de atribuire este convertita la tipul din membrul stang. Pentru o mai buna intelegere a "fenomenului", fie exemplul de mai jos.

int nri;

char car;

float nrr;

void functie(void)

In Linia 1, in variabila car ajung primii 8 biti cei mai putin semnificativi ai variabilei nri. Daca nri este cuprins intre 0 si 255, car si nri vor avea valori identice s.a.m.d.. Presupunand ca sistemul de calcul are cuvantul de 16 biti, Tabelul 5 prezinta posibilele pierderi de informatie care pot sa apara la conversia de tip in atribuiri.

Tipul destinatiei

Tipul expresiei

Posibile pierderi de informatie

signed char

char

Daca valoarea este > 127, destinatia este negativa.

char

short int

Cei mai semnificativi opt biti

char

int

Cei mai semnificativi opt biti

char

long int

Cei mai semnificativi 24 biti

int

long int

Cei mai semnificativi 16 biti

int

float

Partea zecimala si, posibil, mai mult

float

double

Precizie, rezultat, rotunjit

double

long double

Precizie, rezultat, rotunjit

Tabelul 5 Tipuri de conversie frecvent utilizate

Atribuiri multiple

C permite atribuirea aceleeasi valori mai multor variabile prin utilizarea atribuirii multiple intr-o singura instructiune de atribuire. De exemplu instructiunea:

x = y = z = 0;

permite setarea la 0 a variabilelor x,y,z. Programatorii profesionisti folosesc masiv atribuirea multipla pentru a obtine cod performant.

Sa mai adaugam o observatie interesanta pentru un programator profesionist. O atribuire de tipul:

<Variabila>=<Variabila>+<Expresie> (1)

este echivalenta semantic cu sintaxa:

<Variabila>+=<Expresie> (2)

Desi s-ar putea sa vina "peste mana" unor programatori, acestia trebuie sa stie ca pentru compilator sintaxa (2) este de preferat sintaxei (1) din punct de vedere al calitatii codului generat.

Asadar,

x=x+1

este totuna cu:

x+=1.

Operatori aritmetici

Tabelul 6 prezinta operatorii aritmetici din C.

Operator

Actiune

Scadere, de asemenea si minus unar

Adunare

Inmultire

Impartire

Modul

Decrementare

Incrementare

Tabelul 6 Operatori aritmetici in C

Dintre operatorii prezentati in Tabelul 6, operatorii ++ si -- sunt specifici limbajului C. Operatorul ++ aduna 1 la variabila asociata. Operatorul -- scade 1 din variabila asociata. Astfel ca:

x=x+1;

este sinonim cu:

++x;

iar

x=x-1;

este sinonim cu:

x--;

Ambii operatori pot sa fie plasati atat inainte cat si dupa variabila operata. Prin urmare:

x=x+1;

poate fi scris:

++x ;

sau

x++;

Exista, totusi, o diferenta intre forma cu prefix si forma cu sufix, daca operatorii sunt utilizati intr-o expresie. Atunci cand operatorii preced variabila, C efectueaza operatiile corespunzatoare lor, inainte de a evalua expresia. Atunci cand operatorii succed variabila, C efectuiaza operatiile corespunzatoare lor, dupa evaluarea expresiei. Majoritatea compilatoarelor C/C++ produc rapid un cod obiect eficient pentru operatiile de incrementare si decrementare (cod mai bun decat cel obtinut prin utilizarea atribuirii clasice echivalente). Pe acest considerent, recomandarea de a utiliza acesti operatori de cate ori este posibil este fireasca. In sfarsit, ordinea de precedenta a operatorilor aritmetici este:

De ordinul cel mai inalt

(minus unar)

De ordinul cel mai coborat

Operatori relationali si logici

Deoarece operatorii relationali si logici lucreaza de multe ori impreuna, ii prezentam impreuna. Semnificatia celor doua tipuri de operatori este cunoscuta de la alte limbaje. Operatorii relationali permit "compararea" (=punerea in relatie) a operanzilor. Rezultatele compararii pot fi combinate dupa rigorile algebrei Boole cu ajutorul operatorilor logici.

Atat operatorii relationali cat si cei logici au o precedenta mai scazuta decat operatorii aritmetici. Deci, o expresie precum 8 > 1+5 este evaluata ca si cum ar fi fost scrisa 8 > (1+5). In Tabelul 7 prezentam opertorii relationali si logici folositi in C/C++.

Operatori relationali

Operator

Actiune

>

Mai mare decat

>=

Mai mare sau egal

<

Mai mic decat

<=

Mai mic sau egal

Egal

Diferit

Operatori logici

Operator

Actiune

&&

AND (SI)

OR (SAU)

NOT (NEGAT)

Tabelul 7 Operatorii relationali si logici in C.

Tabelul 8 prezinta prioritatile in relatia dintre operatorii relationali si logici.

De ordinul cel mai inalt

>, >=, <, <=

&&

De ordinul cel mai coborat

Tabelul 8 Relatia de precedenta intre operatorii relationali si logici

Evident, parantezele pot fi utilizate pentru a modifica ordinea fireasca de evaluare a unei expresii relationale si/sau logice.

Operatori de actiune pe biti

Spre deosebire de multe alte limbaje, C admite un complement deplin cu operatorii de actiune pe biti. Deoarece C a fost proiectat sa ia locul limbajului de asamblare pentru majoritatea sarcinilor, el trebuie sa fie capabil sa asigure multe operatii care pot fi executate in asamblor, inclusiv asupra bitilor. Operatiile asupra bitilor se refera la testare, initializare sau deplasare a bitilor existenti intr-un octet sau intr-un cuvant care corespund tipurilor de date char si int si variantelor acestora din standardul C. Operatorii de actiune asupra bitilor nu pot fi utilizati asupra tipurilor float, double, long double,void. In Tabelul 9 prezentam operatorii C pentru biti.

Operator

Actiune

&

AND

OR

OR exclusiv (XOR)

Complement fata de 1 (NOT)

>>

Deplasare la dreapta

<<

Deplasare la stanga

Tabelul 9 Operatorii de actiune pentru biti

Intelegerea transformarilor efective care au loc la utilizarea operatorilor AND, OR si XOR este legata de analiza in spiritul legilor logicii Boole a unei expresii de tipul:

<Operand_1> <Operator><Operand_2>

Actiunea operatorului este aplicata bit cu bit operanzilor, rezultand o configuratie de biti asupra carora se pot continua alte prelucrari.

Operatorii de deplasare a bitilor >> si << deplaseaza toti bitii dintr-o variabila la dreapta sau la stanga. Sintaxa asociata este:

<Variabila> >> <Numar_de_pozitii_de_shiftat>

sau

<Variabila> << <Numar_de_pozitii_de_shiftat>

Sensul operatiei de shiftare este cel precizat la un curs de Bazele logice ale sistemelor de calcul.

Precizari referitoare la operatorii suplimentari pot fi gasite in [1].

Operatorul ?

C propune un operator unar foarte puternic si util care poate inlocui anumite instructiuni de forma "daca - atunci - altfel".

Operatorul ? apare in expresii avand forma generala:

<Expresie_1> ? <Expreasie_2> : < Expresie_3>

unde:

-<Expresie_1>, <Expresie_2>, <Expresie_3> sunt expresii, cu precizarea ca <Expresie_1> este o expresie conditionala;

-semantica constructiei sintactice de mai sus este urmatoarea:

l Se evaluiaza <Expresie_1>;

l Daca <Expresie_1> este adevarata se evaluiaza <Expresie_2> si rezultatul evaluarii ei i se atribuie expresiei globale;

l Daca <Expresie_1> este falsa. atunci se evaluiaza <Expresie_3> si rezultatul evaluiarii acesteia este atribuit expresiei globale.

Aceasta semantica este evidentiata si de exemplul de mai jos de utilizare a operatorului ?.

X=24;

X=X<24 ? 1:X+1;

Acest cod este echivalent cu codul:

X=24;

if (X<24) X=1

else X=X+1;

Operatorii & si *

Un pointer este adresa din memorie a unei variabile. O variabila de tip pointer este declarata explicit pentru a retine un pointer catre un obiect de un tip specificat. Cunoasterea adresei unei variabile poate fi de mare utilitate in anumite situatii. In C pointerii au trei functii principale.

l asigura o cale rapida de acces la elementele unei matrici;

l permit functiilor C sa modifice parametrii de apelare;

l permit realizarea structurilor dinamice de date.

Pentru simplificarea lucrului cu pointeri au fost introdusi operatorii & si *.

Operatorul & este un operator unar care permite recuperarea adresei din memorie a unui element C precum si declararea de variabile sinonime.

O atribuire de tipul :

adr=&Numar_Elemente;

este utila pentru a obtine in variabila adr adresa din memorie a variabilei Numar_Elemente. Aceasta adresa este adresa locatiei din memorie incepand de la care se pastreaza continutul variabilei Numar_Elemente.

Al doilea operator pentru pointeri este * , oarecum complementar operatorului &. Si operatorul * este unar, returnand valoarea din variabila localizata la adresa specificata. Astfel , dupa executia secventei:

adr=&Numar_Elemente;

nr=*adr ;

variabila nr va contine aceeasi valoare cu variabila Numar_Elemente, presupunand ca cele doua variabile sunt compatibile ca tip.

Evident, exista, din punct de vedere al utilizatorului, primejdia de a utiliza confuz acesti doi operatori, din moment ce * mai inseamna si "inmultire" iar & mai inseamna si "si logic" la nivel de biti.

Variabilele care pastreaza pointeri trebuie declarate ca atare. Sintaxa de declarare a unei variabile pointer este:

<Tip de baza> * <Nume_Variabila>;

Exemplu

#include <stdio.h>

void main(void)

Operatorii & si * sunt utilizati pentru a introduce valoarea 10 in variabila destinatar .

Operatorul sizeof (cu actiune in timpul compilarii)

sizeof este un operator unar utilizat in timpul compilarii care returneaza lungimea in octeti a variabilei sau a specificatorului de tip dintre parantezele asociate de sintaxa operatorului. Sintaxa de utilizare a operatorului:

sizeof ( <Nume_Variabila>)

sau

sizeof (<Specificator_ de_ tip>)

De remarcat faptul ca in cazul unei variabile este permisa si sintaxa:

sizeof <Nume_Variabila>

Acest operator este util in procesul de realizare a aplicatiilor portabile.

Operatorii . (punct) si -> (sageata)

Sunt utilizati pentru a realiza referirea la elementele individuale ale structurilor si uniunilor din C. Asa cum se va vedea, structurile si uniunile sunt tipuri de date agregate la care se poate avea acces sub un singur nume.

Operatorul punct este utilizat atunci cand se lucreaza cu structuri sau uniuni efective. Operatorul sageata este folosit impreuna cu un pointer la o structura sau la o uniune. Astfel, anticipand putin, daca avem codul:

struct tangajat

angajat;

struct tangajat *pangajat=&angajat;

are sens urmatorul cod:

angajat . salariu:=1100000;

Aceasta atribuire este echivalenta cu atribuirea:

pangajat->salariu=1100000;

De remarcat faptul ca in C exista multe alte facilitati puse la dispozitia programatorilor, precum: conversia automata in expresii, fortarea tipurilor expresiilor utilizand modelatorii, utilizarea expresiilor prescurtate.

11 Comentarea programelor C/C++

Un comentariu este o nota explicativa pentru programatori, ignorata complet de compilator In C comentariile sunt delimitate de perechile de caractere /* .*/. Compilatorul C ignora orice text aflat intre acesti delimitatori.

Exemple de comentarii:

Un comentariu se poate intinde pe mai multe linii

daca aceasta este dorinta programatorului*/

sau

clrscr() /* Stergere ecran in mod text */

Acest tip de comentariu nu poate fi imbricat.

Compilatoarele C++ accepta si comentarii care incep cu secventa //, dar se pot intinde pe o singura linie, astfel:

clrscr() // Stergere ecran in mod text.



Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 875
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