Documente Academic
Documente Profesional
Documente Cultură
char *nume; = atunci cand se declara variabila nume ca pointer la char, de fapt se
anunta compilatorul ca aceasta variabaila va urma sa faca referire (sa referentieze) o
zona din memorie care retine date de tip char;
strcpy(nume, "ABC"); = se incearca sa se pune stringul ABC in zona la care variabila
pointer nume face referire. Numai ca la acest pas, pointerul nume nu face referire la
nicio zona de memorie, deci stringul ABC nu am inca un sa-l pun;
Acesta este un exemplul clasic de eroare de logica (ce va duce si la eroare de rulare) de a
incerca sa pun ceva intr-un pointer neinitializat. Eroarea in acest caz este :
(aceasta eroare este afisata la rularea aplicatiei pe un Windows 7, dar va fi ceva similar pe
orice alta versiune de Windows).
Solutia este de a aloca manual spatiu de memorie catre care, in final, pointerul nume va
referentia. Adica asa cum este aratat in exemplulurmator
adica aloc o zona de memorie de 20 de locatii, in fiecare locatie putand sa pun un char.
Sprea aceasta zona de memorie nou alocata va indica variabila mea pointer nume
declarata anterior.
Mai departe, cand incerc sa pun stringul ABC in nume, de fapt acest string este pus in
memoria alocata anterior, catre care nume va referentia. Cum memoria a fost alocata cu
succes, de data aceasta aplicatia va rula cu succes:
In zona de memorie nou alocata cu malloc() nu stiu exact ce voi gasi, inainte sa incep eu sa
pun date in ea. De obicei, imediat dupa alocarea unei astfel de zone in care urmeaza sa pun
ceva, fac o initializare a zonei cu date implicite, in general in functie de tipul de date ce
urmeaza sa pun acolo, si anume :
- Daca urmeaza sa pun valori numerice, atunci initalizez zona cu valoarea 0 (un fel de
element neutru pentru date numerice);
- Daca urmeaza sa pun caractere, initializez zone cu caracterul \0 (spuneam ca acest
caracter este interpretat ca simbol pentru finalul de sir de caractere), sau cu
caracterul spatiu .
Bineinteles, acestea nu sunt decat indicatii, programatorul poate sa initilizeze zona noua
alocata cu ceea ce doreste (functie de necesitati etc).
Un astfel de exemplu in exercitiul urmator :
La rularea aplicatie de mai sus vom obtine, cum era oarecum de asteptat, o eroare
similara celui prezentate la punctul 1 de mai sus. De ce ? Pentru ca cele doua linii de cod :
free(nume);
strcpy(nume, "XYZ");
reproduc practic cazul punctului 1 si anume incercarea de a pune ceva intr-un pointer
neinitializat.
Asa cum spuneam, daca dorim crearea unei aplicatii care sa utilizeze in mod eficient
memoria, avand aceste doua mecaniste alocare, dezalocarea ne putem imagina
exercitiul de mai jos :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//dezaloc memoria
nume = (char*)malloc(5*sizeof(char));
strcpy(nume, "XYZ");
memset(nume, '\0', 5*sizeof(char));
La rulare se afiseaza :
Exercitiul este unul banal, dar ne putem face o imagine despre ceea ce am spus mai sus, si
anume :
la prima alocare de memorie stiu ca voi pune in pointer un sir de caractere mai lung , de
aceea aloc 10 locatii in care sa pun caractere :
nume = (char*)malloc(10*sizeof(char));
astfel alocata memoria, in ea voi pune sirul "ABCDEFGH"
apoi eliberez memoria referentiata de pointerul nume (free(nume)) si aloc o alta, de data
asta insa de numai 5 caractere, pentru ca stiu ca voi pune un sir mai scurt :
nume = (char*)malloc(5*sizeof(char));
in noua zona voi pune sirul "XYZ"
5. Urmatorul exercitiu exemplifica utilizarea celor mai des intalnite functii de prelucrare
a sirurilor de caractere :
char * strcpy( char * destinatie, const char * sursa );
char * strcat( char * destinatie, const char * sursa );
char * strncpy( char * destinatie, const char * sursa, size_t num );
char * strncat( char * destinatie, const char * sursa, size_t num );
size_t strlen( const char * string );
De asemena, am folosit si functii, tot in spirit didactic.
Pentru ca am avut nevoie sa aloc memorie pentru doua variabile de tip pointer la char si
apoi sa initializez memorie alocata, este mai usor ca creez o functie generala
AlocAndInitSir() care aloca memorie de dimensiune data si o initializeaza, returnand un
pointer la memoria alocata. Atfel, daca voi avea nevoie in aplicatie sa creez si alti pointer la
char, pot utiliza (apela) direct functia creata.
De asemena, pentru ca exercitul este unul didactic, de fiecare data cand modific continutul
unui string ii afisez acest continut precum si (nous) dimensiune a lui. Pentru ca este nevoie
sa afcem asta destul de des, atunci e preferabil crearea unei functii generale care sa aiba in
intrare un pointer la char (string) pentru care afisez continutul si lungimea. Aceast afunctie
se numeste AfisareInfoString().
Codul este :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void AfisareInfoString(char *s);
char *AlocAndInitSir(int dimensiune);
int main(int argc, char **argv)
{
char *sir;
char *sir2;
int c;
int dimens = 100;
sir = AlocAndInitSir(dimens);
sir2 = AlocAndInitSir(dimens);
puts("*** Exemplu de lucru cu stringuri ***");
strcpy(sir, "123ABC"); AfisareInfoString(sir);
strcat(sir, "XYZ"); AfisareInfoString(sir);
strncpy(sir, "098765", 4); AfisareInfoString(sir);
strncat(sir, "ABCDEFGHIJ", 5); AfisareInfoString(sir);
strcpy(sir2, "WERTY"); AfisareInfoString(sir2);
//strcmp() este o functie care compara doua stringuri si care intoarce (sau
returneaza) o valoare intreaga:
//
< 0 => primul string este "mai mic" decat al doilea
// = 0 => cele doua stringuri au acelasi continut
// > 0 => primul string este "mai mare" decat al doilea
//Notiunea de "string mai mare sau mai mic decat un altul" se refera la
comparatia caracter cu caracter,
//incepand din partea stanga a ambelor stringuri, dupa codul ASCII al
caracterelor.
//De exemplu : sir ="abc" si sir2 = "mnport". Cand compar cele doua
stringuri se testeaza :
//
cum este caracterul 'a' fata de caracterul 'm' ?
//
R : este mai mic, deoarece codul ASCII pt caracterul 'a' este mai mic
decat codul ASCII al caarcterului 'm'
// => sir1 < sir2
c = strcmp(sir, sir2);
printf("\nSir 1 = '%s' , sir 2 = '%s'. Rezultatul comparatiei este %d\n ",
sir, sir2, c);
return 0;
}
/*Functie care aloca si initializeaza cu 0 un spatiu de memorie de o dimensiune
data, spatiu in care voi pune caractere.
Functia intoarce un pointer catre acel spatiu alocat.*/
char *AlocAndInitSir(int dimensiune)
{
char *s;
s = (char*)malloc(dimensiune*sizeof(char));
memset(s, '\0', dimensiune);
return s;
}
//Functie care afiseaza continutul unui string si dimensiunea (lungimea) lui.
//Lungimea unui string = numarul de caractere din acel string
void AfisareInfoString(char *s)
{
printf("\nSirul este '%s' si are lungimea = %d\n", s, strlen(s));
}