|
-44-
& -este operatorul binar pentru conditia "si logic".Nu trebuie confundat
|
səhifə | 7/55 | tarix | 07.05.2018 | ölçüsü | 4,6 Mb. | | #50260 |
| -44-
& -este operatorul binar pentru conditia "si logic".Nu trebuie confundat
cu operatorul de adresare(care are acelasi simbol dar nu actioneaza
asupra ariilor de biti) fata de care se diferentiaza prin contextul
sintactic in care este utilizat(se utilizeaza pentru date binare).
Ca operator de biti (bitwise-AND),compara primul operand cu cel de
al doilea,bit cu bit (la aceeasi pozitie a bitilor).Daca ambii biti
(din cei doi operanzi) sunt de tip 1,rezultatul va fi 1,iar in
celelalte situatii(1 si 0,0 si 1 sau 0 si 0) rezultatul va fi 0.
EXEMPLU: intNumar1=1,Numar2=3,Rezultat //00000001,00000011
Rezultat=Numar1 & Numar2 //Rezultat este 1 (00000001)
operatia explicita este:
0 0 0 0 0 0 0 1 & (1)
0 0 0 0 0 0 1 1 (3)
_______________
0 0 0 0 0 0 0 1 (1)
sau intNumar1=95,Numar2=97,Rezultat //01011111,01100001
Rezultat=Numar1 & Numar2 //Rezultat=65 (01000001)
operatia explicita este:
0 1 0 1 1 1 1 1 & (95)
0 1 1 0 0 0 0 1 (97)
__________________
0 1 0 0 0 0 0 1 (65)
Observati ca operatorul & se poate utiliza pentru aducere la zero(
daca cel de al doilea operand este de forma 00000000,rezultatul
operatiei va fi zero,indiferent de primul operand.In mod similar se
poate utiliza pentru a "aduce la zero" doar o parte din octet.Practic
cel de al doilea operand poate introduce o "conditie de filtrare".
^ -este operatorul binar "XOR logic".Compara bit cu bit cei doi operanzi
si returneaza 1 daca unul dintre ei este 0 iar celalalt este 1.Daca
ambii operanzi sunt de acelasi fel(1 si 1 sau 0 si 0) returneaza 0.
Este denumita si operatia ori exclusiv(la fel ca si tipul de poarta
logica a procesorului binar).
EXEMPLU: intNumar1=9,Numar2=3,Rezultat //00001001,00000011
Rezultat=Numar1 ^ Numar2 //Rezultat este 10 (00001010)
operatia explicita este:
0 0 0 0 1 0 0 1 ^ (9)
0 0 0 0 0 0 1 1 (3)
_________________
0 0 0 0 1 0 1 0 (10)
| -este operatorul binar "OR logic".Compara bit cu bit cei doi operanzi.
Daca unul dintre ei este 1,rezultatul va fi 1,iar in celelalte si-
tuatii(daca ambii sunt zero),rezultatul va fi zero.Se numeste si
operatie "ori inclusiv" (la fel ca tipul de poarta logica).
EXEMPLU: intNumar1=95,numar2=97,Rezultat //01011111,01100001
Rezultat=Numar1 | Numar2 //Rezultat este 127 (01111111)
Explicit: 0 1 0 1 1 1 1 1 (95)
0 1 1 0 0 0 0 1 (97)
_______________
0 1 1 1 1 1 1 1 (127)
-45-
&& -este operatorul "si logic"(logic AND),denumit la fel ca si tipul de
poarta logica,pentru a facilita dirijarea bitilor in procesor.
Se utilizeaza pentru a combina mai multe conditii formulate prin
expresii de egalitate sau relationale.Daca ambii operanzi sunt nonzero
(diferiti de zero),operatia returneaza 1,iar in caz contrar(unul
dintre operanzi este evaluat ca fiind zero) returneaza 0.
EXEMPLU: int SoldCont=0,NrAni=1;
if ((SoldCont=0) && (NrAni>3)) {
CalculDobanda();
}
verifica daca ambele conditii sunt adevarate si executa functia,dar
in cazul de mai sus,doar o conditie este indeplinita si returneaza 0
|| -este operatorul "OR logic"(ori inclusiv).Se utilizeaza pentru a
combina mai multe conditii,formulate prin expresii de egalitate sau
relationale.Daca unul dintre operanzi este nonzero(diferit de zero),
operatia returneaza 1,iar in caz contrar(daca ambii operanzi sunt
evaluati a fi zero) returneaza 0.Cu alte cuvinte,este suficienta una
singura dintre optiuni pentru a verifica conditia.
EXEMPLU: int Numar1=1,Numar2=0
if (Numar1 || Numar2) {
Functie();
}
verifica daca unul dintre numere este diferit de zero si executa
functia.In acest caz Numar1 este nonzero asa ca se executa functia.
sau: int a=3,x;
float c=3.6,d=6.6;
x = a == 3 && c
x va primi valoarea lui a,adica 3 deoarece ambele expresii a==3 si
c
= -este operatorul de atribuire ("asignare").Prin aceasta operatie,
valoarea operandului din dreapta este atribuita locatiei de memorie
desemnata prin operandul din stanga(valoarea respectiva este arhivata
la locatia respectiva).Altfel spus,operandul din stanga primeste va-
loarea celui din dreapta.
EXEMPLU: int a=1,b=3;
a=b //a va fi 3 (i se atribuie valaorea lui b)
Limbajul C,permite combinarea operatorului de atribuire cu toti opera-
torii aritmetici binari,avand ca rezultat operatori de atribuire ce
executa doua operatii simultan.Acesti operatori sunt:
+= (atribuie a+b) EXEMPLU: a += b // a va fi 4 (1+3=4 )
-=(atribuie a-b) EXEMPLU: a -= b //a va fi -2 (1-3=-2 )
*=(atribuie a*b) EXEMPLU: a *= b //a va fi 3 (1*3=3 )
/=(atribuie a/b) EXEMPLU: a /= b //a va fi 0.33 (1/3=0.33 )
%=(atribuie a%b) EXEMPLU: a %= b //a va fi 1 (1/3=0 rest 1)
>>=(atribuie a/2E+b)EXEMPLU: a >>=b //a va fi 0.13 (1/2E+3=1/8=0.13)
<<=(atribuie a*2E+b)EXEMPLU: a <<=b //a va fi 8 (1*2E+3=1*8=8)
&= (atribuie a AND b)EXEMPLU: a &= b //a va fi 1 (1 & 3 este 1)
|= (atribuie a OR b) EXEMPLU: a | b //a va fi 3 (1 | 3 este 3)
^= (atribuie a XOR b)EXEMPLU: a ^= b //a va fi 2 (1 ^ 3 este 2)
-46-
EXEMPLE explicite: int a=2;
float b=3.14
a+=b; //a va fi 5 rezultatul e de tipul membrului
stang al operatiei(respectiv int)
sau
int x
int *px;
px=&x;
*px=0; //se atribuie 0 variabilei pointate de px
y=*px+1 //y primeste valoarea lui x plus 1
*px +=1 //incrementeaza variabila x cu x plus 1
In cazul in care se utilizeaza operatori de atribuire care au aceeasi
precedenta,evaluarea expresiei se va face de la dreapta la stanga.
EXEMPLU: int a=2,b=3 ,c;
c = a = b; //c va fi 3 (b se atribuie lui a,apoi lui c)
Prin cumularea operatorului de atribuire cu oricare dintre operatorii
binari se limiteaza spatiul ocupat de program si creste viteza de executie
EXEMPLU: a <<= b efectueaza trei operatii simultan si inlocuieste trei
expresii diferite(trei linii de program ce ar fi ocupat un
numar variabil de octeti de memorie in mod inutil)
?: -este un operator conditional tertiar (necesita trei operanzi).
Sintaxa este de tipul:
expresie1 ? expresie2 : expresie conditionala
expresie1 -trebuie sa fie de tip int,float sau pointer.
Se evalueaza valoarea primului operand si in functie de rezultat se
va evalua unul sau celalat dintre operanzi,dupa cum urmeaza:
-daca primul operand este evaluat nonzero se va evalua expresie2 (al
doilea operand)
-daca primul operand este evaluat zero,se va evalua expresia condi-
tionala (cel de al treilea operand)
In cazul pointerilor,pot fi comparate ambele tipuri(const sau volatile)
dar rezultatul final va mosteni specificatorul de la ambele componente
ale operatiei de comparare.
EXEMPLE: float m,a,b;
m = a>b ? a : b // va fi valoarea maxima dintre a si b
sau:
int Suma,ContCurent=200;
Suma=(ContCurent < 0) ? 0 : ContCurent;
suma va fi cea din ContCurent daca este mai mare decat zero,sau va fi
zero daca soldul este negativ (ContCurent<0).
.* si ->* -sunt operatori de pointare spre membrii unei clase.Operatorul
.* se utilizeaza pentru a orienta pointerul spre un membru al
unei clase(un obiect),iar operatorul ->* se utilizeaza pentru a
orienta pointerul spre un alt pointer care este membru al unei
clase (pointer spre pointer).
In primul caz(.*),primul operand trebuie sa fie un obiect membru
al unei clase,iar cel de al doilea operand trebuie sa fie un
pointer de acelasi tip de data cu membrul din primul operand.
EXEMPLU: int Obiect .* int *po
-47-
Pentru operatorul ->*,primul operand trebuie sa fie un pointer din
acelasi tip de date cu pointerul orientat spre un membru al unei clase
ce se afla in cel de al doilea operand(ambii pointeri trebuie sa fie de
acelasi tip).
EXEMPLU: int *pObiect,*pMembruFunc;
(pObiect->*pMembruFunc) (6);
este pointer spre pointerul int spre membrul al saptelea
& -este operator de referinta.Este specific pentru limbajul C++.
Spre deosebire de operatorul de adresa din limbajul C,in limbaj C++
o referinta este o data de sine statatoare de 16 sau 32 biti (2-4
octeti) care contine adresa de memorie a unui obiect si care se
comporta din punct de vedere sintactic la fel ca un obiect.
Declararea unui referinte se face prin o lista optionala de specifica-
tori,operatorul de referinta (&) si numele obiectului(referintei).
Sintaxa generala este: specificatori & identificator
EXEMPLU: void Functie(int& x)
{
x +=2; //functia adauga 2 la valoarea lui x
}
int x;
x=3; //x este 3
Functie(x); // adauga 2 la x,adica x este 5
printf("%d", x );
Operatorii prezentati mai sus sunt evaluati in expresii in ordinea
precedentei (prioritatii) lor si executati in aceeasi ordine.Precedenta
operatorilor C++,si modul lor de asociere in situatiile in care exista
mai multi operatori cu aceeasi precedenta,sunt dupa cum urmeaza:
++ postfix(de la stanga la dreapata ) -- postfix () [] -> .
++ prefix (de la dreapta la stanga) -- prefix ! ~ - + & *(ind)
sizeof new delete (tipul datei) .* ->*(de la stanga la dreapta)
*(multiplicare) / % + - << >> < <= > >= == != &(AND)
^ && || ?: = *= /= %= += -= <<= >>= &= ^= |= virgula(,)
Precedenta maxima este pentru ++ postfix iar cea minima este pentru vir-
gula(utilizata ca operator).
Nu are rost sa invatati lista de precedente ci este bine sa utilizati un
tabel de precedenta a operatorilor atunci cand programati expresiile.
Este util si un tabel cu specificatorii si modificatorii identificatoru-
lui si eventual cateva fise de functii,pentru principalele biblioteci de
functii standardizate sau adaugate de d-voastra.In viitor,probabil ca
programele vor avea si aplicatii care sa efectueze automat toate aceste
operatiuni,impreuna cu verificarea prin executie a fiecarei expresii.
Combinand constantele si variabilele declarate,cu cuvintele cheie
si un numar oarecare de operatori,se pot formula un numar destul de
complex de expresii,pentru a determina operatii asupra unor date destul
de variate.Auxiliar fata de cele prezentate pana acum,exista si o serie
de conventii ce permit reprezentarea de caractere speciale cu rol fun-
ctional(Exemple: newline=salt la linia urmatoare).Aceste conventii poarta
numele de secvente de scapare,sunt optionale,se pot utiliza in timpul
editarii programelor pentru a determina aspectul textelor redactate.
-48-
Secventele de scapare sunt:
\a -alarma(bell)
\b -backspace(sterge un caracter)
\f -formfeed(incarca un caracter)
\n -new line(linie noua)
\r -carriage return (retur de car)
\t -horizontal tab (tab orizontal)
\v -vertical tab (tab vertical-spatiu gol pe verticala)
\? -Literal quotation mark (citat literal)
\' -single quotation mark (apostrof)
\" -double quotation mark (ghilimele)
\\ -backslash (liniuta de separatie)
\ddd -ASCII octal(caracterul ASCII in notatie octala)
\xdd -ASCII hex(caracterul ASCII in notatie hexazecimala)
\0 -Null character(caracterul nul-spatiu gol)
Aceste conventii se utilizeaza pentru a asigura un anumit format pentru
textele editate si imprimate cu ajutorul unor rutine din programele scrise
de d-voastra.Nu ezitati sa experimentati.
CLASELE DE MEMORIE
In functie de specificatorul de clasa utilizat,clasele de memorie(cele
utilizate pentru arhivarea variabilelor,structurilor,obiectelor) pot fi
de tip auto,intern static sau extern.Prin aceasta se desemneaza modul in
care se va putea avea acces la datele arhivate.
Pentru arhivarea datelor se va putea utiliza memoria stiva,registri de
memorie sau memoria de RAM(cu acces aleator).In sinteza,tipul de arhivare
a datelor se face dupa cum urmeaza:
CLASA DE MEMORIE ZONA DE ALOCARE PERIOADA DE TIMP
________________________________________________________________________
auto stiva sau registru temporar
register stiva sau registru temporar
static psect (RAM) permanent
extern psect (RAM) permanent
Prin stiva se inteleg date care sunt ordonate succesiv dupa principiul
LIFO(Last In First Out),adica ultimele intrate pot fi eliberate primele.
Primul element din stiva este baza stivei,iar ultimul intrat este varful
stivei.La un moment dat,se poate scoate din stiva doar elementul din
varful stivei.Ca rezultat,variabilele declarate auto trebuie actualizate
la fiecare intrare in bloc sau in functie,altfel contine valori reziduale.
Variabilele declarate register se arhiveaza in registrii procesorului (in
memoria de operare a procesorului) si ca rezultat sunt gasite si executate
mai rapid decat celelalte variabile.Daca registrii procesorului sunt ocu-
pati cu alte date,atunci variabilele register vor fi arhivate in memorie.
Variabilele declarate static pot fi apelate doar in cadrul functiei in
care au fost declarate.Cele declarate extern,sunt globale si pot fi ape-
late din oricare dintre functiile programului sau chiar si din alte
module(file de program).
Nu trebuiesc confundate clasele de memorie cu cele de obiecte din C++.
Clasele de memorie specifica structura hardware utilizata pentru arhivarea
datelor iar cele de obiecte reprezinta doar date organizate structurat.
-49-
TIPURI DE DATE STRUCTURATE
TABLOUL(aria):-reprezinta un set de elemente de acelasi tip.Poate fi
unidimensional(sir),bidimensional(matrice) sau multidimensional.
Se declara cu ajutorul parantezelor drepte [].Pentru cele multidimensio-
nale,fiecare noua dimensiune va fi inclusa in paranteaza patrata separata.
EXEMPLU: int Tablou [3][2][2][5] declara o arie cu patru dimensiuni ce
va contine 3*2*2*5=60 de elemente distincte grupate cate 5.
Tablourile pot contine date de orice tip.Declararea dimensiunii ariei
este optionala.Tabloul unidimensional este denumit uneori vector(desi nu
este un vector).Dimensiunea unei arii este data de tipul datelor inmultit
cu numarul de elemente(dim*sizeof()).Cand declarati arii mul-
tiple,este bine sa calculati si volumul de memorie ocupat(evitati sa
declarati arii mult mai mari decat sunt necesare scopului propus).
Un tablou poate fi initializat cu ajutorul unei liste in care elementele
se separa prin virgula si se includ intre acolade.
EXEMPLU: int Tablou[3]={13,25,67}
In cazul unui tablou bidimensional,elementele sunt memorate in line,in
ordinea: EXEMPLU: int TAB[3][2]
elementele vor fi: TAB[0][0],TAB[0][1],TAB[1][0].......TAB[2][1]
In cazul unui tablou bidimensional,initializarea se poate face cu doua
liste,sau cu o singura lista:
EXEMPLU: int TABEL[2][3]=
{
{1,2,3}, sau int TAB[2][3]={1,2,3,4,5,6}
{4,5,6}
};
rezultatul este acelasi.Initializarea se face pe coloane(primul,al doilea
,al treilea...pana la ultima coloana,apoi incepe randul urmator).
Un pointer spre un tablou trebuie sa fie de acelasi tip de data cu cele
din tablou.Un pointer poate parcurge toate elementele tabloului.Prin
operatiile de adunare sau scadere,un pointer sa va referi la unul dintre
elementele tabloului sau respectiv la cel din pozitia rezultata in urma
operatiei(se schimba de la un element la altul).
Un tablou unidimensional de tip char este un sir de caractere.Se declara
cu ajutorul ghilimelelor si este de tip static.Poate fi declarat si ca
variabila.EXEMPLU: char TABLOU[7]="tablou";
Lungimea sirului de caractere este cu un element mai mare decat numarul de
caractere ce apar intre ghilimele.
Un tablou poate fi transmis unei functii,nu prin valoarea sa ci prin
adresa sa,caz in care functia va putea modifica din continutul tabloului.
EXEMPLU: f(tab) sau f(int tab[])
int tab[];
Eventual se poate transmite unei functii doar o parte a unui tablou,cu
ajutorul unui pointer.EXEMPLU : f(&tab[5])
Un tablou poate fi format numai din pointeri,caz in care toti pointerii
sunt orientati spre tipul de data specificat in declaratie.
Tablourile de pointeri prezinta urmatoarele avantaje:-accesul la un ele-
ment se face prin adresare indirecta(printr-un pointer) iar dimensiunea
tablourilor pointate de un element de tablou poate fi variabila(pointerul
poate indica lungimi diferite),deci definitiile sunt mai scurte.
-50-
Pentru limbajul C,un tablou,fata de o variabila simpla este ca si un
cuvant fata de o litera.Pentru declaratie,sintaxa generala este:
SPECIFICATOR DE TIP IDENTIFICATOR [dimensiune1]...[dimensiuneN]
EXEMPLU: int Biblioteca[400]
Primul element al unui tablou este notat cu zero.Astfel,numarul de ele-
mente din tablou va fi mai mare cu unul decat numarul din [dimensiune].
Numele unui tablou fara indice este un pointer spre primul element al
tabloului.
Tablourile unidimensionale pot fi initializate si fara sa fie dimensi-
onate anterior.
EXEMPLU: char Eroare1 []="Eroare de citire a datelor";
Se utilizeaza atunci cand se introduc siruri de caractere cu dimensiune
variabila si nu doriti sa numarati elementele fiecarui sir.
Pentru a afla dimensiunea unui tablou declarat fara dimensiune se va
putea utiliza sizeof(in exemplu: sizeof Eroare1).
Pentru a apela un element dintr-un tablou declarat,se va utiliza doar
numele tabloului si numarul elementului.
EXEMPLU: int DATE[7]; //declara tabloul DATE
DATE[5]; //apeleaza elementul al saselea din DATE
Pentru a modifica dinamic datele unui tablou,trebuie sa poata fi apelate
(solicitate) din interiorul unor functii sau variabile situate la distante
mai mici sau mai mari in cadrul programului.Pentru acest scop,se utili-
zeaza niste variabile speciale denumite "pointeri",care contin adresa de
memorie la care sunt stocate datele respective.Practic un pointer este o
variabila care contine si o instructiune de tipul "GOTO...adresa ".
Pentru declararea unui pointer spre un tablou,trebuie ca pointerul sa fie
declarat cu acelasi tip de date ca si cele din tablou,dupa care i se atri-
bue numele de identificare al tabloului(identificatorul).
EXEMPLU: int PROBA[10]; //se declara tabloul
int *p; //se declara un pointer de acelasi tip
p=PROBA; //pointerul primeste adresa tabloului(se mai
utilizeaza si expresiile "pointeaza","indica"
sau "se orienteaza" spre tabloul respectiv
Pointerul realizat va contine adresa primului element din tablou.Pentru a
obtine orientarea pointerului spre un anumit element din tablou,se pot
utiliza operatii simple sau bucle incrementale.
EXEMPLU: char sir[20],*p; //declara tabloul si pointerul
p=sir; //pointerul este orientat spre sir
*(p+4) //apeleaza elementul 5 din sir (indirect)
sir[4] //apeleaza direct elementul 5 din sir
Cele mai multe greseli de programare sunt datorate apelarii incorecte
Dostları ilə paylaş: |
|
|