Sunteți pe pagina 1din 11

PRELEGERE VI

PROGRAMAREA CALCULATOARELOR ŞI LIMBAJE DE PROGRAMARE

Studiul elementelor de bază din limbajul C++ - continuare


I. Tipuri de constante
Constantele reprezintă cantităţi fixe numerice, alfabetice sau alfanumerice. Tipul
constantei se deduce, în faza de execuţie a programului, din valoarea acesteia. Acestea se
clasifică în următoarele categorii: numerice şi de tip caracter.
La rîndul lor, constantele numerice pot fi întregi zecimale, întregi octale, întregi
hexazecimale sau raţionale în virgulă mobilă. Constantele caracter, şirurile de caractere şi
constantele definite prin identificatori definesc a doua categorie de constante.

I. Constante numerice
a) Constante întregi.
Reamintim doar că în sistemul de numeraţie octal se lucrează cu cifrele 0..7, iar în cel
hexazecimal cu 0..9, a..f sau 0..9, A..F. Aşa cum s-a precizat în tabelul 2.1.2, constantele
octale încep cu zero, iar cele hexazecimale cu 0x sau 0X.
În tabelul 2.3.1 se prezintă pentru fiecare tip implicit de constantă întreagă domeniul de
valori asociat.
Tipul Constantă zecimală Constantă octală Constantă hexazec.
int 0..32767 00..077777 0x0..0x7FFFF
unsigned int 0100000..0177777 0x8000..0xFFFF
long int 32768..2147483647 02000000.. 0x10000..
017777777777 0xFFFFFFF
unsigned 2147483648.. 02000000000.. 0x80000000..
long int 4294967295 03777777777 0xFFFFFFFF
Tabelul 6.1.1
Exemple: - de constante întregi zecimale: -15, 1345, + 142;
- de constante întregi octale fără semn: 037, 0447 (în formă zecimală
corespund numerele 31 şi respectiv 295);
- de constante hexazecimale fără semn: 0xF, 0X1a3 şi 0x23 (în formă zecimală
corespund numerele 15, 419 şi respectiv 35).
Tipul de dată a unei constante întregi poate fi modificat prin adăugarea unui sufix
format din una din literele l, L, u şi U sau una din combinaţiile ul, UL, uL şi Ul. Al doilea
tabel din această secţiune descrie efectul adăugării sufixului la o constantă întreagă în
funcţie de tipul acesteia.
Sufix Tipul constantei
l sau L long int sau unsigned long int
u sau U unsigned int sau unsigned long int
ul, UL, uL, Ul unsigned long int
Tabelul 6.1.2

1
b) Constante în virgulă mobilă.
Structura unei constante raţionale în virgulă mobilă cuprinde:
- semnul plus sau minus (semnul plus are caracter opţional);
- partea întreagă;
- punctul zecimal;
- partea fracţionară;
- exponentul zecimal. Acesta este format din litera e sau E şi un întreg zecimal
din două cifre nn, cu sau fără semn;
- sufixul de reprezentare a tipului: f sau F pentru float şi l sau L pentru long
double.
Matematic, exponentul zecimal se reprezintă prin 10 +/-nn.
Dintr-o constantă în virgulă mobilă poate să absenteze (dar nu simultan) partea întreagă
sau partea fracţionară şi în mod similar pentru punctul şi exponentul zecimal.
Exemple de constante în virgulă mobilă: 4.15, +1.55, -222.2, 0., 12.F, .0, .7893l, 7.33e+5,
+7.33E+5, 7.33e05, 7.33E+05, -15e-2, -15E-02. În mod obişnuit, constantele care conţin
exponent zecimal se referă la numerele 7,33x105 (sau 733000) şi respectiv ultimele două
la –15x10-2(sau –0,15).
Observaţie. În reprezentarea internă a constantelor aritmetice, bitul cel mai semnificativ
corespunde bitului semn (1 pentru minus, 0 pentru plus), iar în rest codificarea în binar a
acestora.
Constantele în virgulă mobilă se reprezintă cu mantisă şi exponent zecimal. Mantisa
este o cantitate subunitară de forma 0.c1c2…cn, unde c1≠0, n este egal cu 7 pentru
constantele raţionale în simplă precizie sau cu 15 pentru cele în dublă precizie. Spaţiul de
memorie rezervat în prima situaţie este de 4 octeţi (bytes), iar în a doua situaţie este de 15
octeţi.

II. Constante de tip caracter


a) Constante caracter.
Constantele caracter pot fi simple sau duble. Orice caracter din codificarea ASCII
(vezi, anexa 1) sau secvenţă de evitare între apotrofuri constituie o constantă caracter
simplă sau pe scurt, constantă caracter. Valoarea desemnată de o constantă caracter este
codul ASCII corespunzător caracterului respectiv (deci, constantele caracter se consideră
de tip int).
Aşa cum le sugerează şi denumirea în structura unei constante caracter duble intervin
două caractere ASCII sau secvenţe de evitare. În general, acestea ridică probleme de
portabilitate şi sînt specifice doar limbajului C++. Reprezentarea lor în memorie se face
pe 2 octeţi.
Exemple de constante caracter: ‘b’, ‘0’, ‘*’, ’\n’, ‘\r’, ‘51’, ‘\t\r’, ‘ac’. Ultimile trei
constante sînt duble şi de exemplu pentru reprezentarea ultimei constante se folosesc doi
octeţi cu structura următoare: ca.
b) Constante şir de caractere.
O înşiruire finită de caractere sau secvenţe de evitare delimitată de ghilimele (“)
defineşte o constantă şir de caractere. Caracterele speciale ghilimele şi apostrof
componente unui şir de caractere se introduc prin secvenţele de evitare \” şi respectiv \’.
Şirul vid se notează cu “”.

2
Un şir poate fi scris pe mai mule linii, fie folosind caracterul \ la sfîrşitul liniilor
respective, fie prin concatenarea unor subşiruri componente. De exemplu, şirul de
caractere “Introduceţi \t numele şi adresa unei persoane” se poate descrie pe două sau
trei linii, fie prin concatenarea subşirurilor:
“Introduceţi \t ”, “numele şi adresa ” şi “unei persoane”,
fie prin construcţia sintactică:
“Introduceţi \t \
numele şi adresa \
unei persoane”.
Este interesant de adăugat că, la fel, se interpretează secvenţa de evitare \n în
interiorul unui şir de caractere care depăşeşte o linie, saltul la linie nouă se înlătură şi
noua linie se tratează ca o parte a liniei anterioare.
Zona de memorie afectată şirului de caractere depinde de lungimea acestuia. În
plus, un octet se alocă caracterului NULL (\0), care se adaugă automat la sfîrşitul oricărui
şir de caractere indiferent de lungimea lui. Deci, pentru şirul vid se alocă un octet de
memorie.

III. Constante definite prin identificatori


Utilizarea într-o scară largă a constantelor definite prin identifcatori de tip utilizator
permite, pe de o parte gruparea la începutul programului a tuturor constantelor
susceptibile de a fi modificate ulterior fără să se altereze restul programului, iar pe de
alta, uşurează lizibilitatea programului. Sub diferiţi identificatori (se obişnuieşte scrierea
lor cu majuscule), programatorul poate să definească o serie de iniţializări numite
constante definite prin identificatori sau constante simbolice. Acestea se introduc, la
începutul programului, prin intermediul directivei #define. Ca valori se pot utiliza
constante de orice tip.
În programul de mai jos s-au utilizat zece constante definite prin identificatori: X, XL, Y,
Z, H, ZD, W, V, S şi T. Rezultatele programului 2.3.3.1 prezintă spaţiul de memorie, în
octeţi, utilizat la memorarea valorilor întregi în formă scurtă, lungă sau fără semn,
raţionale cu sau fără exponent, în simplă sau dublă precizie, caracter şi şir de caractere.
/* Constante definite prin indentificatori */
#include<stdio.h>
#include<conio.h>
#define X 124
#define XL 124l
#define Y 35u
#define Z 3.5f
#define H 3.5
#define ZD 3.5l
#define W 3e+5
#define V -3.5e-2
#define S ‘\n’
#define T “Turbo C++”
void main(void)
{ printf("sizeof(X)=%d X=%d\n", sizeof(X), X);
printf("sizeof(XL)=%d XL=%ld\n", sizeof(XL), XL);

3
printf("sizeof(Y)=%d Y=%d\n", sizeof(Y), Y);
printf("sizeof(Z)=%d Z=%f\n", sizeof(Z), Z);
printf("sizeof(H)=%d H=%6.1f\n", sizeof(H), H);
printf("sizeof(ZD)=%d ZD=%6.1lf\n", sizeof(ZD), ZD);
printf("sizeof(W)=%d W=%lf\n", sizeof(W), W);
printf("sizeof(V)=%d V=%lf\n", sizeof(V), V);
printf("sizeof(S)=%d S=%c", sizeof(S), S);
printf("sizeof(T)=%d T=%s\n", sizeof(T), T); getch();
}
sizeof(X)=2 X=124 Sizeof(W)=8 W=300000.000000
sizeof(XL)=4 XL=124 Sizeof(V)=2 V=-0.03500
sizeof(Y)=2 Y=124 Sizeof(S)=2 S=cursorul este poziţionat
sizeof(Z)=4 Z=3.500000 la începutul rindului urmator
sizeof(H)=8 H= 3.5 Sizeof(T)=10 T=Turbo C++
sizeof(ZD)=10 ZD= 3.5
Programul 6.3.1
Acolo unde nu se folosesc descriptori de format, numărul implicit de cifre în
partea fracţionară pentru valorile raţionale este 6. De asemenea, se observă că efectul
încercării de a tipări pe S este mutarea cursorului în linia următoare de ecran, secvenţa de
evitare ‘\n’ nefiind trecută explicit, aşa cum s-a procedat cu celelalte funcţii printf().

IV. Declararea variabililor


Conceptul de variabilă are aceeaşi semnificaţie ca în matematică. Indentificatorul
utilizator de recunoaştere şi tipul de valoare sînt atribute binecunoscute, la care se
adaugă, în plus, conform specificului programării, necesarul de spaţiu de memorie (în
octeţi) pentru înregistrarea unor valori adecvate. Pe parcursul execuţiei unui program,
valoarea unei variabile poate fi precizată şi modificată prin trei procedee: iniţializare prin
directiva #define, expresii de atribuire şi funcţii de citire. Secţiunea următoare va
cuprinde cîteva detalii privitoare la structura memoriei de tip RAM şi principalele
caracteristic ale acesteia.
Declararea unei variabile trebuie să preceadă orice utilizare a ei. Pentru aceeaşi
variabilă pot exista mai multe linii de declarare în funcţie de contextul de rezolvare al
problemei.

V. Categorii de variabile
O declarare de variabile constă dintr-un tip de dată şi o listă cu un număr nedeterminat de
variabile de acel tip separate prin virgulă, care se poate completa opţional cu iniţializări
adecvate.
Sintaxa generală a unei declarări de variabile se prezintă astfel:
tip_de_dată v_1[=const_1], v_2[=const_2], … v_n[=const_n];
unde n>=1, v_i sînt indentificatorii de recunoaştere a variabilelor, iar const_i sînt
constantele cu care se iniţializează v_i, i=1, 2, …, n.
Amplasamentul şi sintaxa declaraţiei fixează atributele care se asociază în mod implicit
unui indentificator de variabilă. Cu ajutorul specificatorilor de tip se pot adăuga, în mod
explicit, noi atribute sau se pot schimba cele existente.
Pentru clasificarea variabililor se consideră următoarele criterii:

4
- după modul de gestiune a valorilor primite variabilele sînt de intrare, de ieşire şi
intermediare.Variabilele intermediare gestionează datele tranzitorii, iar cele de intrare şi
ieşire precizează datele cunoscute şi respectiv rezultatele problemei de rezolvat;
- după tipul valorii, acestea se împart în variabile numerice, de tip caracter sau şir
de caractere. Dimensiunea şi structura zonei de memorie afectată unei variabile este
conform tipului de valoare atribuită;
- după durata de alocare a spaţiului de memorie (durata de viaţă, timpul de viaţă)
există două categori de variabile: statice şi dinamice. Dacă spaţiul de memorie alocat în
faza de compilare rămîne neschimbat în timpul execuţiei programului, atunci variabila
este statică, altfel este dinamică. Pentru toate tipurile de date statice, dimensiunea zonei
de memorie se extrage automat din declaraţiile de variabile prevăzute într-un program, în
faza de compilare a programului. Pentru structurile de date a căror dimensiune este
necunoscută sau variază în limite mari (adică, pentru cele dinamice), după lansarea în
execuţie a programului, spaţiul de memorie necesar se alocă şi se eliberează de către
programator prin funcţiile standard malloc() şi respectiv free().
- după domeniul de vizibilitate variabilile sînt locale, nelocale şi globale.
Domeniul de vizibilitate este porţiunea de program în care poate fi accesată valoarea
asociată unei variabile. Variabilele
Macrodefiniţii declarate
(Variabile în interiorul blocului de funcţie sînt de tip
globale)
local şi nu sînt vizibile în afara acelei funcţii. Pentru a fi folosite în blocuri exterioare, ele
se decalară din nou. Variabilele nelocale sînt declarate în exteriorul blocurilor funcţiilor
imbricate. Variabilele definite în funcţia nivel_1 vor fi considerate nelocale pentru
funcţiile nivel_2a şi nivel_2b, aşa cum se vede în figura 2.4.2.1.

Funcţia main()
Declaraţii de variabile globale;

Funcţie nivel_1
Declaraţii de variabile locale;

Funcţie nivel_2a
Declaraţii de variabile locale;
Declaraţii de variabile locale redefinite;

Funcţie nivel_2b
Declaraţii de variabile locale;
Declaraţii de variabile locale redefinite;

Figura 6.5.1

5
Variabililele definite în exteriorul oricărei funcţii din programul sursă sînt de tip global.
Acestea sînt de tip static şi sînt vizibile pentru întreg programul executabil, însă totuşi cu
declarările locale se obţine o viteză de lucru mai rapidă.
Alocarea variabilelor neglobale (sau automatice) se face în segmentul de stivă sau
memoria de tip registre, iar a celor globale în segmentul de date. Altfel spus, aceste
declarări pot acoperi cel mult 65536 de octeţi. Schema grafică a geografiei memoriei la
momentul prelucrării unui program se prezintă în anexa 6. Fără să se creeze confuzii,
există posibilitatea de a folosi aceleaşi nume de variabile în ambele situaţii. Deci, în
corpuri de funcţii distincte sînt acceptate declararea şi utilizarea unor variabile cu nume
egale, chiar cu semnificaţii diferite.
- după numărul liniilor de declarare a unei variabile (în acelaşi fişier sursă sau în
diferite unităţi de traducere (fişier, funcţie)), aceasta poate fi cu legătură internă, cu
legătură externă şi fără legătură.
Produsul imagine memorie translatabilă (IMT) executabil se obţine prin editarea
legăturilor între fişierele obiect în format binar translatabil (BT), care sînt traducerea în
binar a fişierelor sursă compilate cu succes, împreună cu funcţiile predefinite din
biblioteci. De multe ori, pentru stabilirea corectă a corespondenţelor între
amplasamentele declaraţiilor de variabile şi zona de memorie alocată în procesul de
editare a legăturilor, se impune crearea a mai multor replici pentru aceeaşi variabilă.
Dacă apariţia variabilei într-o unitate de traducere este cu legătură internă, atunci orice
replică vizează aceeaşi zonă de memorie. De asemenea, în fişierul executabil pot
corespunde mai multe zone de memorie unui singur indentificator de variabilă.
Dacă apariţia variabilei este cu legătură externă, atunci orice replică din unităţile de
traducere, care formează produsul executabil, se asociază unei singure zone de memorie
sau funcţii.
Dacă apariţia variabilei este fără legătură, atunci nu există replici şi zona de memorie
alocată indentificatorului de variabilă este unică. În general, din această categorie fac
parte indentificatorii care nu au afectate zone de memorie.
Pentru variabile globale, legătura implicită este cea externă. Prin specificatorul de tip
static aceasta poate fi schimbată în una de tip intern. Tipul de legătură pentru variabilile
nelocale rezultă, în mod implicit, din sintaxa declaraţiei globale, dacă există şi este cu
vizibilitate sau se stabileşte pe extern şi intern, în mod explicit, prin specificatorii extern
şi respectiv static.
Variabilele statice sînt implicit iniţializate cu zero sau explicit cu valori nenule. La
variabilele globale sînt admise definiţii de redeclarare, dar nu şi de reiniţializare.
Programul 6.5.1 şi rezultatele aferente acestuia, fără alte texte explicative, ilustrează
cîteva exemple simple de declarări variabile cu tipuri întregi, în virgulă mobilă şi
caracter. În mod implicit, acestea sînt statice şi gloabale. Varibilele x1, y, z, w1 şi c se
iniţializează în ordine cu 123, 012, 0xa, 17.75e+5 şi respectiv ‘r’, celelate două (adică, x
şi w) primesc de la dispozitivul de intrare al calculatorului valorile 456 şi respectiv 89.7.
/* Declaratii si initializari de variabile */
#include <stdio.h>
#include<conio.h>
void main(void)
{ int x, x1 = 123, y = 012, z = 0xA;
float w;

6
double w1 = 17.75e+5;
char c=’r’;
printf("Introduceti: x = "); scanf("%d", &x);
printf("Introduceti: w = "); scanf("%f", &w);
printf("Valori intregi zecimale: x = %d x1 = %d", x, x1);
printf("\nValoare intreaga octala: y = %o ",y);
printf("\nValoare intreaga hexzecimala: z = %x ", z);
printf("\nValori in virgula mobila: w = %f w1 = %lf", w, w1);
printf("\nValoare de tip caracter: c = %c ", c);
getch(); }
Introduceti: x = 456
Introduceti: w = 89.7
Valori întregi zecimale: x = 456 x1 = 123
Valoare întreaga octala: y = 12
Valoare întreaga hexazecimala: z = a
Valori în virgula mobila: w=-89.699997 w1=1775000.000000
Valoare de tip caracter: c = r
Programul 6.5.1
În concluzie, o parte din atributele descrise mai sus se asociază numelui unei variabile
implicit, altă parte, în mod explicit. Astfel, atributul unei variabile de a fi de tip numeric
sau de tip caracter rezultă din valoarea asociată variabilei. Poziţia liniei de declarare în
program determină domeniul în care aceasta poate fi cu sau fără vizibilitate. Utilizarea
specificatorilor static, extern, register sau auto şi a modificatorilor de acces const sau
volatile în sintaxa de declarare a variabilei permite adăugarea, în mod explicit, a unor noi
atribute.

VI. Declaraţia typedef


Declaraţia typedef facilitează redenumirea tipurilor standard prin diverse nume simbolice
nerezervate sau definirea de noi tipuri de date conform dorinţelor utilizatorului. O
variabilă se asociază, în mod explicit, cu o anumită declaraţie typedef în modulele din
componenţa programului.
Formatul general al declaraţiei typedef este după cum urmează:
typedef nume_tip nume_nou_tip;
În programul următor tipurile standard int şi long se redenumesc prin nou_int şi respectiv
nou_long.
/* Utilizarea declaratiei typedef */
#include <stdio.h>
#include<conio.h>
typedef int nou_int;
typedef long nou_long;
void main(void)
{ nou_int i;
nou_long x = 3.5;
printf("i = %d x = %5.1f", i, x); getch(); }
i=0 x = 3.5
Programul 6.6.1

7
VII. Tablouri
O colecţie ordonată de valori de acelaşi tip desemnată printr-un identificator formează un
tablou (sau masiv). Cu numele tabloului se denumeşte fiecare element al tabloului, iar
valorile indicilor fixează poziţia acestora în tablou. Orice indice se scrie între paranteze
pătrate. Elementele tabloului se înregistrează secvenţial într-o zonă contiguă de memorie
la care se asigură acces direct. Cantitatea de memorie afectată tabloului se determină prin
înmulţirea numărului de elemente din tablou (adică, talia tabloului) cu lungimea în octeţi
a locaţiilor de memorie ocupate de un element, care este în concordanţă cu tipul tabloului.
Timpul de acces pentru fiecare element de tablou este constant. Dimensiunile tabloului
nu se modifică în timp, adică tabloul se consideră o structură statică de date omogene.
Mai precis, implementarea noţiunii de tablou în limbajul C++ se face prin
definirea unei colecţii de perechi (index, v_e), unde index aparţine la o mulţime numere
asociate locaţiilor de memorie utilizate pentru depozitarea tabloului, iar v_e sînt valorile
conţinute în tablou care pot fi modificate în timp conform cerinţelor utilizatorului.
De exemplu, vectorul (tabloul unidimensional) X = (3, 5, 8) poate fi conceput ca
mulţimea de perechi {(0, 3), (1, 5), (2, 8)}, iar matricea (tabloul bidimensional)
2 4
Α=
5  poate fi gîndită ca mulţimea de perechi {((0, 0) 2), ((0, 1), 4), ((1, 0), 5), ((1,
 6

1), 6)}.

a) Tablouri unidimensionale
Numele simbolic al unui tablou unidimensional, talia lui şi tipul elementelor componente
se declară explicit printr-o costrucţie sintactică de forma:
tip_elem nume_tablou[dim];
unde, tip_elem este un tip de date standard, nume_tablou este identificatorul de
recunoaştere al tabloului stabilit de programator, iar dim este o constantă întreagă fără
semn care precizează dimensiunea tabloului. O declaraţie de tablou de acest gen se
numeşte declaraţie cu definire. O declaraţie fără definire (de referinţă) nu cuprinde în
sintaxa ei argumentul dim. O definire ulterioară a acestui argument se impune în mod
obligatoriu.
De exemplu, pentru declararea unui tablou unidimensional vector se poate folosi
una din formele: - cu definire double vector[5];
- fără definire double vector[ ];
Numai în prima situaţie se alocă o zonă de memorie egală cu 40 de octeţi tabloului
vector. Este bine de reamintit că, zona de memorie afectată unui element de tablou se află
cu operatorul unar size(tip_elem).
Referirea unui tablou, în totalitate, se face prin numele tabloului. Cu formatul general
nume_tablou[expresie_indice] se selectează un anumit element din tabloul cu numele de
indentificare nume_tablou. Ca indice poate fi o constantă întreagă fără semn, o variabilă
de tip întreg sau o expresie întreagă, care va fi evaluată la momentul selectării
elementului respectiv. Primul element din tablou corespunde valorii indicelui 0, iar
ultimul element de tablou valorii indicelui dim-1. Cum dimensiunea necesarului de
memorie fixată pentru (orice fel de) tablou în faza de compilare nu se verifică în faza de
execuţie a programului este posibil o violare a memoriei, fără să fi fost detectată, dacă
valoarea indicelui depăşeşte limita sa superioară (de dim-1). Înscrierea sau încercarea de

8
consultare a valorilor elementelor care ies în afara taliei tabloului, fie poate distruge zone
de date sau de instrucţiuni alocate sau nu programului respectiv, fie permite utilizarea de
valori necontrolabile. În concluzie, se cere un control strict din partea programatorului
asupra listei de valori primită de un indice.
Ca exemplu, problema calculării mediei aritmetice a unui şir finit de numere reale
din secţiunea Cîteva exemple de programe C++. Numerele utilizate în media aritmetică,
se aranjează într-un tablou unidimensional de lugime 10 cu numele simbolic x. Linia de
declarare a tabloului x cuprinde tipul float, dimensiunea fixată prin NR_ELEM şi valorile
de la 1 la 10 cu care se iniţializează elementele lui x.
/* Programul calculeaza media aritmetica a
n valori reale organizate intr-un tablou
unidimensional x cu ajutorul lui do-while */
#include <stdio.h>
#include <conio.h>
#define NR_ELEM 10
void main(void)
{ int i = 1;
float x[NR_ELEM]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
double suma = 0, medie_a;
clrscr();
do
{ suma += x[i]; i++; }
while(i <= NR_ELEM);
medie_a = suma/NR_ELEM;
printf(" Media aritmetică este = %f ", medie_a," \n");
getch(); }
Media aritmetică este =5.500000
Programul 6.7.1
Observaţie. Declararea unui tablou unidimensional poate fi completată cu un set
de valori de un tip compatibil cu tipul elementelor tabloului, astfel:
tip_elem nume_tablou[dim]={lista_valori};
Dimensiunea şi acoladele se pot omite.
În ordine începînd cu primul element şi terminînd cu ultimul, elementele tabloului se
iniţializează cu valori de un tip corespunzător. Dacă lungimea listei este mai mică decît
dimensiunea tabloului, atunci ultimele elemente se iniţializează cu zero. În caz contrar, se
emite eroarea “Too many initializers”.
De exemplu, cu declararea int t[6]={4,16}; se obţin următoarele iniţializări:
t[0]=4, t[1]=16, t[2]=0, t[3]=0, t[4]=0, t[5]=0.

b) Tablouri de tip şiruri de caractere


Am arătat că memorarea şirurilor de caractere se obţine prin declararea acestora ca
tablouri unidimensionale de lungime egală cu cea a şirului de caractere.
Sintaxa generală de declarare a unui tablou şir de caractere este următoarea:
char nume_sir[nr_elem] ;.

9
Zona de memorie alocată şirului de caractere cuprinde nr_elem+1 octeţi, ultimul fiind
afectat caracterului NULL (\0). Aceasta poate fi ocupată, fie în totalitate, fie parţial, cu
codurile ASCII corespunzătoare caracterelor componente.
Cu nume_sir se precizează adresa şirul în întregime, iar cu nume_sir[indice]
adresa cracterului cu poziţia indice în şir. Pentru tratarea variabilelor de tip şir de
caractere, la nivel de tablou, în operaţiile de intrare/ieşire se utilizează, în funcţiile
scanf() şi respectiv printf(), descriptorul de format “%s”. La nivel de caracter se foloseşte
“%c”. Observaţia de la sfîrşitul secţiunii anterioare se aplică şi în cazul tablourilor şir de
caractere.
Biblioteca standard C++ pune la dispoziţia utilizatorului un sortiment bogat de
funcţii pentru prelucrarea şirurilor de caractere. Lista acestora se prezintă în anexa 4.
Astfel, programul 6.7.2 evidenţiază aspecte legate de citirea/scrierea unor şiruri de
caractere, de prelucrare a lor cu ajutorul funcţiilor standard de copiere, de concatenare şi
de aflare a lungimii lor. Iniţializarea şirului s1 cu un şir de caractere particular se face în
linia de declarare tip ataşată acestuia care, pe lîngă definirea lui, precizează zona de
memorie necesară alocării lui. Înainte de a se tipări primul şir, acesta se concatenează cu
subşirul s3 prin intermediul funcţiei strcat(). Cel de al doilea, însă, rămîne în centrul
atenţiei noastre pînă la sfîrşitul programului. După fiecare prelucrare, valoarea lui se
afişează cu printf(), fie în totalitate cu referire prin nume, fie punctual cu referire la nivel
de caracter prin intermediul unui for. Ultima afişare a lui s2 se face cu funcţia puts(). O
primă valoare (un nume) i se afectează prin funcţia strcpy(), apoi i se schimbă valoarea
prin funcţiile gets() şi scanf(). Şirul de caractere Vasilescu se completează prin
concatenare, ulterior, cu subşirurile "Ioan" şi s3, prin intermediul funcţiei strcat(). În
finalul programului se scriu lungimele şirurilor de caractere s1 şi s2 cu strlen(s1) şi
respectiv strlen(s2).
/* Initializare tablouri siruri de caractere */
#include<stdio.h>
#include<conio.h>
#include<string.h>
#define M 20
#define N 30
void main (void)
{int i,j,k;
char s1[M] = "Ionescu Vasile "; char s2[N]; char s3[] = "Iasi"; clrscr();
strcat(s1, s3); /* Se concateneaza sirurile s1 si s3 */
printf("\nSirul s1=%s", s1); /* Se scrie sirul s1 */
strcpy(s2,"Popescu");
printf("\nSirul s2=%s\n", s2); /* Se scrie sirul s2 */
gets(s2); printf("Sirul s2=%s\n", s2);
scanf("%s2=%s",s2,"\n"); printf("Sirul s2=%s\n", s2);
strcat( s2," Ioan ");
strcat(s2, s3); /* Se adauga prin concatenare la s2 sirul s3 */
/* Se scrie sirul s2 */
for(i = 0; s2[i] != ’\0’; ++i) printf("%c", s2[i]); printf("\n");
puts(s2);
/* Se tiparesc lungimile celor doua siruri */

10
printf("Lungimele sirurilor sint %d si %d", strlen(s1), strlen(s2)); getch(); }
Sirul s1=Ionescu Vasile Iasi
Sirul s2=Popescu
Constantinescu
Sirul s2=Constantinescu
Vasilescu
Sirul s2=Vasilescu
Vasilescu Ioan Iasi
Vasilescu Ioan Iasi
Lungimea sirurilor sint 19 si 20
Programul 6.7.2
c) Tablouri multidimensionale
Formatul general al definirii unui tablou multidimensional este următorul:
tip_elem nume_tablou [dim_1][dim_2] … [dim_n];
unde n>1. Tip_elem, nume_tablou şi dim_i, cu i=1, …, n, au semnificaţii analoage celor
din secţiunea 2.5.1. Spaţiul de memorie contiguu afectat unui tablou multidimensional
este egal cu valoarea produsului dim_1 x dim_2 x … x dim_n x size(tip_elem) în octeţi.
Referirea unui element de tablou multidimensional se face printr-o construcţie de genul:
nume_tablou[indice_1] ][indice_2] … [indice_n],
unde indice_i, cu i=1, …, n, primeşte valori de la 0 la dim_n-1.
Rămîne valabilă observaţia privitoare la iniţializarea cu valori a unui tablou.
Acoladele care delimitează valorile corespunzătoare elementelor tablourilor
unidimensionale din structura logică a tabloului multidimensional sînt opţionale. De
asemenea, se recomandă ca în linia de declarare a unui astfel de tablou cel mult prima
dimensiune să se omită, altfel modul de organizare a elementelor rămîne aleatoriu şi
referirea corectă a acestora nu ar fi posibilă.
Programul 6.7.3 ilustrează, în două ipostaze, iniţializarea elementelor unei matrice
cu 2 şi 3 coloane. În linia de declarare de tip corespunzătoare matricei b, componentele
acesteia se iniţializează cu diverse constante raţionale în simplă precizie. Apoi,
elementele matricei b, poziţie cu poziţie, se transferă elementelor matricei a prin
intermediul a două instrucţiuni for. La sfîrşitul programului sînt prezentate rezultatele
funcţiei de tipărire printf().
#include<stdio.h> /* Initializare tablouri bidimensionale */
#include<conio.h>
#define M 2
#define N 3
void main (void)
{ int i, j; float a[M][N];
float b[M][N]={{3.5, 4.5, 2.22}, {-2.3, 4.55, -.123}};
for( i = 0; i < M; ++i) for( j = 0; j < N ;j++)
{a[i][j] = b[i][j]; printf("\n a[%d,%d]=%f", i, j, a[i][j]); }getch(); }
a[0,0]=3.500000 a[1,0]=-2.300000
a[0,1]=4.500000 a[1,1]=4.550000
a[0,2]=2.220000 a[1,2]=-0.123000
Programul 6.7.3

11

S-ar putea să vă placă și