O variabila este un obiect de programare caruia i se atribuie un nume. x3c6cg
  Variabilele ca si constantele sint elemente de baza cu care opereaza un 
  program scris in C.
  Variabilele se deosebesc dupa denumire si pot primi diferite valori. Numele 
  variabilelor sint identificatori. Numele de variabile se scriu de obicei 
  cu litere mici (fara a fi obligatoriu).
  Variabilele in limbajul C sint caracterizate prin doua atribute: 
  clasa de memorie si tip.
  Aceste doua atribute ii sint atribuite unei variabile prin intermediul 
  unei declaratii. Declaratiile listeaza variabilele care urmeaza a fi folosite, 
  stabilesc clasa de memorie, tipul variabilelor si eventual valorile initiale, 
  dar despre declaratii vom discuta in capitolul 5.
 3.1. Clase de memorie
 Limbajul C prezinta patru clase de memorie: automatica, externa, statica, 
  registru.
 Variabile automatice
 Variabilele automatice sint variabile locale fiecarui bloc (sectiunea 
  6.2) sau functii (capitolul 7). Ele se declara prin specificatorul de clasa 
  de memorie auto sau implicit prin context. O variabila care apare in corpul 
  unei functii sau al unui bloc pentru care nu s-a facut nici o declaratie de 
  clasa de memorie se considera implicit de clasa auto.
  O variabila auto este actualizata la fiecare intrare in bloc si se distruge 
  in momentul cind controlul a parasit blocul. Ele nu isi retin 
  valorile de la un apel la altul al functiei sau blocului si trebuie initializate 
  la fiecare intrare. Daca nu sint initializate, contin valori reziduale. 
  Nici o functie nu are acces la variabilele auto din alta functie. In functii 
  diferite pot exista variabile locale cu aceleasi nume, fara ca variabilele sa 
  aiba vreo legatura intre ele.
 Variabile externe
 Variabilele externe sint variabile cu caracter global. Ele se definesc 
  in afara oricarei functii si pot fi apelate prin nume din oricare functie 
  care intra in alcatuirea programului.
  In declaratia de definitie aceste variabile nu necesita specificarea nici 
  unei clase de memorie.
  La intilnirea unei definitii de variabila externa compilatorul aloca 
  si memorie pentru aceasta variabila.
  Intr-un fisier sursa domeniul de definitie si actiune al unei variabile 
  externe este de la locul de declaratie pina la sfirsitul fisierului.
  Aceste variabile exista si isi pastreaza valorile de-a lungul executiei 
  intregului program.
  Pentru ca o functie sa poata utiliza o variabila externa, numele variabilei 
  trebuie facut cunoscut functiei printr-o declaratie. Declaratia poate fi facuta 
  fie explicit prin utilizarea specificatorului extern, fie implicit prin context.
  Daca definitia unei variabile externe apare in fisierul sursa inaintea 
  folosirii ei intr-o functie particulara, atunci nici o declaratie ulterioara 
  nu este necesara, dar poate fi facuta.
  Daca o variabila externa este referita intr-o functie inainte ca 
  ea sa fie definita, sau daca este definita intr-un fisier sursa diferit 
  de fisierul in care este folosita, atunci este obligatorie o declaratie 
  extern pentru a lega aparitiile variabilelor respective.
  Daca o variabila externa este definita intr-un fisier sursa diferit de 
  cel in care ea este referita, atunci o singura declaratie extern data 
  in afara oricarei functii este suficienta pentru toate functiile care 
  urmeaza declaratiei.
  Functiile sint considerate in general variabile externe afara de 
  cazul cind se specifica altfel.
  Variabilele externe se folosesc adeseori in locul listelor de argumente 
  pentru a comunica date intre functii, chiar daca functiile sint 
  compilate separat.
 
 Variabile statice
 Variabilele statice se declara prin specificatorul de clasa de memorie static. 
  Aceste variabile sint la rindul lor de doua feluri: interne si externe.
  Variabilele statice interne sint locale unei functii si se definesc in 
  interiorul unei functii, dar spre deosebire de variabilele auto, ele isi 
  pastreaza valorile tot timpul executiei programului. Variabilele statice interne 
  nu sint create si distruse de fiecare data cind functia este activata 
  sau parasita; ele ofera in cadrul unei functii o memorie particulara permanenta 
  pentru functia respectiva.
  Alte functii nu au acces la variabilele statice interne proprii unei functii.
  Ele pot fi declarate si implicit prin context; de exemplu sirurile de caractere 
  care apar in interiorul unei functii cum ar fi argumentele functiei printf 
  (vezi capitolul 11) sint variabile statice interne.
  Variabilele statice externe se definesc in afara oricarei functii si orice 
  functie are acces la ele. Aceste variabile sint insa globale numai 
  pentru fisierul sursa in care ele au fost definite. Nu sint recunoscute 
  in alte fisiere.
  In concluzie, variabila statica este externa daca este definita in 
  afara oricarei functii si este static interna daca este definita in interiorul 
  unei functii.
  In general, functiile sint considerate obiecte externe. Exista insa 
  si posibilitatea sa declaram o functie de clasa static. Aceasta face ca numele 
  functiei sa nu fie recunoscut in afara fisierului in care a fost 
  declarata.
  
  Variabile registru
 O variabila registru se declara prin specificatorul de clasa de memorie register. 
  Ca si variabilele auto ele sint locale unui bloc sau functii si valorile 
  lor se pierd la iesirea din blocul sau functia respectiva. Variabilele declarate 
  register indica compilatorului ca variabilele respective vor fi folosite foarte 
  des. Daca este posibil, variabilele register vor li plasate de catre compilator 
  in registrii rapizi ai calculatorului, ceea ce conduce la programe mai 
  compacte si mai rapide.
  Variabile register pot fi numai variabilele automatice sau parametrii formali 
  ai unei functii. Practic exista citeva restrictii asupra variabilelor 
  register care reflecta realitatea hardware-ului de baza. Astfel:
  ? numai citeva variabile din fiecare functie pot fi pastrate in 
  registri (de obicei 2 sau 3); declaratia register este ignorata pentru celelalte 
  variabile;
  ? numai tipurile de date int, char si pointer sint admise;
  ? nu este posibila referirea la adresa unei variabile register.
 3.2. Tipuri de variabile
 Limbajul C admite numai citeva tipuri fundamentale de variabile: caracter, 
  intreg, flotant.
 Tipul caracter
 O variabila de tip caracter se declara prin specificatorul de tip char. Zona 
  de memorie alocata unei variabile de tip char este de un octet. Ea este suficient 
  de mare pentru a putea memora orice caracter al setului de caractere implementate 
  pe calculator.
  Daca un caracter din setul de caractere este memorat intr-o variabila 
  de tip char, atunci valoarea sa este egala cu codul intreg al caracterului 
  respectiv. Si alte cantitati pot fi memorate in variabile de tip char, 
  dar implementarea este dependenta de sistemul de calcul.
  Ordinul de marime al variabilelor caracter este intre -128 si 127. Caracterele 
  setului ASCII sint toate pozitive, dar o constanta caracter specificata 
  printr-o secventa de evitare poate fi si negativa, de exemplu '\377' are valoarea 
  -1. Acest lucru se intimpla atunci cind aceasta constanta 
  apare intr-o expresie, moment in care se converteste la tipul int 
  prin extensia bitului cel mai din stinga din octet (datorita modului de 
  functionare a instructiunilor calculatorului).
 Tipul intreg
 Variabilele intregi pozitive sau negative pot fi declarate prin specificatorul 
  de tip int. Zona de memorie alocata unei variabile intregi poate fi de 
  cel mult trei dimensiuni.
  Relatii despre dimensiune sint furnizate de calificatorii short, long 
  si unsigned, care pot fi aplicati tipului int.
  Calificatorul short se refera totdeauna la numarul minim de octeti pe care poate 
  fi reprezentat un intreg, in cazul nostru 2.
  Calificatorul long se refera la numarul maxim de octeti pe care poate fi reprezentat 
  un intreg, in cazul nostru 4.
  Tipul int are dimensiunea naturala sugerata de sistemul de calcul. Scara numerelor 
  intregi reprezentabile in masina depinde de asemenea de sistemul 
  de calcul: un intreg poate lua valori intre -32768 si 32767 (sisteme 
  de calcul pe 16 biti) sau intre -2147483648 si 2147483647 (sisteme de 
  calcul pe 32 de biti).
  Calificatorul unsigned alaturi de declaratia de tip int determina ca valorile 
  variabilelor astfel declarate sa fie considerate intregi fara semn.
  Numerele de tipul unsigned respecta legile aritmeticii modulo 2n, unde n este 
  numarul de biti din reprezentarea unei variabile de tip int. Numerele de tipul 
  unsigned sint totdeauna pozitive.
  Declaratiile pentru calificatori sint de forma: short int x; long int y; unsigned int z;
  Cuvintul int poate fi omis in aceste situatii.
 Tipul flotant (virgula mobila)
 Variabilele flotante pot fi in simpla precizie si atunci se declara 
  prin specificatorul de tip float sau in dubla precizie si atunci se declara 
  prin specificatorul double. Majoritatea sistemelor de calcul admit si reprezentarea 
  in precizie extinsa; o variabila in precizie extinsa se declara 
  prin specificatorul long double.
 Tipul void (tip neprecizat)
 Un pointer poate fi declarat de tip void. In aceasta situatie pointerul 
  nu poate fi folosit pentru indirectare (dereferentiere) fara un cast explicit, 
  si aceasta deoarece compilatorul nu poate determina marimea obiectului pe care 
  pointerul il indica.
 int x; float r; void *p = &x; /* p indica pe x */ int main() A
  *(int *) p = 2; p = &r; /* p indica pe r */
  *(float *)p = 1.1;
  S
 Daca o functie este declarata de tip void, aceasta nu va returna o valoare:
 void hello(char *name) A printf("Hello, %s.",name);
  S
 Tipuri derivate
 In afara de tipurile aritmetice fundamentale, exista, in principiu, 
  o clasa infinita de tipuri derivate, construite din tipurile fundamentale in 
  urmatoarele moduri:
  -; „masive de T” pentru masive de obiecte de un tip dat T, 
  unde T este unul dintre tipurile admise;
  -; „functii care returneaza T” pentru functii care returneaza 
  obiecte de un tip dat T;
  -; „pointer la T” pentru pointeri la obiecte de un tip dat 
  T;
  -; „structuri” pentru un sir de obiecte de tipuri diferite;
  -; „reuniuni” care pot contine obiecte de tipuri diferite, 
  tratate intr-o singura zona de memorie.
  In general aceste metode de construire de noi tipuri de obiecte pot fi 
  aplicate recursiv. Amanunte despre tipurile derivate sint date in 
  sectiunea 5.3.
 
 3.3. Obiecte si valori-stinga
 Alte doua notiuni folosite in descrierea limbajului C sint obiectul 
  si valoarea-stinga.
  Un obiect este continutul unei zone de memorie.
  O valoare-stinga este o expresie care se refera la un obiect. Un exemplu 
  evident de valoare-stinga este un identificator. Exista operatori care 
  produc valori-stinga: de exemplu, daca E este o expresie de tip pointer, 
  atunci *E este o expresie valoare-stinga care se refera la obiectul pe 
  care-l indica E. Numele valoare-stinga (in limba engleza left value) 
  a fost sugerat din faptul ca in expresia de atribuire E1 = E2 operandul 
  sting E1 trebuie sa fie o expresie valoare-stinga. In paragraful 
  de descriere a operatorilor se va indica daca operanzii sint valori-stinga 
  sau daca rezultatul operatiei este o valoare-stinga.
 3.4. Conversii de tip
 Un numar mare de operatori pot cauza conversia valorilor unui operand de la 
  un tip la altul. Daca intr-o expresie apar operanzi de diferite tipuri, 
  ei sint convertiti la un tip comun dupa un mic numar de reguli. In 
  general se fac automat numai conversiile care an sens, de exemplu: din intreg 
  in flotant, intr-o expresie de forma f+i. Expresii care nu au sens, 
  ca de exemplu un numar flotant ca indice, nu sint admise.
 Caractere si intregi
 Un caracter poate aparea oriunde unde un intreg este admis. In 
  toate cazurile valoarea caracterului este convertita automat intr-un intreg. 
  Deci intr-o expresie aritmetica tipul char si int pot aparea impreuna. 
  Aceasta permite o flexibilitate considerabila in anumite tipuri de transformari 
  de caractere. Un astfel de exemplu este functia atoi descrisa in sectiunea 
  7.5 care converteste un sir de cifre in echivalentul lor numeric.
  Expresia: saii - '0' produce valoarea numerica a caracterului (cifra) memorat in ASCII.
  Atragem atentia ca atunci cind o variabila de tip char este convertita 
  la tipul int, se poate produce un intreg negativ, daca bitul cel mai din 
  stinga al octetului contine 1. Caracterele din setul de caractere ASCII 
  nu devin niciodata negative, dar anumite configuratii de biti memorate in 
  variabile de tip caracter pot aparea ca negative prin extensia la tipul int.
  Conversia tipului int in char se face cu pierderea bitilor de ordin superior.
  Intregii de tip short sint convertiti automat la int. Conversia 
  intregilor se face cu extensie de semn; intregii sint totdeauna 
  cantitati cu semn.
  Un intreg long este convertit la un intreg short sau char prin trunchiere 
  la stinga; surplusul de biti de ordin superior se pierde.
 Conversii flotante
 Toate operatiile aritmetice in virgula mobila se executa in precizie 
  extinsa. Conversia de la float la int se face prin trunchierea partii fractionare. 
  Conversia de la int la float este acceptata.
 Intregi fara semn
 Intr-o expresie in care apar doi operanzi, dintre care unul unsigned 
  iar celalalt un intreg de orice alt tip, intregul cu semn este convertit 
  in intreg fara semn si rezultatul este un intreg fara semn.
  Cind un int trece in unsigned, valoarea sa este cel mai mic intreg 
  fara semn congruent cu intregul cu semn (modulo 216 sau 232). Intr-o 
  reprezentare la complementul fata de 2 (deci pentru numere negative), conversia 
  este conceptuala, nu exista nici o schimbare reala a configuratiei de biti.
  Cind un intreg fara semn este convertit la long, valoarea rezultatului 
  este numeric aceeasi ca si a intregului fara semn, astfel conversia nu 
  face altceva decit sa adauge zerouri la stinga.
 Conversii aritmetice
 Daca un operator aritmetic binar are doi operanzi de tipuri diferite, atunci 
  tipul de nivel mai scazut este convertit la tipul de nivel mai inalt inainte 
  de operatie. Rezultatul este de tipul de nivel mai inalt. Ierarhia tipurilor 
  este urmatoarea:
  -; char ? short ? int ? long;
  -; float ? double ? long double;
  -; tip intreg cu semn ? tip intreg fara semn;
  -; tip intreg ? virgula mobila.
 Conversii prin atribuire
 Conversiile de tip se pot face prin atribuire; valoarea membrului drept este 
  convertita la tipul membrului sting, care este tipul rezultatului.
 Conversii logice
 Expresiile relationale de forma i<j si expresiile logice legate prin operatorii 
  && si || sint definite ca avind valoarea 1 daca sint 
  adevarate si 0 daca sint false.
  Astfel atribuirea: d = (c>='0') && (c<='9');
  il face pe d egal cu 1 daca c este cifra si egal cu 0 in caz contrar.
 Conversii explicite
 Daca conversiile de pina aici le-am putea considera implicite, exista 
  si conversii explicite de tipuri pentru orice expresie. Aceste conversii se 
  fac prin constructia speciala numita cast de forma:
  (nume-tip) expresie
  In aceasta constructie expresie este convertita la tipul specificat dupa 
  regulile precizate mai sus. Mai precis aceasta este echivalenta cu atribuirea 
  expresiei respective unei variabile de un tip specificat, si aceasta noua variabila 
  este apoi folosita in locul intregii expresii. De exemplu, in 
  expresia: sqrt((double)n) se converteste n la double inainte de a se transmite functiei sqrt. Notam 
  insa ca, continutul real al lui n nu este alterat. Operatorul cast are 
  aceeasi precedenta ca si oricare operator unar.
 Expresia constanta
 O expresie constanta este o expresie care contine numai constante. Aceste 
  expresii sint evaluate in momentul compilarii si nu in timpul 
  executiei; ele pot fi astfel utilizate in orice loc unde sintaxa cere 
  o constanta, ca de exemplu:
 #define MAXLINE 1000 char lineaMAXLINE+1i;