Hibridizarea orbitalilor


Pentru moleculele substantelor organice teoria MLV nu poate da explicatii privind structura acestora.
Pentru atomul de C sunt posibile doar 2 covalente rezultate prin punerea in comun a celor 2 electroni neimperecheati.

In realitate C are 4 covalente, orientate tetraedric la 109o28' , cum se observa in cazul CH4.
La apropierea unui atom de H orbitalii s si p puri ai C se deformeaza si rezulta 4 orbitali hibrizi sp3, cu energii egale si intermediare ca valoare intre cea corespunzatoare nivelului 2s si 2p.


Cei patru orbitali rezultati au o forma bilobara asimetrica, permitand o suprapunere mai buna cu alti orbitali si deci legaturi mai puternice.
Cei 4 orbitali vor fi distribuiti spatial astfel incat distanta dintre ei sa fie maxima, obtinandu-se o orientare tetraedrica a orbitalilor hibrizi .


Prin combinarea orbitalilor s si p (numai 2 dintre ei) rezulta 3 orbitali , de energie egala, orientati in plan la 120o si un orbital p perpendicular pe planul lor.


Orbitalii sp2 sunt bilobari si asimetrici, permitand legaturi puternice, in timp ce orbitalul tip p poate participa la realizarea unei legaturi .

Structura etenei C2H4


Evident, legatura este ceva mai slaba decat celelalte legaturi datorita unei suprapuneri mai reduse a orbitalilor, ea fiind cea mai reactiva, adica se poate rupe cel mai usor.
Prin combinarea unui orbital s cu unul p rezulta 2 orbitali sp, de energie egala, orientati in plan la 180o si doi orbitali p perpendiculari pe planul lor. 


Orbitalii sp sunt bilobari si asimetrici, permitand legaturi puternice, in timp ce orbitalii tip p, perpendiculari intre ei, pot participa la realizarea unor legaturi .

Hibridizarea

În cazul atomului de Si există de asemenea un fenomen de hibridizare care stă la baza silicaţilor şi siliconilor .
Intre legaturile O-Si-O ale tetraedrului (Si O4)4-, elementul structural de baza al silicatilor, unghiurile sunt de 109 grade ca si in cazul legaturilor H-C-H ale metanului.


Există şi alte tipuri de hibridizare, cum ar fi de exemplu sp3d.

Corelatia structura - proprietati pentru legatura covalenta

Orientarea legaturilor din moleculele organice in care C este hibridizat explica aranjamentul in zig-zag al lanturilor moleculare ale polimerilor. Legatura nu este rigida, permitand rotatii in jurul ei, ce explica si impachetarile acestor lanturi (elastomeri).
In diamant (C pur) exista un aranjament tetraedric al atomilor de C, datorat hibridizarii sp3, ce imprima duritate si casanta; diamantul este un izolator electric, electronii fiind localizati la fiecare atom.

In cazul grafitului, forma alotropica a C, atomii sunt hibridizati sp2, ca si in etena, formand o retea hexagonala stratificata.

Intre planele hexagonale exista legaturi slabe, datorate distantelor mari, fapt ce explica clivajul grafitului.

De asemenea prezenta electronilor delocalizati la toti atomii dintr-un plan explica buna lui conductivitate electrica.

MLV- dezavantaje

Dezavantajul metodei este reprezentat de numarul mare de structuri limita in cazul moleculelor complexe, precum si faptul ca nu pot fi explicate unele proprietati ale moleculelor, cum ar fi paramagnetismul moleculei O2.


Orbitalii prin care se realizeaza legatura in molecula de O2 vor fi complet ocupati cu 2 perechi de elctroni de spin opus, proprietatile magnetice corespunzand unei substante diamagnetice; in realitate molecula O2 este paramagnetica.

Abordarea cuantica a legaturii chimice



Abordarea cuantica a legaturii chimice


Abordarea cuantica a problemei legaturii chimice se face utilizand metoda LCAO = Linear Combination of Atomic Orbitals, ce considera functia de unda a electronilor implicati in legatura
electroni imposibil de deosebit intre ei, ca fiind o combinatie liniara a functiilor de unda caracteristice electronilor din fiecare atom
 respectiv si :

CA si CB sunt coeficienti, de la a caror stabilire incep sa apara diferente intre diferitele metode de aproximare. Au aparut Metoda Legaturii de Valenta - MLV elaborata de Linus Pauling şi John Slater şi Metoda Orbitalilor Moleculari - MOM elaborată de Friedrich Hund şi Robert Mullikan.

Metoda legaturii de valenta

Premisele MLV

legatura covalenta se realizeaza prin cuplarea electronilor cu spin opus din orbitalii atomici de energie ridicata incomplet ocupati. 


Functia de unda corespunzatoare electronilor implicati in legatura 

este o combinatie liniara a functiilor de unda corespunzatoare unor structuri limita:


Structurile limita reprezinta toate cazurile ipotetice in care se pot afla electronii implicati in legatura.

Structuri limita - exemplu


In cazul structurii I ambii electroni sunt localizati la primul atom de H, in structura tip II electronii se gasesc la atomii din care provin, structura III corespunde cazului schimbului de electroni, iar in structura IV ambii electroni sunt localizati la al doilea atom de H.

Exista 4n structuri limita, unde n este numarul de covalente din molecula.

Premisele MLV

Legatura covalenta se realizeaza prin suprapunerea orbitalilor atomici, marimea interpatrunderii lor determinand taria legaturii.
Legatura formata cand orbitalul molecular are simetrie de rotatie fata de axa care uneste cele 2 nuclee se numeste legatura σ


Astfel, datorita gradului crescut de suprapunere a orbitalilor, legatura formata din 2 orbitali p, notata p-p, este de 1,73 ori mai puternica decat cea tip s-s; legatura de tip d-d este de 2,236 ori mai puternica decat cea s-s.

Legatura formata cand orbitalul molecular are simetrie fata de planul care trece printre cele 2 nuclee se numeste legatura .


Orbitalii tip p pot participa la realizarea de legaturi si ;celorlalti orbitali le este specifica doar legatura .

Metoda MLV

MLV aplicată reţelei metalice presupune formarea unor legături covalente delocalizate. Astfel, electronii din stratul exterior al unui atom metalic din reţea se pot afla, pe rând, în orbitalii rezultaţi prin interpătrunderea orbitalilor tuturor vecinilor de reţea. Cu cât gradul de ocupare al acestor orbitali creşte, cu atât tăria legăturii metalice şi deci si proprietăţile mecanice şi temperatura de topire cresc.
Acest lucru se întâmplă odată cu creşterea numărului de electroni din straturile exterioare.

MLV si teoria legaturii chimice

Natura legaturii este fizica, fiind rezultatul tendintei fiecarui atom de a ajunge intr-o stare caracterizata de o energie cat mai mica. Valoarea energiei sistemului, rezultata din calcule in ipoteza MLV este prezentata in figura

Nivelul 0 a energiei sistemului corespunde sumei energiilor corespunzatoare celor 2 atomi implicati in legatura, aflati in stare libera. La apropierea lor energia sistemului scade pana la o valoare minima, Eleg la distanta ro.

Energia eliberata la formarea unei legaturi din atomi adusi de la o distanta la care nu interactioneaza se numeste energie de legatura Eleg. 

MLV si teoria legaturii chimice

Orientarea in spatiu a legaturilor este data de unghiurile facute intre ei de orbitalii puri p, d sau f. Astfel, pentru molecula H2S:


Unghiul teoretic dintre legaturi este de 90grade, iar cel gasit experimental este de 92grade.

Teoria „legăturii metalice”





Metalele au o serie de proprietăţi care le deosebesc net de celelalte substanţe şi anume:
Proprietăţi electrice şi termice - conductibilitatea electrică şi termică foarte bună;
Proprietăţi optice - luciu specific, opacitate;
Proprietăţi mecanice - ductilitate, maleabilitate;
Insolubilitatea în solvenţi, cu excepţia metalelor topite.
Niciuna din teoriile prezentate până acum nu poate explica conductibilitatea electrică a metalelor, astfel încât era nevoie de o altă teorie pentru acest gen de substanţe.
De asemenea, atomii metalelor au în general un număr mic de electroni pe ultimul strat, ei neavând posibilitatea să ajungă la starea stabilă de octet nici prin cedare de electroni, atomii fiind identici, nici prin punere în comun de electroni.
Pentru explicarea proprietăţilor metalelor K.Drude şi H.Lorenz au considerat că reţeaua metalică este constituită din ioni pozitivi, ce se găsesc în noduri, formaţi din atomii ce au pierdut electronii de pe straturile exterioare şi un nor electronic alcătuit din electronii delocalizaţi. Este, de fapt, o legătură de tip ion-electron delocalizat.

Natura „legăturii metalice” este electrostatică, coeziunea reţelei fiind asigurată de atracţia dintre ionii pozitivi din nodurile reţelei şi electronii liberi.
„Legătura metalică” nu este orientată ceea ce permite aşezarea foarte compactă a particulelor constituiente în nodurile reţelei, un argument în favoarea acestei teorii.
Explicarea calitativă a unor proprietăţi ale metalelor este prezentată în continuare:
Conductibilitatea electrică foarte bună este atribuită electronilor liberi care se pot mişca sub acţiunea unui câmp electric extern;
Conductibilitatea termică foarte bună este, de asemenea, atribuită contribuţiei electronilor liberi;
Opacitatea este explicată prin aceea că în substanţele transparente (şi care în acelaşi timp nu conduc curentul electric) electronii sunt localizaţi şi puternic legaţi ceea ce face ca oscilaţiile electromagnetice să fie transmise mai departe prin vibraţii de aceeaşi frecvenţă fără pierdere de energie;
Maleabilitatea şi ductilitatea sunt explicate prin lipsa orientării „legăturii metalice” ceea ce face ca existenţa unor deformaţii traduse prin deplasări ale unor noduri ale reţelei faţă de altele să nu existe influenţe asupra tăriei legăturii;
Existenţa electronilor liberi, ca un „gaz electronic” este susţinută şi de faptul că energia necesară pentru a îndepărta un electron de pe suprafaţa metalului este mai mică decât energia de ionizare. De asemenea, autorii teoriei au putut determina, folosind elemente de teorie cinetico-moleculară pentru „gazul electronic”, raportul dintre conductivitatea electrică şi termică, ce are o valoare aproape constantă indiferent de metal.
Totuşi, teoria nu a reuşit să ofere explicaţii dincolo de nivelul calitativ decât într-un caz, menţionat anterior şi nici să ajute sau să explice variaţia unor proprietăţi ale metalelor.


Polaritatea moleculelor si Momentul de dipol

Polaritatea moleculelor


Legatura covalenta pura se intalneste doar in moleculele homonucleare, adica acelea constituite din atomi identici.
Atat legaturile ionice cat si cele covalente heteronucleare nu sunt pure, legaturile ionice avand si caracter covalent si invers; legaturile reale sunt covalent-polare.
Moleculele, desi neutre in ansamblu, poseda un numar de sarcini pozitive, localizate in nucleele atomice si sarcini negative repartizate in jurul acestora. Se poate admite existenta, ca in cazul centrului de greutate, a doua centre ale sarcinilor electrice, unul pentru cele pozitive si unul pentru cele negative.
Moleculele in care cele doua centre coincid se numesc nepolare, celelalte fiind molecule polare.

Momentul de dipol

Moleculele polare pot fi asociate unor dipoli electrici, caracterizati de momentul de dipol :


unde       este vectorul de pozitie cu originea in centrul atribuit sarcinilor negative si varful in centrul corespunzator sarcinilor pozitive.
Unitatea de masura pentru momentul de dipol este
1 D (Debye) =

Polaritatea moleculelor este rezultatul diferentei de electronegativitate dintre atomii componenti, cei mai electronegativi determinand o crestere a densitatii electronice in apropierea lor.
In molecula HF, cei doi electroni pusi in comun sunt deplasati spre F, mai electronegativ, fapt ce determina aparitia unei polarizari a moleculei.
este o fractiune a sarcinii elementare
In acest mod, legatura covalenta H-F nu este pura ci are si un caracter ionic. 


Momentul de dipol al moleculei de apa

Momentul de dipol al unei molecule este suma vectoriala a momentelor de dipol ale legaturilor dintre atomii constituienti.

Molecula de apa are un moment de dipol de 1,84D ca rezultat al compunerii geometrice ale momentelor de dipol ale legaturilor O-H (1,54D), ce fac intre ele un unghi de 105o.
Polaritatea moleculelor de apa are mare importanta, ea putand dizolva majoritatea substantelor ionice.

Caracterul ionic al legaturii

Momentul de dipol al unei legaturi ionice, ar trebui sa fie egal cu produsul dintre sarcinile ionilor implicati si distanta dintre ei (in A).
Raportul dintre momentul de dipol masurat experimental si cel calculat dupa cel cel mentionat anterior este o masura a caracterului ionic al legaturii:

caracterul ionic al legaturii=  (%)

Existenta caracterului covalent si in cazul legaturii ionice poate fi explicata prin deformarea pe care fiecare ion o produce asupra invelisului electronic a ionului vecin de semn opus, cu aparitia unei suprapuneri a acestora.

Teoria „legăturii covalente”




Legatura covalenta se formeaza prin punere in comun de electroni de catre doi atomi intre care exista o diferenta redusa de electronegativitate.
Pentru atomii implicati in legatura se realizeaza configuratii electronice stabile, in general cu 8 electroni pe ultimul strat conform teoriei electronice a lui Lewis si Langmuir.
Legatura realizata prin intermediul unei singure perechi de electroni se numeste legatura simpla; implicarea a doua perechi de electroni conduce la formarea unei legaturi duble, iar a 3 perechi la legaturi triple.
Electronii pusi in comun se numesc electroni participanti si se noteaza schematic printr-o liniuta : Cl-Cl.
Exemple de legaturi covalente
Simpla

Dubla

Tripla


„Legătura covalentă” conduce la formarea de molecule cu număr bine definit de participanţi.
Valenţa unui atom legat covalent este dată de numărul perechilor de electroni puse în comun cu vecinii săi din moleculă.
Există situaţii in care punerea în comun de electroni conduce doar la realizarea parţială a octetului de electroni pe ultimul strat pentru unul din parteneri, molecula rezultată fiind reactivă, atomul cu învelişul incomplet manifestând tendinţa de a accepta electroni de la un altul – acceptor de electroni.
În acest mod se poate forma o „legătura covalentă” în care un atom pune în comun o pereche de electroni neparticipanţi într-o altă legătură – atom donor, cu un atom/ion care nu are realizat octetul/dubletul pe ultimul strat – atomul acceptor; această legătură poartă denumirea de „legătură covalentă coordinativă”.
În cazul ionului amoniu – NH4+, cei 2 electroni neparticipanţi la legături ai N din amoniac NH3, pot fi puşi în comun cu un ion de H, care are un orbital liber, rezultând un ion pozitiv:

„Legătura covalent coordinativă” apare şi între moleculele conţinând un atom cu deficit de electroni, care are deci un octet incomplet - molecule acceptoare şi molecule conţinând atomi capabili să pună la dispoziţie electroni - molecule donoare, cum este cazul complexului H3N×BH3.


Cum a fost enunţat anterior, o teorie a legăturii chimice trebuie să explice natura legăturii, orientarea în spaţiu şi să coreleze structura cu proprietăţile moleculei - definită ca fiind cea mai mică parte a substanţei care păstrează proprietăţile acesteia.
Natura legăturii este electrostatică, manifestându-se prin forţele ce apar între nucleele pozitive şi electronii puşi în comun.
În privinţa formei moleculelor şi orientării legăturilor teoria trebuie completată cu VSEPR – Valence Shell Electron Pair Repulsion elaborată în 1957 de R.Gillespie şi R. S. Nyholm. Această teorie consideră că există o repulsie între perechile de electroni participanţi/neparticipanţi la legătură,în urma căruia acestea vor adopta un aranjament ce minimizează această respingere, fapt ce se reflectă în orientarea legăturilor şi implicit în geometria moleculei. Folosind aceste teorii se pot prevedea cu succes formele unor molecule, de exemplu forma piramidala a moleculei NH3.
Corelaţia structură – proprietăţi este limitată; nu poate fi prevăzut/explicat comportamentul unor substanţe şi nici forma moleculelor. Există o serie întreagă de excepţii - PCl5 -10 electroni pe ultimul strat pentru P, SF6 - 12 electroni pentru S şi chiar 14 electroni în cazul IF7. De asemenea, metalele tranziţionale nu formează anioni (ioni negativi) ci cationi, care nu au obligatoriu structură de gaz rar.


Teoria „legăturii ionice”




Teoria clasică a legăturii ionice, elaborată în 1916 de W.Kossel, presupune faptul că atomii elementelor tind către o configuraţie mai stabilă de gaz nobil, fie prin cedare fie prin acceptare de electroni, rezultând ioni pozitivi sau negativi mai stabii decât atomii iniţiali. Atracţia electrostatică dintre ionii de semn opus conduce la o apropiere a acestora, până la o distanţă la care se realizează echilibrul cu forţele de respingere dintre învelişurile electronice ale acestora.Astfel, natura „legăturii ionice” este atracţia electrostatică dintre ioni de semn opus.
Teoria electronică clasică consideră legătura chimică rezultatul interacţiunii dintre electronii din stratul exterior, numiţi electroni de valenţă şi postulează că octetul de electroni reprezintă o configuraţie electronică extrem de stabilă. Din această cauză gazele rare, care au 8 electroni pe ultimul strat, sunt practic inerte din punct de vedere chimic, ceilalţi atomi reacţionând între ei în vederea ajustării configuraţiei electronice şi dobândirii uneia stabile.
Elementele din grupele I si II principale au tendinţa de a ceda 1 respectiv 2 electroni şi a ajunge astfel la configuraţia stabilă cu 8 electroni pe ultimul strat, devenind ioni pozitivi. Această tendinţă este pusă în evidenţă de valorile energiei de ionizare mici a metalelor alcaline (v. tab. 1.2.)
Elementele cu 6-7 electroni pe ultimul strat (cele din grupele VI - VII principale) au o tendiţă redusa de a pierde electroni, manifestată prin energii mari de ionizare şi o afinitate mare pentru electroni (în modul) - tabelul 1.2, formând ioni negativi.
Elementele din grupele secundare ale sistemului periodic au pe ultimul strat 1-2 electroni, manifestându-se tendinţa de a se forma ioni pozitivi şi prin pierderea unor electroni de pe penultimul strat, ceea ce explică existenţa mai multor tipuri de ioni pentru acelaşi element.
Valenţa electrochimică a unui atom este reprezentată în teoria lui Kossel de numărul de electroni primiţi sau cedaţi.
Urmărind datele din tabelul 1.2 se observă că energia cedată la formarea unui ion negativ, (Cl- ,de exemplu, 3,74 eV) nu este suficientă pentru ionizarea nici măcar a Cs.
Teoria „legăturii ionice”
Combinaţiile ionice apar spontan şi din elementele aflate în stare liberă datorită existenţei şi a altor factori energetici.
Astfel, la formarea unei substanţe ionice solide intervine -energia de reţea, definită ca fiind energia ce se degajă la formarea unui mol de substanţă cristalizată din ioni aflaţi iniţial la infinit. Starea solidă este o stare caracterizată de o energie scazută, diferenţa dintre energiile corespunzătoare particulelor componente - atomi, molecule, luate separat şi integrate în structura simbolizând energia de reţea.
Pentru a înţelege mai bine originea energiei de reţea să urmărim schema din figura 2.1.

Energia de atractie electrostatica a celor doua perechi de ioni luate separat este de  , 
in timp ce pentru cazul in care au fost integrate in structura, aceasta creste in valoare absoluta la

Semnul minus este specific interactiilor atractive.


Energia cedata la integrarea ionilor in retea poate determina formarea in continuare a ionilor, proces care este endoterm in ansamblu.
Astfel, la formarea NaCl din Na (g) si Cl (g) exista:
un proces endoterm - ionizarea Na necesita 5,14 eV: Na®Na++e-
un proces exoterm - ionizarea Cl ce elibereaza 3,74 eV: Cl+e-®Cl-
un proces exoterm - integrarea ionilor in retea ce elibereaza~8 eV
Pe ansamblu procesul este exoterm ceea ce arata ca acesta este sensul natural de desfasurare a reactiei.
Pe lângă atracţia electrostatică dintre ioni o contribuţie la realizarea acestor combinaţii chimice o are şi suprapunerea norilor electronici ai ionilor, datorită atracţiei nucleelor vecinilor, astfel încât o „legătură ionică” nu este niciodată „pură”, existând şi o altă componentă datorată „legăturii covalente’ prezentate în subcapitolul următor.
Pe măsura ce diferenţa de electronegativitate dintre speciile atomice participante la „legătura ionică” scade, scade şi ponderea acestei legături în dauna „legăturii covalente”.
Legătura este preponderent ionică atunci când diferenţa dintre electronegativităţile relative ale atomilor implicaţi în legătura depăşeşte 1,7.
Energia de reţea depinde de mai mulţi factori, între care enumerăm:
sarcinile electrice ale ionilor;
razele ionice ale speciilor implicate, energia de reţea scăzând cu creşterea acestora;
modul de aşezare a ionilor în reţea.
Cu cât energia de reţea este mai ridicată, cu atât stabilitatea combinaţiei este mai mare.
Reţinem că în cazul legăturii „ionice” nu se formează molecule, ci nişte asociaţii deschise în care fiecare ion tinde să se înconjoare de ioni de semn opus, alcătuind un agregat tridimensional – reţeaua ionică. Astfel, formulele chimice ale combinaţiilor ionice nu reprezintă decât raportul de combinare al ionilor.
Legătura ionică este neorientată, ionii implicaţi putând avea practic orice poziţie unul faţă de celălalt, respectându-se evident alternanţa ion pozitiv - ion negativ.
Proprietăţile determinate de existenţa unei legături ionice sunt legate de formarea unor reţele ionice cu:
- temperaturi de topire relativ ridicate, ce denotă existenţa unei energii de reţea mari, de ordinul sutelor de KJ/mol,
-coeficient de dilatare mic;
-rezistenţe mecanice bune; solidele cu reţea ionică nu sunt deformabile, maleabile sau ductile, deoarece deplasarea unei porţiuni a cristalului faţă de cealaltă conduce la respingeri între ionii de acelaşi semn şi ruperea materialului (v. fig.2.3);
-proprietăţi de izolator electric în stare solidă şi de conductor în stare topită sau soluţie;
-solubilitate în solvenţi polari, datorită lipsei de orientare a legăturii.



Teoria lui Kossel a „legăturii ionice” nu rezolvă problema combinaţiilor care apar între atomii identici, neputând explica de ce unul dintre atomi ar deveni pozitiv şi celălalt negativ, arătându-şi astfel limitele.

Compuşii „ionici” de interes pentru domeniul construcţiilor vor fi prezentaţi împreună cu cei în care se manifestă şi „legătura covalentă” datorită acţiunii simultane a celor două „tipuri” de legături chimice.


Teoria legaturii chimice



Atomii pot interacţiona între ei în mai multe feluri, această proprietate stând la baza diversităţii prezente în tot ce ne înconjoară.
Legătura chimică reprezintă interacţiunea atractivă dintre doi sau mai mulţi atomi identici sau diferiţi, concretizată în realizarea unei noi entităţi.
Legătura chimică îşi are originea în tendinţa atomilor de a avea o încărcătura energetică minimă. Astfel, energia totală a unor atomi legaţi prin legături chimice este inferioară sumei energiilor atomilor luaţi separat.
Teoriile referitoare la legătura chimică trebuie să explice:
-natura legăturii dintre atomii componenţi;
-aranjamentul spaţial al acestora;
-relatiile dintre structură şi proprietăţi.
Există şi interacţii atractive care nu conduc în mod real la formarea unor noi combinaţii între atomi şi molecule, manifestându-se mai mult la nivelul unor proprietăţi fizice:
-legătura de hidrogen;
-legătura prin forţe van der Waals.

În privinţa naturii acestei interacţii atractive, să analizăm cazul în care doi atomi se apropie unul de celălalt. Electronii unui atom sunt atraşi din ce în ce mai mult de nucleul celuilalt atom, pe măsura micşorării distanţei interatomice. Impactul acţiunii de apropiere a atomilor este resimţit mai puternic de electronii din stratul exterior, aceştia fiind pe de o parte mai puţin atraşi de propriul nucleu şi mai puternic atraşi de către nucleul atomului vecin, cauza fiind distanţa dintre sarcinile pozitive şi negative. Acţiunile atractive ale celor două nuclee vor conduce la o apropiere a celor doi atomi, până la o distanţă la care respingerea electrostatică dintre învelişurile electronice va compensa această atracţie şi se va realiza un echilibru. Este posibil ca unii electroni sa fie favorizaţi în a se situa între cele două nuclee – ca şi cum ar aparţine ansamblului de doi atomi. Este, de asemenea, posibil ca unii electroni să treacă chiar în învelişul celuilalt, atracţia dintre cei doi atomi iniţiali (acum deveniţi ioni) fiind de asemenea de natură electrostatică. Raţionamentul de mai sus arată importanţa structurii electronice a ultimului strat, care decide în fapt modul în care atomii interacţionează.


Comportarea substanţelor exprimată prin seturi de proprietăţi a arătat că există mai multe categorii de substanţe; comportamentul acestor categorii a început sa fie explicat individual, apărând astfel teorii ale legăturilor chimice. Aceste teorii sunt valabile strict pentru categoriile corespunzătoare de substanţe:
-teoria legăturii ionice;
-teoria legăturii covalente;
-teoria legăturii metalice.


Teoriile enumerate mai sus, au un succes parţial şi nu sunt universal valabile.

Atomul- Structura si consecinte


Scopul acestui prim capitol este de a prezenta stadiul cunoaşterii structurii materiei din punct de vedere chimic şi de a crea premisele întelegerii  modului în care atomii interacţionează între ei.

Structura atomului

Divizibilitatea materiei până la o cea mai mică particulă denumită atom a fost susţinută de filozoful grec Democrit cu mult înaintea erei noastre.
Dalton, un chimist englez din secolul XVIII a considerat că toată materia este constituită din atomi care nu pot fi nici creaţi nici divizaţi.
În accepţiunea modernă atomul este cea mai mică parte de substanţă care nu mai poate fi divizată prin metode chimice.Un şir lung de descoperiri din domeniul fizicii au arătat că în fapt atomul este format din mai multe particule elementare: protoni, neutroni şi electroni.
     
Protonul este o particulă elementară cu masa de aproximativ 1.66*10-27 kg şi este încărcat electric cu o sarcină pozitivă egală cu sarcina electrică elementară: 1.6*10-19 C.
Neutronul este o particulă elementară cu masa practic egală cu a protonului şi care este neutru din punct de electric.
Electronul este o particulă elementară cu masa de 9.1*10-31 kg, de peste 1800 ori mai mică decât a protonului sau neutronului şi este încărcat electric negativ cu o sarcină electrică elementară.

Modele atomice clasice

      Pentru descrierea modului în care sunt aşezate aceste particule elementare au fost elaborate de-a lungul timpului mai multe modele atomice.
      J.J.Thompson, la începutul secolului XIX, a elaborat modelul unui atom „plin” în care sarcinile pozitive şi negative erau distribuite uniform. Modelul are doar importanţă istorică, neputând explica proprietăţile atomilor.
     

Modelul Rutherford

       Ceva mai târziu, Rutherford, în urma unor experienţe de împrăştiere a particulelor α pe un strat subţire (foiţă) de atomi de Au a elaborat modelul lacunar al atomului: protonul şi neutronul se găsesc în centrul atomului, într-o zonă cu dimensiuni foarte reduse şi densitate enormă - aproximativ  numită nucleu; în jurul acestuia se învârt, pe orbite circulare, electronii care alcatuiesc învelişul electronic. Atomul este aproape gol, masa lui fiind concentrată aproape toată în nucleu, fapt ce permite traversarea lui de către particule uşoare cum sunt cele α fără a fi deviate decât în cazuri rare. Numărul de protoni din nucleu se numeşte număr atomic Z; numărul de electroni din învelişul electronic este egal tot cu Z, pentru păstrarea neutralităţii electrice a atomului. Numărul de protoni şi neutroni din nucleu se numeşte număr atomic de masă A.

      Structura nucleului este mai puţin importantă pentru chimie şi face obiectul de studiu al fizicii nucleare. Structura învelişului electronic este determinantă pentru proprietăţile atomului şi prin acestea pentru comportamentul lui chimic.

      Conform legilor electrodinamicii clasice, o sarcină electrica în mişcare accelerata emite energie, astfel încât, un atom cu o astfel de structură este instabil, electronii căzând rapid pe nucleu.

Modelul Bohr

Pentru a elimina acest neajuns, Niels Bohr, un fizician danez,  a elaborat un model bazat pe două postulate, în care, ca o ironie a sorţii, nu a crezut până la moarte. Postulatele enunţau existenţa unor orbite ‘’staţionare’’ pentru care electronii în mişcare nu emit energie, iar trecerea de la o orbită staţionară la alta se face prin emiterea sau absorbtia unor cuante de energie egale cu diferenţa energetică dintre acestea. Modelul a introdus numărul cuantic principal ‘’n’’ care caracteriza aceste orbite staţionare. Modelul a reuşit să explice doar spectrul atomului de H.

Modelul  Bohr-Sommerfeld

Modelul  Bohr-Sommerfeld consideră că electronii se mişcă pe orbite eliptice cu nucleul în unul din focare. Dimensiunea şi forma elipselor (raportul dintre semiaxele a şi b) sunt  determinate de două numere cuantice, introduse arbitrar pe baza unor postulate, n - număr cuantic principal şi l - număr cuantic secundar.  Sunt permise numai orbitele eliptice pentru care:  
                                     l=0,1,...., n-1       
                                     a/b=n/(l+1)
                      
      Orientarea planului acestor elipse faţă de un câmp magnetic exterior este determinată de numărul cuantic magnetic m, care ia valori de -l până la +l, adică 2l+1 valori.  Această orientare este rezultatul interacţiei dintre câmpul magnetic creat de electronul în mişcare pe orbită şi cel exterior. De asemenea, pentru descrierea mişcării de rotaţie a electronului în jurul axei proprii s-a introdus numărul cuantic de spin s, care poate lua doar două valori. Aceste două valori au ca semnificaţie polarizările posibile ale câmpului magnetic generat de mişcarea electronului în jurul axei sale, mişcare de rotaţie ce poate avea doar două sensuri.
Toţi electronii şi orbitele corespunzătoare unui acelaşi număr cuantic principal n formează o pătură (strat) electronic. Aceste straturi electronice sunt alcătuite din substraturi, ce conţin orbite de excentricitate variabilă, determinată de valorile numărului cuantic secundar l.
Modelul Bohr-Sommerfeld a reuşit să explice unele dintre proprietăţile atomilor hidrogenoizi (cu un singur electron), fiind însă incapabil să le explice pe cele ale atomilor polielectronici.

Modelul cuantic al atomului

Principiul de nedeterminare Heisenberg - stabileşte o relaţie între incertitudinile în măsurarea simultană a două mărimi (de exemplu poziţie - x şi impuls - p):



 cu cât una dintre ele este măsurată mai precis cu atât incertitudinea de măsurare a celeilalte este mai mare. 
noţiunea de traiectorie (poziţie cunoscută cu exactitate în orice moment) a electronului îşi pierde semnificaţia.
Noţiunea de traiectorie - orbită a electronului va fi înlocuită cu probabilitatea ca acesta să se afle într-o zonă din spaţiu.
Modelul cuantic al atomului
dualismul corpuscul - undă; Louis de Broglie a emis ipoteza conform căreia oricărui corp în mişcare îi este asociată o undă cu lungimea de undă dată de relaţia:

unde:
h este constanta Planck =6.625*10-34J*s
m este masa particulei în mişcare;
v viteza de mişcare.
Electronului în mişcare îi va fi asociată o undă, ale cărei caracteristici depind de viteza acestuia.

Ecuatia Schrodinger

Considerând unda asociată electronului în mişcare şi scriind ecuaţia de propagare a acesteia in campul de forte al nucleului, Schrodinger ajunge la relaţia care îi poartă numele, scrisă în cele ce urmează în coordonate spaţiale:

unde:
este funcţia de undă, ce depinde de coordonate;
E operatorul energie totală a electronului;
V operatorul energie potenţială a electronului.
Funcţia de undă  nu are semnificaţie fizică; modulul funcţiei de undă - reprezintă probabilitatea de a găsi la un moment dat electronul în unitatea de volum:

Rezolvarea ecuaţiei Schrodinger pentru atomi/ioni cu un singur electron

       Rezolvarea ecuaţiei Schrodinger nu este însă posibilă din punct de vedere matematic decât pentru atomi sau ioni  cu un singur electron.
     
Solutiile acestei ecuatii  se obtin numai pentru anumite valori ale energiei, numite valori proprii si care sunt determinate de numerele cuantice n.l si m.

      Numerele cuantice n, l, m sunt în acest caz rezultate prin calcul şi nu introduse arbitrar ca în modelul Bohr - Sommerfeld.
       Pentru acelasi numar cuantic n energia nivelelor este aceeasi – nivelele cu acelasi n formeaza o patura.
      Zonele în care electronii se găsesc cu probabilitate ridicată (>90-95%) se numesc orbitali. Forma acestor orbitali depinde de valorile lui l:
      l=0, orbitali de tip s, sferici;
      l=1, orbitali de tip p, bilobari;
      l=2, orbitali de tip d, cu forme relativ complicate;
      l=3, orbitali de tip f, cu forme complicate.

Orbitali

Fiecărui tip de orbitali îi corespund 2l+1 orbitali cu forme sau orientări diferite. Astfel, pentru l=0 (orbitali tip s) există doar orbitali sferici, pentru l=1 (orbitali p) există 3 orbitali: px, py, pz, identici ca formă însă orientaţi în lungul axelor respective.




Rezolvarea ecuaţiei Schrodinger pentru atomi multielectronici

Pentru atomii cu mai mulţi electroni, rezolvarea aproximativă a ecuaţiei Schrodinger a condus la obţinerea unei imagini oarecum asemănătoare cu a atomului cu un electron.
Aproximatia consta in considerarea miscarii electronilor, neglijand interactiunile dintre ei, in campul electric creat de nucleu, care are insa o sarcina efectiva mai mica decat Z, datorita ecranarii produse de ceilalti electroni de pe paturile interioare.
Principala deosebire rezultata consta in despicarea nivelelor energetice corespunzatoare unei aceeasi paturi electronice, datorita interactiilor diferite dintre nucleu si electronii aflati in orbitali tip s, p, d si f

Contractia orbitalilor

Calculand functiile de unda pentru fiecare electron din atom se constata ca se produc unele inversiuni in ordinea energetica a orbitalilor, odata cu cresterea lui Z.
Fenomenul poarta denumirea de contractia orbitalilor si conduce la anumite modificari in ordinea de completare a straturilor electronice.
Astfel, pentru K, nivelul 4s este mai sarac in energie decat 3d, pentru Sc energia nivelelor este egala, iar incepand cu V orbitalii 3d au energie mai redusa decat 4s.

Despicarea nivelelor energetice


Ordinea de completare a invelisului electronic

Ocuparea cu electroni a orbitalilor se face :
în ordinea creşterii energiei acestora;
conform principiul lui Pauli:
Fiecare orbital poate fi ocupat de maxim 2 electroni cu spinii antiparaleli.
regulilor lui Hund:
la completarea unui strat cu electroni se ocupă maximum de orbitali;
în acelaşi substrat electronii necuplaţi au spin paralel.

Ordinea creşterii energiei orbitalilor se poate stabili cu regula (n+l):
orbitalul cu suma (n+l) mai mică este de energie mai scăzută,
pentru aceeaşi sumă (n+l) orbitalul cu n mai mic are energia mai scăzută.
Ordinea de ocupare cu electroni a orbitalilor poate fi stabilită utilizând şi următoarea schemă (fig).

Schema practica pentru stabilirea ordinii de completare a straturilor electronice

Hibridizarea orbitalilor

Matematic se poate demonstra ca o combinatie liniara a solutiilor ecuatiei lui Schrodinger este o solutie a acesteia. Noile solutii se numesc orbitali hibrizi, operatia numindu-se hibridizarea orbitalilor.
Orbitalii hibrizi se noteaza pornind de la cei de la care s-a plecat si au energii intermediare orbitalilor initiali: ,,,.
Orbitalii hibrizi  provin dintr-un orbital s si 3 orbitali tip p si au forme si energii diferite de cei initiali.



Curs C

String-uri (Cap. 9)

             Ne propunem să studiem modul în care se memorează şi cum se lucrează cu un string în
limbajul C.
În C, un şir de caractere care se termină cu caracterul NULL sau ‘\0’ sau pur şi simplu 0
(de unde şi denumirea de şir de caractere NULL terminat) este echivalentul noţiunii de string din
alte limbaje (cum ar fi de exemplu limbajul Pascal). În consecinţă, în C o variabilă string este de
fapt un pointer de tipul char. Fiind vorba de un şir, alocarea memoriei pentru un string se poate
face atât static cât şi dinamic.
În fişierul antet stdio.h avem definite funcţiile gets şi puts pentru citirea unui string de la
tastatură, respectiv afişarea pe ecran a unui string. Ambele funcţii primesc ca parametru o
variabilă de tip pointer către tipul char.
Funcţia gets, spre deosebire de scanf poate citi string-uri care conţin spaţii. În cazul
funcţiei scanf se consideră încheiată introducerea unei valori pentru o variabilă când se întâlneşte
caracterul spaţiu sau unde s-a apăsat Enter. De exemplu, dacă se citeşte Popescu Ioan pentru un
string s de la tastatură cu gets(s), atunci la adresa s se depun caracterele Popescu Ioan’\0’. Dacă
citirea se face însă cu scanf(“%d”,s), atunci la adresa s se depun caracterele Popescu’\0’ (citirea
lui s se încheie la apariţia spaţiului).
Dacă se afişează un string s cu puts(s); atunci după afişarea şirului de la adresa s se face
salt la începutul liniei următoare, ceea ce nu se întâmplă dacă afişarea se face cu printf(“%s”,s).
Fişierul antet string.h conţine definiţiile funcţiilor C de lucru cu string-uri:

1) strcat(s1, s2) la sfârşitul string-ului s1 se adaugă s2 şi caracterul ‘\0’.
2) strchr(s,c) returnează adresa de memorie către prima apariţie a caracterului c în
string-ul s. Dacă nu există caracterul în string, se returnează adresa nulă ( NULL).
3) strcmp(s1,s2) returnează o valoare întreagă care dacă este 0, înseamnă că şirurile sunt
identice ca şi conţinut. Dacă valoarea returnată este negativă, atunci înseamnă că
string-ul s1 este înaintea lui s2 din punct de vedere lexicografic (alfabetic). Dacă însă
valoarea returnată este pozitivă, atunci înseamnă că string-ul s1 este după s2 din punct
de vedere lexicografic.
4) stricmp(s1,s2) face acelaşi lucru ca şi strcmp, cu deosebirea că nu se face distincţie
între litere mari şi mici.
5) strcnmp(s1,s2,n) realizează o comparaţie între primele cel mult n caractere ale stringurilor
s1 şi s2.
6) strcnmpi(s1,s2,n) realizează o comparaţie între primele cel mult n caractere ale stringurilor
s1 şi s2 fără a se face distincţie între litere mari şi mici.
7) strcpy(s1,s2) copiază caracterele de la adresa s2 (până se întâlneşte inclusiv caracterul
‘\0’) la adresa s1. Cu alte cuvinte, se copiază conţinutul string-ului s2 peste string-ul
s1.

8) strlen(s) returnează lungimea string-ului s (numărul de caractere până la ‘\0’).
9) strlwr(s) transformă literele mari din string-ul s în litere mici.
10) strupr(s) transformă literele mici din string-ul s în litere mari.
11) strncat(s1,s2,n) adaugă la sfârşitul string-ului s1 cel mult n caractere din string-ul s2,
după care se adaugă caracterul ‘\0’.
12) strncpy(s1,s2,n) copiază cel mult n caractere de la începutul string-ului s2 la adresa
s1, după care se adaugă la sfârşit caracterul ‘ \0’.
13) strnset(s,c,n) setează primele n caractere ale string-ului s la valoarea primită în
parametrul c.
14) strpbrk(s1,s2) returnează adresa de memorie la care apare prima dată un caracter din
string-ul s2 în string-ul s1.
15) strchr(s,c) returnează adresa la care apare ultima dată caracterul c în string-ul s.
16) strrev(s) inversează caracterele string-ului s (primul se schimbă cu ultimul, al doilea
cu penultimul etc.).
17) strset(s,c) setează toate caracterele string-ului s (până la ‘\0’) la valoarea primită în
parametrul c de tip char.
18) strstr(s1,s2) returnează adresa de memorie la care apare prima dată string-ul s2 în s1.
Dacă s2 nu apare în s1, atunci se returnează adresa nulă NULL.
19) strxfrm(s1,s2,n) înlocuieşte primele cel mult n caractere ale string-ului s1 cu primele
cel mult n caractere din string-ul s2.

String-ul se memorează în C într-un şir de caractere obişnuit. Caracterul ‘\0’ (caracterul
cu codul ASCII 0, adică NULL) marchează sfârşitul string-ului. De aceea, despre string în C se
spune că este un şir NULL terminat.
În fişierul antet string.h găsim definiţiile funcţiilor de lucru cu string-uri în C.

Funcţii în C

      Ne propunem să vedem cum se redactează o funcţie în C şi cum se transmit parametrii
funcţiei.În C, C++ şi Java (limbajele ce au la bază standardul ANSI C) ca subprograme nu avem
decât funcţii, o procedură putând fi implementă ca o funcţie care returnează tipul void (vid).
În C, o funcţie care returnează alt tip decât void poate fi apelată atât ca o funcţie (în
cadrul unei expresii), cât şi ca o procedură (ignorându-se valoarea returnată). De exemplu,
funcţia printf returnează valoarea int, care reprezintă numărul de octeţi care s-au afişat pe ecran.
De cele mai multe ori (după cum am văzut şi în exemplele de mai sus) funcţia printf este apelată
ca o procedură, ignorându-se valoarea returnată.
După cum am mai spus şi în primul capitol, funcţiile pot fi descrise atât la începutul
programului, deasupra funcţiei principale, cât şi după aceasta, situaţie în care definiţiile funcţiilor
trebuie totuşi să apară deasupra funcţiei principale.
Structura unei functii:

tip nume_functie(argumente)

corpul functiei (instructiuni)
}

           Definiţia funcţiei începe cu tip, care este tipul valorii pe care o returnează funcţia. Dacă
tip nu este void, atunci funcţia va conţine de regulă cel puţin o instrucţiune return expresie. Dacă
execuţia programului ajunge la o astfel de instrucţiune, atunci se evaluează expresia a cărei
valoare trebuie să fie de tipul tip sau unul compatibil şi valoarea obţinută se returnează, execuţia
programului continuând cu instrucţiunile de după locul în care a fost apelată funcţia.
Dacă o funcţie ce returnează o valoare de un tip diferit de void nu se termină cu o
instrucţiune return, atunci la compilare vom obţine mesajul de atenţionare Warning 5: Function
should return a value.
În C parametrii ce se returnează din funcţie (variabilele de ieşire) se transmit prin adresă.
În acest sens dăm un exemplu în care media aritmetică este returnată printre parametrii funcţiei:
void medie2(float x,float y,float *m)
{
*m=(x+y)/2;
}
void main()
{
float x,y,med;
printf("Dati doua numere reale: ");
scanf("%f%f",&x,&y);
medie2(x,y,&med); /* apel functie */
printf("Media este: %f",med);
}

La apelul unei funcţii valorile parametrilor de intrare, cei transmişi prin valoare (aşa cum
este cazul parametrilor x şi y), sunt copiate în zone de memorie noi şi de aceea, dacă le
modificăm, la părăsirea funcţiei, valorile modificate se pierd, zonele de memorie alocate pentru
aceşti parametri în funcţie fiind eliberate.
Parametrul m al funcţiei medie2 este transmis prin adresă. Mai exact, în funcţie se
transmite adresa la care este alocată memorie pentru variabila med din funcţia principală. În
funcţia medie2 se modifică valoarea de la adresa m, adresă care coincide cu cea a variabilei med
şi de aceea valoarea calculată rămâne în variabila med după ce se părăseşte funcţia.
Dacă vrem ca o variabilă transmisă prin adresă să nu poată fi modificată, punem în faţa ei
cuvântul rezervat const. În general, dacă se încearcă modificarea unei variabile declarate cu
const (a unei constante), atunci se semnalează eroare la compilare.
Variabilele de tip tablou sunt pointeri, de aceea valorile de la adresele indicate de ele se
transmit prin adresă şi eventualele modificări în interiorul funcţiei asupra elementelor tabloului
păstrându-se şi la părăsirea funcţiei.
În continuare prezentăm o funcţie care calculează media aritmetică a elementelor unui şir
de numere reale:
float mediesir(int n,const float *a)
{
int i;
float s=0;
for (i=0;i<n;i++) s+=a[i];
return s/n;
}
void main()
{
int i,n;
float a[100];

printf("Dati numarul de elemente al sirului: ");
scanf("%d",&n);
puts("Dati elementele sirului:");
for (i=0;i<n;i++)
{
printf("a[%d]=",i);
scanf("%f",&a[i]);
}
printf("Media aritmetica: %f",mediesir(n,a));
}

Rezumat:
Definiţia unei funcţii în C începe cu tipul returnat de către funcţie, urmat de numele
funcţiei şi de lista de argumente dată între paranteze. Dacă o funcţie are tipul returnat void,
atunci ea nu returnează nici o valoare şi se apelează practic ca o procedură.
Parametrii de intrare în funcţie se transmit prin valoare, iar cei de ieşire se transmit prin
adresă.
Cum se scrie o functie in C ?

Pointeri. Tablouri de elemente.

Rezumat(pointeri,alocare dinamica si statica pentru vector si matrice)


Un pointer reţine o adresă de memorie la care se află memorată o anumită dată (un întreg,
un număr real etc.). Pentru a obţine valoarea de la adresa reţinută în pointer se aplică operatorul *
pointerului. Pentru a obţine adresa la care se află memorie alocată pentru o variabilă folosim
operatorul &.
Alocarea dinamică a memoriei în C se face cu ajutorul funcţiilor calloc, malloc şi
realloc, ale căror antete se găsesc în fişierul malloc.h. Eliberarea memoriei alocate dinamic în C
se face cu ajutorul funcţiei free.
În C putem aloca memorie pentru un tablou (vector, matrice etc.) atât în mod static cât şi
dinamic (în timpul rulării aplicaţiei). Alocarea dinamică a memoriei pentru o matrice
bidimensională se face în două etape: întâi alocăm memorie pentru a reţine adresele de început
ale liniilor matricei şi apoi alocăm memorie pentru a reţine elementele matricei. În consecinţă,
eliberarea memoriei se face tot în două etape, dar în ordine inversă: eliberăm întâi memoria
alocată anterior dinamic pentru a reţine elementele matricei şi apoi eliberăm memoria ocupată de
vectorul de adrese de început a liniilor matricei.

Alocare dinamica a memoriei.


Alocarea dinamică a memoriei în C se poate face cu ajutorul funcţiilor malloc, calloc şi
realloc, ale căror definiţii le găsim în fişierul antet malloc.h. Cele 3 funcţii pentru alocare
dinamică returnează toate tipul pointer către void, adică void*. De aceea, în momentul folosirii
acestor funcţii trebuie făcută o conversie de tip. Oricare dintre cele trei funcţii de alocare
returnează valoarea NULL (constanta NULL are valoarea 0) în cazul în care alocarea de memorie
nu s-a putut face (nu este suficientă memorie liberă sau lungimea zonei de memoriei ce se
doreşte a fi alocată nu este validă, adică este negativă).
Funcţia malloc primeşte un parametru de tip întreg, care reprezintă numărul de octeţi de
memorie ce se doreşte a fi alocaţi. De exemplu, pentru un vector de numere întregi scurte trebuie
să definim un pointer către tipul int, pointer care va reţine adresa către zona de memorie alocată.
Cum se face o alocare dinamica pentru vector ?

int i,*a,n,m;
printf("Dati lungimea vectorului: ");
scanf("%d",&n);
a=(int*)malloc(n*sizeof(int)); /* alocare memorie pentru n
elemente de tip int */
if (a==NULL)
{
perror("Memorie insuficienta!"); /* mesaj eroare */
exit(1); /* parasire program cu cod de eroare */
}
for (i=0;i<n;i++)
{
printf("a[%d]=",i);
scanf("%d",&a[i]);
}

Funcţia malloc returnează tipul void*, care trebuie convertit în exemplul de mai sus la
tipul int*, adică la tipul variabilei a.
Funcţia calloc are doi parametri. Primul parametru reprezintă numărul de blocuri ce se
alocă, iar al doilea este lungimea unui bloc. Alocarea memoriei pentru vectorul a din exemplul
de mai sus poate fi rescrisă folosind funcţia calloc astfel:
a=(int*)calloc(n,sizeof(int));
Spre deosebire de funcţia malloc, funcţia calloc iniţializează zona de memorie alocată cu
0, adică toţi octeţii sunt setaţi la valoarea 0.
Funcţia realloc este folosită pentru ajustarea lungimii unei zone de memorie deja alocate,
copiind conţinutul memoriei anterior alocate dacă este necesar la o nouă adresă. Funcţia are doi
parametri. Primul reprezintă adresa zonei de memorie pentru care se doreşte să se facă
realocarea, iar al doilea este noua lungime (în octeţi) a memoriei ce se vrea a fi realocată.
Dacă lungimea memoriei realocate este mai mică sau egală decât lungimea zonei de
memorie iniţiale, atunci adresa rămâne nemodificată (şi este returnată), eventuala diferenţă de
memorie se eliberează.
Dacă memoria realocată este mai mare decât cea iniţială, atunci se alocă o nouă zonă de
memorie în care se copiază informaţia din zona iniţială, după care prima zona de memorie se
eliberează, în final returnându-se noua adresă.
Cum se face realocarea unui vector?

printf("Dati noua lungime a vectorului: ");
scanf("%d",&m);
a=(int*)realloc(a,m*sizeof(int));
if (a==NULL)
{
printf("Memorie insuficienta!");
exit(1);
}
Eliberarea memoriei alocate cu malloc, calloc şi realloc se face cu ajutorul funcţiei free,
care primeşte ca parametru pointerul spre zona de memorie alocată. Pentru exemplele de mai sus
eliberarea memoriei pentru vectorul a se face cu free(a).
Alocarea memoriei pentru o matrice se poate face, de asemenea, atât static cât şi dinamic.
Varianta statică este: tip a[nl][nc];, unde nl reprezintă numărul de linii, iar nc este numărul de
coloane al matricii.
În continuare prezentăm două moduri în care se poate face alocare dinamică de memorie
pentru o matrice a de valori reale (float) de dimensiuni m şi n. În C, o matrice alocată dinamic
este un vector (de lungime m) de vectori (fiecare de lungime n). Pentru aceasta trebuie să definim
variabila a care va fi de tipul float**, adică pointer către pointer către tipul float. Pointerul a va fi
adresa către zona de memorie în care se reţine vectorul cu adresele de început ale fiecărei linii
ale matricii. Întâi va trebui să alocăm memorie pentru vectorul de adrese de lungime m. Apoi
vom aloca memorie necesară stocării celor m x n elemente ale matricii. În final vom face
legăturile între vectorul de adrese şi zona de memorie unde vor fi stocate elementele matricii.
Cum se face alocarea dinamica a unui matrici?

int i,j,m,n;
float **a;
printf("Dati dimensiunile matricii: ");
scanf("%d%d",&m,&n);
…. a[m-1]
a
…. …. ….
a[0]
a[0][0] a[0][n-1] a[1][0]
a[0] a[1]
Fig. 1: Prima schemă de alocare dinamică a memoriei pentru o matrice
a[m-1][0] a[m-1][n-1]
a[1] a[m-1]
26
a=(float**)calloc(m,sizeof(float*));
if (a==NULL)
{
printf("Memorie insuficienta!");
exit(1);
}
a[0]=(float*)malloc(m*n,sizeof(float));
if (a[0]==NULL)
{
printf("Memorie insuficienta!");
exit(1);
}
for (i=1;i<m;i++) a[i]=a[i-1]+n; /* adresele de inceput ale
liniilor */
....
free(a[0]); /* eliberarea memoriei ocupata de matrice */
free(a);

Întâi se alocă memorie pentru vectorul de adrese al liniilor (a este un vector de elemente
de tipul float*). Apoi se alocă memorie necesară stocării tuturor elementelor matricii a (se alocă
m x n blocuri de lungime sizeof(float)), iar adresa către zona alocată se depune în a[0]. a[1] va fi
adresa către zona de memorie aflată cu n căsuţe (fiecare de lungime sizeof(float)) după a[0] etc.
Cu alte cuvinte la adresa a[0] se găsesc elementele primei linii, apoi în continuare elementele
celei de-a doua linii care încep să fie memorate de la adresa a[1], apoi a treia linie la adresa a[2]
ş.a.m.d., iar la sfârşit la adresa a[n-1] avem elementele ultimei linii.
Eliberarea zonei de memorie ocupate de matricea a se face în doi paşi: întâi se eliberează
vectorul cu cele m x n elemente de tip float (aflat la adresa a[0]), iar apoi se eliberează memoria
ocupată cu vectorul de adrese (vector aflat la adresa a).
Dezavantajul alocării dinamice de mai sus constă în faptul că se încearcă alocarea unei
zone continue de memorie de lungime totală m x n x sizeof(float) şi s-ar putea să nu dispunem de
o zonă continuă de memorie liberă de o asemenea dimensiune. Acest dezavantaj în prezent nu
poate fi considerat major, pentru că astăzi calculatoarele dispun de memorie RAM de capacităţi
mari. Marele avantaj al alocării dinamice de mai sus este dat de viteza mare de execuţie datorată
faptului că se fac numai două alocări şi tot atâtea eliberări de memorie.
O alternativă la alocarea de mai sus este alocarea separată a memoriei pentru fiecare linie
a matricii:
int i,j,m,n;
float **a;
printf("Dati dimensiunile matricii: ");
scanf("%d%d",&m,&n);
a = (float**)calloc(m,sizeof(float*));
if (a==NULL)
{
printf("Memorie insuficienta!");
exit(1);
}
for (i=0;i<m;i++)
{
a[i] = (float*)calloc(n,sizeof(float));
if (a[i]==NULL)
27
{
printf("Memorie insuficienta!");
exit(1);
}
}
....
for (i=0;i<m;i++) free(a[i]); */ eliberarea memoriei */
free(a);
În exemplul de mai sus se fac m+1 alocări de memorie pentru m+1 vectori. Primul vector
alocat (de lungime m), ca şi la prima variantă de alocare a memoriei pentru o matrice, va reţine
adresele către fiecare din cele m linii ale matricii. Apoi se încearcă m alocări de vectori de
lungime n, vectorii cu elementele fiecărei linii a matricii. Astfel, a[0], a[1], … , a[m-1] sunt
adresele către fiecare linie obţinute în urma alocărilor. Eliberarea memoriei alocate pentru
matricea a se face tot în m+1 paşi: întâi se eliberează cele m zone de memorie în care sunt
reţinute elementele matricii şi în final se eliberează zona de memorie ocupată de vectorul cu
adresele de început ale liniilor.

Procedând în mod asemănător cu alocarea dinamică a unei matrici putem aloca memorie
pentru vectori de vectori, în sensul că fiecare dintre vectorii de la adresele a[0], a[1], … ,
a[m-1] pot avea lungimi diferite:

int i,j,m,*n;
float **a;
printf("Dati numarul de vectori: ");
scanf("%d",&m);
n=(int*)calloc(m,sizeof(int));
if (n==NULL)
{
printf("Memorie insuficienta!");
exit(1);
}
printf("Dati numarul de elemente al fiecarui vector:\n");
for (i=0;i<m;i++)
{
printf("n[%d]=",i+1);
scanf("%d",&n[i]);
}
a=(float**)calloc(m,sizeof(float*));
if (a==NULL)
{
printf("Memorie insuficienta!");
exit(1);
}
for (i=0;i<m;i++)
{
a[i]=(float*)calloc(n[i],sizeof(float));
if (a[i]==NULL)
{
printf("Memorie insuficienta!");
exit(1);
}
}
printf("Dati elementele vectorilor:\n");
for (i=0;i<m;i++)
for (j=0;j<n[i];j++)
{
printf("a[%d,%d]=",i+1,j+1);
scanf("%f",&a[i][j]);
}
....
29
for (i=0;i<m;i++) free(a[i]); /* eliberarea memoriei */
free(a);
free(n);
}






Alocarea statică a memoriei


    În C există posibilitatea alocării memoriei atât mod static, cât şi dinamic. Prin alocare
statică înţelegem faptul că memoria este alocată automat încă de la pornirea execuţiei
instrucţiunilor unei funcţii, iar eliberarea memoriei se face tot automat la părăsirea funcţiei. Cu
alte cuvinte, când se intră într-o funcţie (inclusiv funcţia main) se face alocarea statică a
memoriei, iar eliberarea se face la părăsirea acelei funcţii. Lungimea zonei de memorie alocate
static este constantă, adică de fiecare dată când se intră cu execuţia într-o funcţie, se alocă
automat acelaşi număr de octeţi.
Spre deosebire de alocarea statică, în cazul alocării dinamice stabilim noi momentul
alocării memoriei şi lungimea zonei de memorie alocate. De asemenea, putem decide momentul
în care să se facă eliberarea memoriei.
Pentru un vector putem aloca memorie în mod static sub forma tip
numevector[lungimev], unde lungimev este o constantă numerică care reprezintă numărul de
elemente (căsuţe de memorie) al vectorului.
Dăm câteva exemple de alocări statice de memorie pentru vectori:
# define N 100
....
float a[10],b[N];
int i,n,vect[N+1];
Elementele unui vector în C au indici între 0 şi lungimev-1. De exemplu, vectorul a
definit mai sus are elementele: a[0], a[1], … , a[9].
Dacă se trece de capetele 0 şi lungimev-1 ale vectorului a, în C nu se semnalează în
general eroare. Astfel se poate accesa elementul a[-1] (zona de memorie aflată cu o căsuţă în
stânga lui a[0]) sau se poate accesa a[lungime]. Acest lucru poate conduce la blocarea
programului sau la alterarea altor date reţinute în memorie la adresele respective, pe care le-am
accesat greşit!
În declaraţia numevector[lungimev], numevector este un pointer care reţine adresa de
început a zonei de memorie alocate static pentru vector (elementele vectorului se reţin în căsuţe
succesive de memorie). Cu alte cuvinte, pointerul a reţine adresa la care se află memorat primul
element a[0] al vectorului a, iar a+1 este adresa la care se află elementul a[1], a+2 este adresa
lui a[2] etc. De asemenea, *a este tot una cu a[0], *(a+1) este a[1] etc. În general, a[k]
reprezintă o scriere simplificată pentru *(a+k).

Pointeri.


     Ne propunem să înţelegem în acest capitol cea mai importantă noţiune a limbajului C.
Este vorba de pointer.
Pentru a stăpâni modul de funcţionare al limbajului C, trebuie înţeleasă foarte bine
noţiunea de pointer.
O variabilă de tip pointer reţine o adresă de memorie la care se află o informaţie (un
caracter, un întreg, un şir etc.).
O variabilă de tip pointer se declară sub forma: tip *numepointer. De exemplu, o
variabilă de tip pointer către tipul int se declară astfel: int *pint. Variabila pint va reţine adresa de
memorie la care se află stocată o dată de tip int.
23
Revenind la declaraţia generală tip *numepointer, numepointer este o variabilă de tipul
tip* şi memorează o adresă de memorie, la care este reţinută o informaţie de tipul tip. O adresă
se memorează pe 4 octeţi şi în consecinţă sizeof(tip*) este 4.
Putem aplica operatorul * unei valori de tip pointer pentru a afla valoarea care se află la
adresa reţinută de pointer. Astfel, *numepointer reprezintă valoarea de tipul tip aflată în memorie
la adresa numepointer.
Adresa la care se află zona de memorie rezervată unei variabile se poate afla folosind
operatorul &. Cu alte cuvinte, operatorul & este inversul operatorului *. În consecinţă, pentru o
variabilă var de tipul tip are sens o atribuire de forma numepointer=&var. De asemenea, se poate
face atribuirea var=*numepointer. Operatorul * anulează pe & şi & anulează pe *, adică *&var
este totuna cu var, iar &*numepointer este acelaşi lucru cu numepointer.
Pentru valori de tip pointer funcţionează operatorii: =, +, -, +=, -=, ++, -- şi !. De exemplu
putem scrie numepointer+=10, sau numepointer=&var-1.
După aplicarea operatorului += pointerului numepointer sub forma numepointer+=10,
pointerul va reţine adresa aflată cu 10 căsuţe mai la dreapta în memorie faţă de adresa iniţială. O
căsuţă de memorie are sizeof(tip) octeţi, unde tip este tipul de dată către care pointează
numepointer. Cu alte cuvinte, în urma atribuirii numepointer+=10, variabila numepointer va
reţine adresa de memorie aflată cu 10*sizeof(tip) octeţi la dreapta adresei de memorie iniţiale din
numepointer.
De reţinut este şi faptul că pentru valori de tip pointer nu funcţionează operatorii: *, /, %,
adică pointerii nu se pot înmulţi, împărţi cu alte valori.

Tipul char (cap 6).


 Tipul char.


Ne propunem să vedem unde găsim şi care sunt principalele funcţii scrise pentru tipul
char din limbajul C.
Tipul char a fost prezentat la capitolul dedicat tipurilor întregi de date. Informaţia
reţinută într-o valoare de tip char poate fi interpretată în C ca un caracter al tabelei ASCII. De
acest lucru o să ne ocupăm în acest capitol.
Definiţiile principalelor funcţii de lucru cu caractere în C le găsim în fişierul antet
ctype.h. Dintre aceste funcţii o să le prezentăm numai pe cele mai importante şi mai utile. Facem
observaţia că toate funcţiile de mai jos returnează o valoare de tip int şi primesc ca argument un
caracter:

1) isalnum(c) returnează valoare de adevărat (nenulă) dacă c este un caracter alfa-numeric
(litera mică, literă mare sau cifră), altfel se returnează 0.
2) isalpha(c) returnează valoare de adevărat (nenulă) dacă c este o literă, altfel se
returnează 0.
3) isdigit(c) returnează valoare de adevărat (nenulă) dacă c este o cifră, altfel returnează
0.
4) isxdigit(c) returnează valoare de adevărat (nenulă) dacă c este cifră hexazecimală (0, 1,
2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, a, b, c, d, e, f), altfel se returnează 0.
5) islower(c) returnează valoare de adevărat (nenulă) dacă c este literă mică, altfel
returnează 0.
6) isupper(c) returnează valoare de adevărat (nenulă) dacă c este literă mare, altfel
returnează 0.
7) tolower(c) returnează transformarea caracterului c în litera mică dacă este literă mare,
altfel se returnează valoarea lui c nemodificată.
8) toupper(c) returnează transformarea caracterului c în litera mare dacă este literă mică,
altfel se returnează valoarea lui c nemodificată.
Şi în fişierul antet conio.h întâlnim câteva funcţii legate de tipul char:

1) getch() citeşte un caracter de la tastatură, fără ecou pe ecranul monitorului. Funcţia
returnează caracterul citit fără a-l afişa pe ecran.
2) getche() citeşte un caracter de la tastatură, se returnează caracterul citit după ce este
afişat pe ecran (cu ecou).
3) putch(c) afişează pe ecran caracterul c primit ca argument de funcţie. Se ţine cont de
eventuala fereastră text definită cu funcţia window.
4) kbhit() verifică dacă în buffer-ul de intrare de la tastatură există caractere. Cu alte
cuvinte se verifică dacă s-a apăsat un buton de la tastatură. Dacă buffer-ul este nevid, atunci se
returnează o valoare nenulă.
Programul următor afişează codul ASCII pentru o literă mică preluată de la tastatură:
char c;
c=getch();
if (97<=c && c<=’z’)
printf("Litera mica %c cu codul ASCII %d!\n",c,c);
while (kbhit()) getch(); /* golire buffer */
printf("Apasati Escape pentru a parasi programul");
do c=getch();
while (c!=27 && c!=13); /* se paraseste daca se apasa
Esc sau Enter */
if (c==27) exit(0); /* Functia exit intrerupe executia
programului */
Rezumat
Tipul caracter coexistă în C cu tipul întreg de date. Funcţiile special scrise pentru tipul
caracter au antetele definite în fişierul ctype.h.

Rezumat(for,while,do..while).


În C există trei intrucţiuni repetitive: for, while şi do….while.
Implementarea instrucţiunii for este destul de complexă, în sensul că putem face mai
multe iniţializări, putem avea o condiţie complexă de terminare a ciclării şi putem avea mai
multe actualizări. Aici se utilizează practic operatorul virgulă.
Instrucţiunea do….while este cu test final. Cu ajutorul ei putem implementa o instrucţiune
pseudocod repeat….until.