Sunteți pe pagina 1din 9

10. Pointeri i tablouri. Transferul de argumente ctre main().

Pointeri spre funcii. (Pointers and arrays. Transfer of arguments to


main(). Pointers to functions.)

1. Obiective:
nelegerea legturii dintre pointeri i tablouri.
nelegerea modului n care se transmit parametrii din linia de comand.
Utilizarea pointerilor spre funcii
Scrierea i rularea de programe care exploateaz aceste faciliti.
1. Objectives:
Understanding the relation between pointers and arrays.
Understanding the way the command line arguments are transmitted.
Pointers to functions usage
Writing and running programs that have these functionalities.

2. Breviar teoretic
Un nume de tablou (fr index) este un pointer constant, de tipul elementelor tabloului, avnd
ca i valoare adresa primului element din tablou.
Consecine:
- Adresa tabloului (data de numele lui) poate fi atribuita unui alt pointer (ne-constant),
pointer ce poate fi utilizat pentru accesul la elementele tabloului;
- un pointer se poate indexa ca i cnd ar fi un tablou, dar dac nu pointeaz pe un tablou
rezultatul este imprevizibil;
- dac p pointeaz pe un tablou compilatorul C/C++ genereaz cod executabil mai scurt
pentru *(p+i) dect pentru p[i];
- numele unui tablou este un pointer de tip constant, deci nu se poate modifica, dar poate fi
folosit ca i pointer aritmetic (adunnd la el o variabil cu rol de index. Vezi Exemplul 1).
Tablouri de pointeri
Tablourile de pointeri se definesc similar cu tablourile altor tipuri predefinite i se folosesc
mai ales la crearea de tabele de pointeri ctre iruri de caractere care pot fi selectate funcie de
anumite valori ntregi fr semn, cu rol de indice (vezi exemplul din Cursul 8):

char *p[] = { "Out of range", "Disk full", "Paper out" };


Tablourile de pointeri pot fi accesate i cu pointeri dubli.
Pointerii si modificatorul const
Exist pointeri ctre constante i pointeri constani, care nu pot fi modificai.
- pointeri ctre constante

const char *str1 = "pointer catre constanta";


str1[0] = 'P';
// incorect: sir declarat imutabil
str1 = "ptr la const"; //OK: pointerul nu e declarat cst
-

pointeri constani

char *const str2 = "pointer constant ";


str2 = "ptr const";// incorect: ptr. e declarat cst.
L10 pointeri2

str2[0] = 'P';
-

// OK: sirul nu e declarat cst.

pointeri constani ctre constante

const char *const str3 = "pointer constant la constanta";


str3 = "ptr const la const";
// incorect
str3[0] = 'C';
// incorect
Indirectarea multipl
Cnd un pointer pointeaz pe alt pointer avem un proces numit indirectare dubl (multipl).
El arat asfel: Pointer ctre pointer -----> Pointer ----> Obiect. Cnd un pointer
pointeaz alt pointer, primul pointer conine adresa celui de-al doilea pointer, care pointeaz
locaia care conine obiectul. Declararea se face utiliznd un asterisc suplimentar n faa
numelui pointerului.
Pointeri spre funcii
La o funcie, ca i la o structur sau un tablou, sistemul de operare i aloc o adres de
memorie fizic. Un pointer ctre o funcie va conine aceast adres.
Declararea unui pointer spre o funcie trebuie s precizeze tipul returnat de funcie i numrul,
respectiv tipul parametrilor formali:

tip_rezultat (*pf) (lista_param_formali);


Regul practic: declaraia se face ca i cum am scrie un prototip de funcie, numele funciei
fiind substituit de construcia (*nume_pointer_la_funcie).
Numele unei funcii este sinonim cu adresa de nceput a codului su executabil n memorie,
astfel c:
pf = nume_functie; este sinonim cu pf = &nume_functie;
Apelul unei funcii prin intermediul unui pointer se face cu construcia:

(*pf) (lista_param_actuali);
iar dac funcia returneaz o valoare care se poate atribui unei variabile (funcie cu tip), atunci
apelul poate fi:

var = (*pf) (lista_param_actuali);


Standardul C++ permite simplificarea apelului folosind pointeri la functii astfel:

var = pf (lista_param_actuali);
Transferul de argumente ctre funcia main()
La lansarea n execuie multe aplicaii permit specificarea unor argumente n linia de
comand.
Programele scrise n limbajul C/C++ permit introducerea de argumente n linia de comand,
prin definirea unor parametri pentru funcia main() :

void main([ int argc, char *argv[] [ ,char *env[] ]]) { ... }
-

argc, argument count,conine numrul argumentelor ( >= 1)


argv, argument vector este un tablou de pointeri ctre iruri de caractere, unde:
argv[0] pointeaz pe numele i calea programului care se lanseaz n execuie
argv[1] pointeaz pe primul argument din linia de comand, .a.m.d.
env, environment variables este un tablou de pointeri ctre iruri de caractere care
reprezint o list de parametri ai SO (tipul prompt-erului...); ultimul pointer are valoarea
NULL, marcnd sfritul listei de parametri.

L10 pointeri2

Caracteristici:
- ntre argumente se consider ca i separator caracterul spaiu i tab, iar dac un argument
va conine spaiu (tab), acel argument trebuie ncadrat ntre ghilimele.
- Numele argc, argv, env nu sunt impuse, utilizatorul poate folosi i alte nume.
- Pentru c aceste argumente se primesc sub forma de iruri de caractere, aceste iruri pot fi
convertite spre un format intern de reprezentare n memorie cu funciile atoi(), atof(),
atol().
- Indiferent de modul de utilizare a funciei main() de ctre utilizator, cei 3 parametri sunt
alocai pe stiv.
Testarea programelor ce transfer argumente din linia de comand poate face n dou moduri:
- din sistemul de operare, dup ce s-a creat fiierul executabil, lansnd programul folosind
opiunea Start->Run i apoi selectnd fiierul executabil aferent programului, dup care
se tasteaz argumentele, separate prin spaiu; pentru fiecare lansare n execuie trebuie
repetat aceast operaie.
- din mediul de programare, stabilind n setrile proiectului curent argumentele ce vor
ajunge la funcia main(); setrile respective i modul n care se ajunge la acestea depinde
de mediul de programare cu care se lucreaz; odat stabilite, aceste setri sunt valabile
pentru toate programele ce se testeaz i pentru orice lansare n execuie. (vezi setri
Visual Studio)

3. Exemple
Exemplul 1: program pentru determinarea celui mai mic element dintr-un tablou
unidimensional.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <conio.h>
#define DIM 20
int DetMin(int *, int);//prototip ce ret min din tablou
void main(void){
int i, dim, min;
int x[DIM];
printf("\nIntroduceti dimensiunea tabloului unidimensional: ");
scanf("%d", &dim);
if(dim<=0 || dim > DIM)
{
printf("\n Dimensiune gresita !\n");_getch();
return;
}
printf("\n Introduceti elementele tabloului unidimensional:\n");
for(i=0; i<dim; i++)
{
printf("\tx[%d] = ", i);
scanf("%d", (x+i));
}
min = DetMin(x, dim);
printf("\n Cel mai mic element din tabloul unidimensional este: %d\n", min);

L10 pointeri2

_getch() ;
}

int DetMin(int *x, int n){


int i, min;
min = *x++;
for(i=1; i<n; i++)
{
if(*x < min)
min = *x;
x++;
}
return min;
}
Exemplul 2: program ce utilizeaz pointeri spre funcii.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <conio.h>
int get_result(int, int, int (*)(int, int));
int max(int, int);
int min(int, int);
void main(void)
{
int result;
result = get_result(1, 2, max);
printf("Max dintre 1 si 2 este: %d\n", result);
result = get_result(1, 2, min);
printf("Min dintre 1 si 2 este: %d\n", result);
_getch();
}
int get_result(int a, int b, int (*compare)(int, int))
{
return(compare(a, b)); // apel functie prin pointer
}

int max(int a, int b)


{
printf("Apel functia max:\n");
return((a > b) ? a: b);
}
int min(int a, int b)
{
printf("Apel functia min:\n");

L10 pointeri2

return((a < b) ? a: b);


}
Exemplul 3: program care preia de la consol mai multe numere ntregi ca i valori de
rezistene i calculeaz rezistena echivalent gruprii serie sau paralel.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#define DIM 10
float calcul(int*, int, float (*)(int*, int));
float serie(int *, int);
float paralel(int *, int);

void main(void)
{
int i, n, tab[DIM];
float rez;
char grp;
printf("\nIntroduceti numarul de rezistente <=10 : ");
scanf("%d", &n);
if(n==0) return;
printf("\nIntroduceti %d valori de rezistente :\n", n);
for(i=0; i<n; i++)
{
printf("Rezistenta %d :", i+1);
scanf("%d", &tab[i]);//(tab+i)
}
printf("\nGrupare serie/paralel (s/p) ? ");
fflush(stdin);
scanf("%c", &grp);//grp=_getch()
switch(toupper(grp))
{
case 'S':
case 'P':
default:

rez = calcul(tab, n, serie);


break;
rez = calcul(tab, n, paralel);
break;
printf("\n Operatie invalida !");
return;

}//end switch
printf("\n Rezistenta echivalenta este: %f\n", rez);
_getch();
}//end main
float calcul(int *tab, int n, float (*pf)(int *, int))
{
// alte prelucrari

L10 pointeri2

return(pf(tab, n));
}//end calcul
float serie(int *tab, int n)
{
float suma = 0.;
while(n)
suma += tab[--n];
return(suma);
}//end serie
float paralel(int *tab, int n)
{
float suma = 0.;
while(n)
suma += 1./tab[--n];
return(1./suma);
}//end parelel
Exemplul 4: program care preia din linia de comand numere ntregi i afieaz suma
acestora.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void main (int argc, char *argv[])
{
int i, suma=0, n;
if (argc == 1) {
printf("\n\n\tNu ati introdus numerele de adunat !");
_getch();
exit(1);
}//end if
else
{
for(i=1; i<argc; i++)
{
n = atoi(argv[i]);
suma += n;
}//end for
printf("\nSuma argumentelor din linia de comanda este : %d\n", suma);
_getch();
}//end else
}//end main
4. Intrebri:
Care sunt operatorii specifici pentru pointeri ?
Care sunt operaiile permise cu pointerii ?
Care este diferena ntre un pointer constant i un pointer ctre o constant?

L10 pointeri2

Ce este un pointer ctre o funcie ?


Cum se poate face apelul unei funcii folosind pointeri ?
Ce reprezint parametri din linia de comand ?
Cum pot fi accesai parametri din linia de comand ntr-un program C/C++?

5. Teme:
1. Rezolvai problemele din laboratorul de aplicaii cu tablouri (laboratorul 8,
problemele 1-12) folosind pointeri.
2. Se consider doi parametri ntregi i ali doi flotani din linia de comand. S se
afieze suma i produsul lor.
3. Scriei o aplicaie care citete de la tastatur un ir de caractere cu lungimea mai mare
dect 7. Folosii un pointer pt. a accesa i afia caracterele de pe poziiile 1, 3, 5 i 7.
4. Citii de la tastatur elementele a 2 matrici de valori ntregi. Scriei o funcie care
primete ca parametri pointerii la cele 2 matrici i returneaz un pointer la matricea
sum. Rezultatul nsumrii matricelor va fi afiat n funcia main. Afiai elementele
de pe diagoanala secundar a matricii sum, folosind acelai pointer.
5. Definii un tablou de pointeri ctre iruri de caractere. Fiecare locaie a tabloului
conine adrese ctre unul din urmatoarele iruri de caractere:
- "valoare prea mic"
- "valoare prea mare"
- "valoare corect"
Aplicaia genereaz un numr aleator ntre 1 i 100 i apoi citete n mod repetat
intrarea de la tastatur pn cnd utilizatorul introduce valoarea corect. Folosii
mesajele definite pentru a informa utilizatorul, la fiecare pas, despre relaia existent
ntre numrul generat i ultima valoare citit.
6. Scriei un program n care s definii un tablou de pointeri spre iruri de caractere, pe
care s-l iniializai cu diferite mesaje. Afiai mesajele.
7. S se scrie un program care preia din linia de comand iruri de caractere i afieaz
irul rezultat din concatenarea acestora.
8. S se scrie un program care inverseaz irul de caractere citit din linia de comand.
9. Scriei un program care citete de la tastatur elementele de tip float ale unui tablou
unidimensional, elemente ce reprezint mediile unei grupe de studeni. S se scrie o
funcie care determin numrul studenilor cu media >= 8. Afiai rezultatul n main.
(lucrati cu pointeri, fr variabile globale).
10. Scriei un program C/C++ n care se citesc de la tastatur elementele de tip ntreg ale
unui tablou unidimensional a, utiliznd o funcie. Scriei o funcie care completeaz
un alt tablou unidimensional b, fiecare element al acestuia fiind obinut prin scderea
mediei aritmetice a elementelor din a din elementul corespunztor din a. Scriei o
funcie care permite afiarea unui tablou unidimensional i afiai tablourile
unidimensionale a i b. (utiliznd pointeri, fr variabile globale).
11. Scriei un program n care se citesc de la tastatur elementele de tip ntreg ale unei
matrici ptratice, utiliznd o funcie. Scriei o funcie care determin numrul de
elemente negative de deasupra diagonalei secundare. Afisai rezultatul n main() (fr
variabile globale).
12. Scriei un program n care se citesc de la tastatur elementele de tip ntreg ale unei
matrici ptratice, utiliznd o funcie. Scriei o funcie care interschimb dou linii ale
matricii. Afiai cu o funcie matricea iniial i cea obinut. Dimensiunea matricii i
numerele ce identific liniile care vor fi interschimbate se citesc de la tastatur, n
funcia main. (fr variabile globale).
13. Considernd algoritmul care preia numerele de la tastatur direct ordonate cresctor
ntr-un tablou unidimensional, folosii mecanismul de acces la elemente prin poinetri.
Scriei o aplicaie C/C++ care implementeaz o funcie care are ca parametri formali

L10 pointeri2

un pointer la un tablou unidimensional de tip float i dimensiunea. (void dir_sort(float


*, int n);)
14. Scriei algoritmul care interclaseaz dou tablouri unidimensionale de tip ntreg.
Folosii pointeri.
15. Ordonai cresctor un tablou unidimensional de numere ntregi folosind funcia de
bibliotec qsort() din stdlib.h. Folosii acelai algoritm pentru numere de tip float i
ordonai descresctor.
5. Homework
1. Resolve the problems referring to arrays (from the previous lab number 8, problems
1-12), using pointers.
2. Considering two integer and two float parameters from the command line, display the
sum and the product of these parameters.
3. Write a C/C++ application that reads from the keyboard an array of characters that
has more than 7 elements. Use a pointer for displaying the characters that have the
indexes 1, 3, 5 and 7.
4. Write a C/C++ application that reads from the keyboard the elements of 2 integer
matrices. Write a function that receives as parameters the pointers to the matrices and
returns the pointer to the sum matrix. The result is to be displayed in function main.
Display the elements from the second diagonal of the sum matrix using the returned
pointer.
5. Define an array of character pointers. Each location will store one of the following
messages:
- "value too small"
- "value too big"
- "correct value"
The application generates a random number between 0 and 100 and then reads
repeatedly the keyboard until the user enters the right number. Use the previously defines
messages for informing the client about the relation between the auto-generated number
and the last value entered from the keyboard.
6. Write a C/C++ application that defines an array of pointers to character strings and
initialize them with different messages. Display the messages.
7. Write a C/C++ program that reads some character arrays from the command line and
displays the resulting concatenated string.
8. Write a C/C++ program that inverts a string of characters read from the command
line.
9. Write a C/C++ program that reads from the keyboard the float type elements of a onedimensional array. The values represent the average marks of a group of students.
Write a function that determines the number of students having the average mark >=
8. Display the result in the main function. (use pointers, avoid global variables).
10. Write a C/C++ program that implements a function for reading from the keyboard
some integer values. The function stores the values in a one-dimensional array named
A. Write another function that fills a different one-dimensional array B, each element
being obtained by subtracting the mean value of the initial values from the
corresponding element located in the one-dimensional array A. Write a function that
displays a one-dimensional array and use it for A and B one-dimensional array. (use
pointers, dont use global variables)
11. Write a C/C++ program that defines a function for reading from the keyboard the
integer type values that form a [n x n] matrix. Write a function that determines the
number of negative elements that are located above the secondary diagonal. Display
the result in the main function (dont use global variables).
12. Write a C/C++ program that defines a function for reading from the keyboard the
integer type values that form a [n x n] matrix. Write a function that interchanges two
lines of the matrix. Use another function for displaying the initial and the processed

L10 pointeri2

matrices. Read from the keyboard (in the main function) the dimension (n) of the
matrix and the indexes that indicate the rows to be switched (do not use global
variables).
13. Considering the algorithm that directly introduces the numbers from KB in a sorted
mode in a one-dimensional array, use the mechanism to access by pointers the
elements. Develop a C/C++ application considering a function having as formal
parameters a pointer to a one-dimensional array of float type and the dimension. (void
dir_sort(float *, int n);)
14. Develop the algorithm able to interclass two one-dimensional arrays of int type. Use
pointers.
15. Order in increasing mode a one-dimensional array of integer type using qsort() from
stdlib.h. Use the same algorithm for float numbers and a decreasing order.

L10 pointeri2

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