Documente online.
Zona de administrare documente. Fisierele tale
Am uitat parola x Creaza cont nou
 HomeExploreaza
upload
Upload




Pointeri pe caractere si functii

c


Pointeri pe caractere si functii

Un sir constant scris astfel

"I am a string "

este un tablou de caractere. In reprezentare interna, compilato-
rul termina un tablou cu caracterul \0 in asa fel incit programele
sa poata detecta sfirsitul. Lungimea in memorie este astfel
mai mare cu 1 decit numarul de caractere cuprinse intre ghilimele.
Poate cea mai comuna aparitie a unui sir de constante
este ca argument al functiei cum ar fi in

char *message;

atunci instructiunea

message = "now is the time";

asigneazaa lui mesage un pointer in functie de caracterele
reale. Aceasta nu este o copie a sirului; nu sint implicati 525f57f decit
pointerii. C nu este inzestrat cu alti operatori care sa trateze
eze un sir de caractere ca o unitate.
Vom ilustra mai multe aspecte in legatura cu pointerii si cu
tablourile stiind ca doua functii cu adevarat utile, din bibliote-
ca standard de I/O, subiect care va fi discutat in capitolul 7.
Prima functie este strcpy(s, t) care copiaza sirul t in
sirul s. Argumentele sint scrise in aceasta ordine prin analogie
cu aranjarea, unde cineva ar putea spune

s = t

pentru a asigna pe t lui s. Versiunea ca tablouri este mai intii.

strcpy(s, t) /*copiaza t in s */
char s[], t[];


Iata o versiune a lui strcpy cu pointeri

strcpy(s, t) /* copiaza t in s, versiunea pointeri 1*/
char *s, *t;

}


Deoarece argumentele sint transmise prin valoare, strcpy
poate utiliza s si t in orice fel se doreste. Aici ei sint
conventional utilizati ca pointeri, care parcurg tablourile pina
in momentul in care s-a copiat \0 sfirsitul lui t, in s.
In practica, strrcpy nu va fi scris asa cum s-a aratat
mai sus. O a doua posilitate ar fi

strcpy(s, t) /* copiaza t in s, versiunea 2*/
char *s, *t;


In aceasta ultima versiune se imita incrementarea lui s si t in
partea de test. Valoarea lui *t++ este caracterul pe care a
pointat inainte ca t sa fi fost incrementat; prefixul ++ nu-l
schimba pe t inainte ca acest caracter sa fi fost adus. In acelasi
fel, caracterul este stocat in vede a pozitie s inainte ca s sa
fie incrementat. Acest caracter este deasemenea valoarea care
se grupeaza cu \0 pentru simboul buclei. Efectul net este ca,
caracterele sint copiate din t in s, inclusiv sfirsitul lui \0.
Ca o ultima abreviere vom observa ca si gruparea cu \0 este
redundanta, astfel ca functia este adesea scrisa ca

strcpy(s, t) /* copiaza t in s; versiunea pointeri 3 */
char *s, *t;


Desi aceasta versiune poate parea compilcata la prima vedere,
aranjamentul ca notatie este considerat suveran daca nu exista
alte ratiuni de a schimba astfel ca il veti intilni frecvent in
programele C.

A doua rutina este strcmp(s, t) care compara sirurile de
caractere s si t si returneaza negativ, zero sau pozitiv in
functie de relatia dintre s si t; care poate fi: s<t, s=t sau
s>t. Valoarea returnata este obtinuta prin scaderea caracterului
de pe prima pozitie unde s difera de t.

strcmp(s, t)
/* returneaza <0 daca s<t, 0 daca s==t, >0 daca s>t */
char s[], t[];


Versiunea pointeri a lui strcmp.

strcmp(s, t) /* returneaza <0 daca s<t, 0 daca s==t,
>0 daca s>t */
char *s, *t;


Daca ++ si -- sint folositi altfel decit operatori prefix sau
postfix pot apare alte combinatii de * si ++ si --, desi mai putin
frecvente. De exemplu:

*++p

incrementeaza pe p inainte de a aduce caracterul pe care pointeaza
p.

*--p

decrementeaza pe p in acelasi conditii.

Exercitiul 5.2. Scrieti o versiune pointeri pentru o functie
strcat expusa in capitolul 2: strcat(s, t) copiaza sirul t la
sfirsitul sirului s.

Exercitiul 5.3. Scrieti un macro pentru strcpy.

Exercitiul 5.4. Rescrieti variantele programelor din capito-
lele anterioare si exercitii cu pointeri in loc de tablouri
indexate. Bune posibilitati ofera: getline, atoi, itoa si vari-
antele lor, reverse, index, getop.

5.6. Pointerii nu sint de tip int

S-a putut observa ca programele C mai vechi au o atitudine mai
toleranta fata de copierea pointerilor. In general a fost adevarat
ca pe majoritatea masinilor un pointer poate fi asignat unui
intreg si invers, fara a-l schimba; nu are loc nici o scalare
sau conversie si nu se pierd biti. In mod regretabil aceasta
stare de lucruri a condus la asumarea unor libertati nepermise
desi partea programatorului in lucru cu rutina ce returneaza
pointeri ce sint transmisi apoi pur si simplu altor rutine -
necesitatea declararii pointerului fiind adesea omisa. De exemplu,
sa luam o functie strsave care copiaza sirul s undeva, intr-o
zona obtinuta printr-un apel la alloc, returnind apoi un pointer
pe ea. Strsave se poate scrie astfel

char *strsave(s) /* salveaza undeva sirul s */
char *s;


In practica, exista o tendinta puternica de a omite declararile:

strsave(s) /* salveaza undeva sirul s */


Acest cod s-ar putea sa mearga pe multe masini deoarece tipul
implicit al functiilor si al argumentelor este int iar atit int-ul
cit si pointerul pot fi asignati la inceput cit si la sfirsit. Cu
toate acestea, acest gen de cod este inerent riscant deoarece el
depinde de detalii de implementare si de arhitectura masinii, care
nu pot fi rezolvate pentru compilatorul particular utilizat de
dvs. Este recomandabil sa se efectueze toate declararile necesare.
(Programul lint va avertiza in legatura cu astfel de restrictii
in cazul in care se vor strecura inadvertente).




Document Info


Accesari: 1037
Apreciat: hand-up

Comenteaza documentul:

Nu esti inregistrat
Trebuie sa fii utilizator inregistrat pentru a putea comenta


Creaza cont nou

A fost util?

Daca documentul a fost util si crezi ca merita
sa adaugi un link catre el la tine in site


in pagina web a site-ului tau.




eCoduri.com - coduri postale, contabile, CAEN sau bancare

Politica de confidentialitate | Termenii si conditii de utilizare




Copyright © Contact (SCRIGROUP Int. 2024 )