Scrigroup - Documente si articole

Username / Parola inexistente      

Home Documente Upload Resurse Alte limbi doc  
AccessAdobe photoshopAlgoritmiAutocadBaze de dateCC sharp
CalculatoareCorel drawDot netExcelFox proFrontpageHardware
HtmlInternetJavaLinuxMatlabMs dosPascal
PhpPower pointRetele calculatoareSqlTutorialsWebdesignWindows
WordXml


Pointeri

c



+ Font mai mare | - Font mai mic



Pointeri

Probleme rezolvate

P9.1 Scrieti un program care determina suma elementelor de pe diagonala unei matrice patrate de dimensiune maxima 10  10 formata din numere reale. Pentru citirea matricei se va scrie si utiliza o functie care citeste matricea impreuna cu dimensiunile sale efective.



#include <stdio.h>

#include <stdlib.h>

#define DIMMAX 10

void citmat(float mat[][DIMMAX], int *dim);

int main(void)

void citmat(float mat[][DIMMAX], int *dim) while (*dim > 10 || *dim < 0);

for(i = 0; i < *dim; i++)

for(j = 0; j < *dim; j++)

Programul va afisa pe ecran, dupa compilare si executie:

Introduceti dimensiunea efectiva (<=10) :20

Introduceti dimensiunea efectiva (<=10) :2

mat[0][0] = 1

mat[0][1] = 2

mat[1][0] = 3

mat[1][1] = 4

Suma elementelor de pe diagonala este: 5.000000

Discutie

-  Acest program pune in evidenta utilizarea pointerilor la transferul unei valori dintr‑o functie. Al doilea parametru al functiei citmat() este un pointer prin intermediul caruia se transfera dimensiunea efectiva a metricei.

P9.2 Scrieti un program care determina suma elementelor de pe diagonala unei matrice patrate formata din numere reale. Pentru citirea matricei se va scrie si utiliza o functie care citeste matricea impreuna cu dimensiunile sale efective. Precizare: desi problema pare identica cu problema 9.1 nu este asa de aceasta data programul trebuie sa poata prelucra matrice oricat de mari.

#include <stdio.h>

#include <stdlib.h>

float **citmat(int *dim);

int main(void)

sumdiag = 0.0;

for(i = 0; i < dimef; i++)

sumdiag += mat[i][i];

printf('Suma elementelor de pe diagonala este: %fn',

sumdiag);

system('PAUSE');

return 0;

float **citmat(int *dim)

/* Se aloca memorie pentru fiecare linie a matricei */

for(i = 0; i < *dim; i++)

if(!(mat[i] = (float *)malloc(*dim * sizeof(float))))

/* Se citesc elementele matricei */

for(i = 0; i < *dim; i++)

for(j = 0; j < *dim; j++)

return mat;

Programul va afisa pe ecran, dupa compilare si executie:

Introduceti dimensiunea efectiva: 2

mat[0][0] = 1

mat[0][1] = 2

mat[1][0] = 3

mat[1][1] = 4

Suma elementelor de pe diagonala este: 5.000000

sau

Introduceti dimensiunea efectiva: 123456

Matricea este prea mare!

Matricea nu se poate citi!

Discutie

-  Acest program pune in evidenta utilizarea pointerilor pentru alocarea dinamica a unei matrice. Se observa ca matricea este declarata ca fiind de tip loat ** adica de tip "pointer la pointer". In functia citmat() se aloca mai intai un vector de pointeri care reprezinta matricea propriu‑zisa si apoi se aloca cate un pointer catre fiecare rand din matrice. Se observa ca procedand astfel elementele matricei se pot adresa exact ca atunci cand matricea a fost alocata static.

P9.3 Scrieti un program care afiseaza pe ecran continutul si adresele a doua variabile de tip intreg, apoi atribuie adresa uneia dintre ele unui pointer si reia afisarea utilizand pointerul.

#include <stdio.h>

#include <stdlib.h>

int main()

Programul va afisa pe ecran, dupa compilare si executie:

j are valoarea 1 si este stocat la adresa 0022FF6C

k are valoarea 2 si este stocat la adresa 0022FF68

ptr are valoarea 0022FF68 si este stocat la adresa 0022FF64

Valoarea int catre care arata pointerul este: 2

Discutie

-  Programul pune in evidenta modul de utilizare a pointerilor. Se observa faptul ca inainte de a fi utilizat, pointerului trebuie sa i se atribuie o adresa valida. Daca se omite instructiunea:

ptr = &k;

afisarea va arata astfel:

j are valoarea 1 si este stocat la adresa 0022FF6C

k are valoarea 2 si este stocat la adresa 0022FF68

ptr are valoarea 004010C0 si este stocat la adresa 0022FF64

Valoarea int catre care arata pointerul este: 807409035

-  Precizam ca adresele afisate pot diferi de cele de mai sus in functie de spatiul de memorie alocat programului de catre sistemul de operare precum si faptul ca in varianta eronata este posibil ca programul sa nu functioneze de loc.

P9.4 Scrieti un program care construieste un vector si il afiseaza atat in mod obisnuit, cat si utilizand pointeri. Programul va afisa apoi adresele elementelor din vector si valorile lor. Se va incerca si depasirea dimensiunilor tabloului.

#include <stdio.h>

#include <stdlib.h>

int main() ;

int *ptr;

int i;

ptr = &tablou[0]; /* sau ptr = tablou; */

printf('n');

/* Afisarea vectorului */

for(i = 0; i < 6; i++)

printf('n');

/* Afisarea adreselor la care sunt stocate elementele

vectorului */

for(i = 0; i < 6; i++)

printf('adresa pentru tablou[%d]: %dn', i, ptr+i);

printf('n');

/* Afisare cu depasirea spatiului vectorului */

for(i = 0; i <= 6; i++)

printf('n');

system('PAUSE');

return 0;

Programul va afisa pe ecran, dupa compilare si executie:

tablou[0] = 1 ptr + 0 = 1

tablou[1] = 23 ptr + 1 = 23

tablou[2] = 17 ptr + 2 = 17

tablou[3] = 4 ptr + 3 = 4

tablou[4] = -5 ptr + 4 = -5

tablou[5] = 100 ptr + 5 = 100

adresa pentru tablou[0]: 2293576

adresa pentru tablou[1]: 2293580

adresa pentru tablou[2]: 2293584

adresa pentru tablou[3]: 2293588

adresa pentru tablou[4]: 2293592

adresa pentru tablou[5]: 2293596

ptr + 0 = 1

ptr + 1 = 23

ptr + 2 = 17

ptr + 3 = 4

ptr + 4 = -5

ptr + 5 = 100

ptr + 6 = 2293664

Discutie

-  Prima instructiune atribuie pointerului ptr adresa primului element din vectorul tablou. Asa cum se arata si in comentariu, aceasta instructiune se poate scrie si

ptr = tablou;

Observatie: Precizam ca un tablou nu este un vector. Din acest motiv atribuirea:

tablou = ptr;

nu este corecta.

-  Primul ciclu for afiseaza valorile memorate in vector utilizand atat direct vectorul cat si pointerul.

-  Cel de al doilea ciclu afiseaza adresele de memorie la care sunt stocate elementele vectorului. Se observa ca elementele vectorului sunt memorate in locatii succesive de memorie.

-  In cel de al treilea ciclu se repeta afisarea, dar se depaseste dimensiunea vectorului. Asa cum se observa din rezultatul rularii programului, limbajul C nu verifica depasirea dimensiunii vectorului. In acest mod programul ruleaza mult mai repede dar programatorul trebuie sa fie foarte atent pentru a nu comite astfel de greseli.

P9.5 Scrieti un program care concateneaza doua siruri de caractere (stringuri) strA si strB, rezultatul fiind depozitat in stringul strA. Programul cauta apoi prima litera 'c' din strA si o inlocuieste cu secventa 'CCC'. In final, se va alipi si portiunea ramasa din strA la stringul final. Prima concatenare se va realiza cu ajutorul pointerilor. Pentru copierile si concatenarile ulterioare se vor utiliza functiile standard strcpy() si strcat()

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

int main()

/* Copiaza strC in locul unde era litera 'c' */

(void)strcpy(pB, strC);

printf('Noul strB: '%s'n', strB);

/* Adauga sirul de caractere salvat */

(void)strcat(pB, paux);

printf('String final: '%s'n', strB);

system('PAUSE');

return 0;

Programul va afisa pe ecran, dupa compilare si executie:

strA = 'Sir de caractere demonstrativ'

Adresa stringului strA: 0022FE24

strB = 'SIR2'

Concatenare stringuri: 'SIR2Sir de caractere demonstrativ'

Inlocuire 'c' cu 'CCC'

Noul strB: 'SIR2Sir de CCC'

String final: 'SIR2Sir de CCCaractere demonstrativ'

Discutie

-  Modul in care se realizeaza concatenarea este similar codului din functia standard strcat(). Aceasta sectiune se poate rescrie intr‑un mod mai compact astfel:

/* Avanseza pana la sfarsitul lui strB */

while(*pB++ != '0');

/* Aduce inapoi la caracterul NULL */

pB--;

/* Copiaza strA in strB inclusiv caracterul NULL */

while((*pB++ = *pA++) != '0');

-  Pentru inlocuirea caracterului 'c' mai intai acesta este localizat. Apoi se salveaza restul sirului de caractere care urmeaza dupa acesta si se compune noul sir de caractere prin doua operatii succesive de concatenare.

P9.6 Scrieti un program care, prin doua functii distincte, verifica egalitatea alfabetica sau numerica a argumentelor, folosind pointeri. Afisarea se va face utilizand functia standard puts() si citirea se va face cu fgets()

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

void verifica(char *a, char *b,

int (*cmp)(const char *, const char *));

int comparanum(const char *a, const char *b);

int main() else

puts('n');

system('PAUSE');

return 0;

void verifica(char *a, char *b,

int (*cmp)(const char *, const char *))

int comparanum(const char *a, const char *b)

Programul va afisa pe ecran, dupa compilare si executie:

Introduceti primul argument:

str1

Introduceti al doilea argument:

str2

Argumente de tip caracter

Verificarea egalitatii: Argumentele nu sunt egale

Discutie

-  Pentru verificarea tipului de valori citite se foloseste functia standard isalpha() care returneaza "adevarat" daca sirul de caractere este de tip alfanumeric (cuprinde si litere) sau "fals" daca este format doar din cifre.

-  Cel de al treilea argument al functiei verifica() este un pointer catre o functie. Functia verifica() apeleaza functia de verificare a egalitatii prin intermediul pointerului la functie.

P9.7 Scrieti un program care incarca valori intr o structura folosind un pointer catre aceasta.

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

struct strpoint s, *p;

/* s este variabila de tip structura si

p un pointer catre o astfel de structura */

int main()

Programul va afisa pe ecran, dupa compilare si executie:

10 10 tablou unidimensional de caractere

Discutie

-  Programul pune in evidenta utilizarea operatorului ->

P9.8 Scrieti un program care schimba intre ele doua linii ale unei matrice de dimensiuni 3  3 elemente reale si apoi le schimba la loc. Se vor defini si utiliza functii diferite pentru citirea unei matrice, afisarea unei matrice precum si pentru schimbarea intre ele a liniilor.

#include <stdio.h>

#include <stdlib.h>

void citeste(float mat[][3])

}

void afiseaza(float mat[][3])

printf('n');

}

void schimba1(float mat[][3], int i, int j)

void schimba2(float mat[][3], int i, int j)

int main(void)

printf('Introduceti indicele celei de a doua linii (<3): ');

scanf('%d', &j);

while(j < 0 || j >= 3)

printf(' ** ** ** ** ** ** *****n');

printf('Liniile inversaten');

schimba1(m, i, j);

afiseaza(m);

printf(' ** ** ** ** ** ** *****n');

printf('Liniile inversate din noun');

schimba2(m, i, j);

afiseaza(m);

system('PAUSE');

return 0;

Programul va afisa pe ecran, dupa compilare si executie:

Introduceti elem. mat[0][0]: 1

Introduceti elem. mat[0][1]: 2

Introduceti elem. mat[0][2]: 3

Introduceti elem. mat[1][0]: 4

Introduceti elem. mat[1][1]: 5

Introduceti elem. mat[1][2]: 6

Introduceti elem. mat[2][0]: 7

Introduceti elem. mat[2][1]: 8

Introduceti elem. mat[2][2]: 9

Inainte de inversarea liniilor

2.000000 3.000000

5.000000 6.000000

8.000000 9.000000

Introduceti indicele primei linii (<3): 0

Introduceti indicele celei de a doua linii (<3): 1

Liniile inversate

5.000000 6.000000

2.000000 3.000000

Liniile inversate din nou

2.000000 3.000000

5.000000 6.000000

8.000000 9.000000

Discutie

-  Schimbarea intre ele a liniilor matricei se face utilizand doua functii diferite. Functia schimba1() pune in evidenta faptul ca in limbajul C o matrice bidimensionala este o matrice unidimensionala formata din matrice unidimensionale. Functia schimba2() utilizeaza pointerii pentru accesul la valorile din matrice.



P9.9 Scrieti un program care cauta un subsir intr un sir de caractere. Programul va afisa pozitia subsirului in sir sau un mesaj de eroare daca subsirul nu a fost gasit.

#include <stdio.h>

#include <stdlib.h>

int cauta(char *sir1, char *sir2)

return -1;

int main(void)

Programul va afisa pe ecran, dupa compilare si executie:

Introduceti primul sir

Unu doi trei

Introduceti sirul al doilea

doi

Sirul 'doi' se gaseste in 'Unu doi trei' la pozitia 4

sau

Introduceti primul sir

Unu doi trei

Introduceti sirul al doilea

patru

Sirul 'patru' nu se gaseste in 'Unu doi trei'

Discutie

-  Se remarca modul in care se face cautarea cu ajutorul a doua cicluri cu contor. Ciclul cu contor exterior avanseaza pozitia de cautare in sirul in care se cauta. Cel de al doilea ciclu realizeaza cautarea propriu‑zisa. Mai intai, la initializarea ciclului, se aduc cei doi pointeri, la inceputul celor doua siruri de caractere. Cautarea continua cat timp mai exista caractere in cele doua siruri si caracterele din cele doua siruri sunt identice. Daca la iesirea din ciclul intern s‑au epuizat caracterele din sirul cautat inseamna ca sirul a fost gasit. Pozitia se determina prin diferenta dintre pointerul care indica inceputul sirului in care se cauta si pointerul care indica inceputul subsirului gasit.

P9.10 Scrieti un program care citeste dimensiunea exacta a unui vector de numere intregi, construieste, citeste si afiseaza acest vector.

#include <stdio.h>

#include <stdlib.h>

int main(void) while(dim <= 0);

if(!(vector = (int *)malloc(dim * sizeof(int))))

printf('Citiren');

for(i = 0; i < dim; i++)

printf('Scrieren');

for(i = 0; i < dim; i++)

printf('vector[%d] = %dn', i, *(vector + i));

free(vector);

system('PAUSE');

return 0;

Programul va afisa pe ecran, dupa compilare si executie:

Introduceti dimensiunea vectorului: 3

Citire

vector[0] = 1

vector[1] = 2

vector[2] = 3

Scriere

vector[0] = 1

vector[1] = 2

vector[2] = 3

sau

Introduceti dimensiunea vectorului: 1567311664

Dimensiunea 1567311664 este prea mare!

Vectorul nu are loc in memorie!

Discutie

-  Programul aloca spatiul de memorie necesar stocarii vectorului. Se verifica faptul ca spatiul de memorie a putut fi alocat. Daca alocarea esueaza, executia programului se intrerupe. Dupa citire si scriere spatiul de memorie alocat este eliberat.

P9.11 Scrieti un program care citeste, sorteaza si afiseaza un vector de siruri de caractere implementand o procedura de tip bubble‑sort si comparand pointerii alaturati.

#include <stdio.h>

#include <stdlib.h>

void sort(char *p[], int nr)

}

}

int main() ;

int j;

printf('Sirurile nesortate sunt:n');

for(j = 0; j < 6; j++)

printf('%sn', p[j]);

sort(p, 6);

printf('nSirurile sortate sunt:n');

for(j = 0; j < 6; j++)

printf('%sn', p[j]);

system('PAUSE');

return 0;

Programul va afisa pe ecran, dupa compilare si executie:

Sirurile nesortate sunt:

Gabi

Bebe

Alina

Claudia

Catalin

Andrei

Ana

Sirurile sortate sunt:

Alina

Ana

Andrei

Bebe

Catalin

Claudia

Gabi

Discutie

-  Prin utilizarea pointerilor catre sirurile de caractere sunt modificate adresele catre care indica pointerii si nu sunt mutate sirurile de caractere propriu‑zise. Efectul ramane cel dorit, dar este obtinut cu un efort de calcul mult mai mic.

Probleme propuse

Scrieti un program care determina de cate ori un subsir de caractere se regaseste intr‑un alt sir de caractere. Indicatie: se va generaliza solutia de la problema 9.9.

Scrieti un program care citeste trei variabile a, b si c si apoi le roteste intre ele astfel: a -> b b -> c si c -> a

Scrieti un program care citeste si sorteaza in ordinea ascendenta data de cuvant_cheie un vector format din inregistrari definite astfel:

typedef struct Inregistrare;

Pentru ordonare / sortare se va utiliza functia qsort() disponibila in bibliotecile standard C si declarata in stdlib.h

Indicatie: functia qsort( este declarata astfel:

void qsort(void *base, int nmemb, int size,
int(*compar)(const void *elem1, const void *elem2));

unde:

base este adresa de inceput a vectorului;

- nmemb reprezinta numarul de elemente din vector;

- size este dimensiunea in octeti a unui element din vector si

- compar este un pointer catre o functie definita de utilizator care realizeaza comparatia intre doua elemente ale vectorului, elem1 si elem2, returnand o valoare intreaga mai mica decat, egala cu, sau mai     mare decat zero dupa cum elem1 este mai mic, egal cu, sau mai mare decat elem2

O metoda de sortare presupune adaugarea valorilor dintr‑un vector una cate una intr‑un vector nou. Prima valoare este adaugata la inceputul vectorului. Valorile urmatoare sunt adaugate in pozitia corespunzatoare ordinii sale prin deplasarea datelor adaugate deja pentru a face loc valorii care se adauga. Aceasta metoda poarta numele de "sortare prin inserare" ("insertion sort"). Scrieti o functie denumita insort() care realizeaza astfel sortarea si se comporta in acelasi mod precum functia qsort() descrisa in problema anterioara. Functia insort() va avea prototipul:

void insort(void *base, int nmemb, int size,
int(*compar)(const void *elem1, const void *elem2));

Prototipul este similar cu al functiei qsort() realizand sortarea unui vector cu adresa de inceput indicata de base, format din nmemb elemente de tip arbitrar si de dimensiune size si care sunt comparate de functia compar()

Scrieti si programul principal care testeaza functia.

Scrieti o functie care primeste ca argument un sir de caractere si returneaza un pointer catre primul caracter care nu este spatiu din acest sir de caractere.

Precizari:

a.       Se vor considera spatii caracterele space") si 't' ("tab").

b.      Prototipul functiei este:

char *primul_caracter(char *sir);

c.       Scrieti si programul principal care testeaza functia.

Scrieti un program care citeste un text, il desparte in cuvinte si afiseaza cuvintele textului ordonate alfabetic.

Scrieti un program care citeste un text si afiseaza doar ultimele 5 linii ale textului.

Scrieti un program care parcurge lista definita mai jos cu ajutorul pointerului p_lista si afiseaza numarul si numele.

define MAX 4

struct lista data[MAX] = ;

struct lista *p_lista;

Scrieti un program care citeste o expresie matematica simpla formata din doi operanzi numerici si un operator ( ) si determina si afiseaza valoarea expresiei. Un exemplu de rulare a programului va arata astfel:

Introduceti expresia:

1.25 * 4

= 5

Scrieti un program care citeste de la tastatura o matrice de numere reale de dimensiuni maxime 10 x 10, impreuna cu dimensiunile sale efective si determina catul impartirii modulului sumei numerelor negative din matrice la suma numerelor pozitive din matrice. Programul va semnala cazul special al impartirii prin zero. Pentru calculul sumelor se va folosi o functie cu urmatorul prototip:

void suma(float A[][10], int n, int m, float *pos, float *neg);

unde:

A[][10] este matricea de lucru;

n m sunt dimensiunile efective ale matricei;

pos suma numerelor pozitive;

neg suma numerelor negative.

Reluati problema anterioara si scrieti un program care citeste de la tastatura o matrice de numere reale de orice dimensiuni, impreuna cu dimensiunile sale efective si determina catul impartirii modulului sumei numerelor negative din matrice la suma numerelor pozitive din matrice. Programul va semnala cazul special al impartirii prin zero. Pentru calculul sumelor se va folosi o functie cu urmatorul prototip:

void suma(float **A, int n, int m, float *pos, float *neg);

unde:

A    este matricea de lucru;

n m sunt dimensiunile efective ale matricei;

pos suma numerelor pozitive;

neg suma numerelor negative.

Scrieti un program care citeste de la tastatura o matrice de numere reale de dimensiuni maxime 10 x 10, impreuna cu dimensiunile sale efective si determina catul impartirii modulului produsului elementelor de pe diagonala principala a matricei la produsul elementelor de pe diagonala secundara a matricei. Programul va semnala cazul special al impartirii prin zero. Pentru calculul sumelor se va folosi o functie cu urmatorul prototip:

void prod_diag(float A[][10], int n, float *dprin, float *dsec);

unde:

A[][10] este matricea de lucru;

n este dimensiunea efectiva a matricei;

dprin produsul elementelor de pe diagonala principala;

dsec produsul elementelor de pe diagonala secundara.

Scrieti o functie care primeste ca parametru un numar intreg si returneaza un pointer catre numele lunii calendaristice corespunzatoare. Daca numarul nu reprezinta o luna, este mai mic decat 1 sau mai mare decat 12, functia va returna un pointer catre sirul de caractere "nici o luna".

Precizari:

a.    Denumirile lunilor vor fi memorate intr‑o variabila locala statica a functiei definita astfel:

static char *luna[] = ;

b.    Prototipul functiei este:

char *denumire_luna(int numar);

Scrieti si programul principal care verifica functionarea functiei.

Folosind functia din exercitiul anterior scrieti o alta functie care primind un sir de caractere de forma 'zzllaaaa' returneaza data scrisa sub forma 'zi luna an'. De exemplu: functia primeste si returneaza '15 aprilie 2004'. Functia va verifica si corectitudinea datei rejectand date cum ar fi (anul 2001 nu a fost bisect) sau (aprilie nu are 31 de zile). Scrieti si programul principal care verifica functionarea functiei.

Scrieti o functie care citeste cel mult n numere reale de tip float si le plaseaza in memorie incepand de la adresa indicata de pfloat. Functia va returna numarul valorilor citite. Prototipul functiei este:

int citeste_n_nr(int n, float *pfloat);

Scrieti si programul principal care verifica functionarea functiei.





Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 3113
Importanta: rank

Comenteaza documentul:

Te rugam sa te autentifici sau sa iti faci cont pentru a putea comenta

Creaza cont nou

Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved