POO Cauta

Saptamana 01 / 14 Programare Orientata Obiect

Seminar 1 - Debugger si modelul memoriei

Pornim de la un program cu defecte. Il citim, prezicem ce face, il rulam pas cu pas in debugger si il reparam.

Obiective
  • Creezi, compilezi si rulezi un proiect C++
  • Deosebesti problemele de compilare, link-editare, logica si executie
  • Folosesti breakpoint-uri si executia pas cu pas
  • Inspectezi variabilele si reprezinti stiva
  • Explici valoare, adresa, pointer si referinta
  • Prezici comportamentul unui program simplu inainte sa il rulezi

Plan (90 min)

TimpActivitate
0-5Recapitulare prin intrebari
5-15Predictia rezultatului pentru programul de pornire
15-30Demonstratie: debugger, breakpoint, Locals, Memory
30-60Lucru individual: gasesti si repari defectele
60-75Extindere: cerinta noua
75-85Verificare individuala si intrebari scurte
85-90Trei lucruri pe care le stii acum

Programul de pornire

Codul este in repository, in folderul S01. Nu il rula inca. Citeste-l si noteaza ce crezi ca afiseaza.

S01/S01.cpp
#include<iostream>
using namespace std;

void adunare(int x, int y) {
	int suma = 0;
	suma = x + y;
	cout<< "suma=";
	cout << suma;
}
void adunare2(int x, int y,int &suma) {
	suma = x + y;
	x = 0;
	y = 0;
}
void adunare3(int *x, int *y, int *suma) {
	suma = *x + y;
	*x = 1;
	*y = 1;
}
int main() {
	int v[10];
	for (int i = 0;i < 10;i++)
		v[i] = i;

	for (int i = 0;i < 10;i++)
		cout << v[i] << " ";
	int a, b;
	cout << "a=";
	cin >> a;
	cout << "b=";
	cin >> b;
	int s=0;
	adunare3(&a, &b, &s);
	cout << s<<endl;
	cout << a <<" "<< b;
}

Gaseste defectele

Functia adunare3

Functia adunare3 ar trebui sa puna suma lui *x si *y in variabila spre care arata suma. Programul afiseaza insa 0. De ce?

Pune un breakpoint pe prima linie din adunare3. Urmareste in fereastra Locals valoarea lui suma (adresa) inainte si dupa prima instructiune.

IndiciuUita-te la tipurile din expresia *x + y. Ce tip are y? Ce obtii cand aduni un int cu un int*?
IndiciuInstructiunea suma = ... schimba pointerul local suma, nu valoarea de la adresa lui. Pentru a scrie la adresa ai nevoie de *suma.
Solutie
void adunare3(int* x, int* y, int* suma) {
    *suma = *x + *y;   // scriem la adresa primita
    *x = 1;
    *y = 1;
}

*x + y este aritmetica pe pointeri: rezultatul e o adresa. Atribuirea suma = ... modifica doar copia locala a pointerului, asa ca s din main ramane 0.

Intrebari obligatorii

  1. Ce iti spune compilatorul?
  2. Nu repara inca: de ce este gresit?
  3. Ce valoare prezici pe aceasta linie?
  4. Pune un breakpoint aici. A fost corecta predictia?
  5. Ce se afla pe stiva in acest moment?

Prezice, apoi verifica:

#include <iostream>
using namespace std;
void adunare2(int x, int y, int& suma) { suma = x + y; x = 0; y = 0; }
int main() {
    int a = 2, b = 3, s = 0;
    adunare2(a, b, s);
    cout << a << " " << b << " " << s;
}

#include <iostream>
using namespace std;
void adunare3(int* x, int* y, int* suma) { suma = *x + y; *x = 1; *y = 1; }
int main() {
    int a = 2, b = 3, s = 0;
    adunare3(&a, &b, &s);
    cout << s << endl;
    cout << a << " " << b;
}

Sarcina minima

Media unui vector

Repara adunare3, apoi adauga functia double medie(double* valori, int n), care intoarce media celor n valori. Testeaza cu cel putin doua seturi de date, dintre care unul cu n = 1.

#include <iostream>
using namespace std;

double medie(double* valori, int n) {
  // TODO: calculeaza media
  return 0;
}

int main() {
  double note[] = {7, 9, 10, 6};
  cout << medie(note, 4) << endl;   // asteptat: 8
}
Intrare (stdin)

Deschide in Godbolt

Provocare

Cerinta noua: scrie void minMax(double* valori, int n, double& mn, double& mx), care intoarce prin referinta minimul si maximul. De ce nu poti intoarce doua valori cu return? Ce alta solutie ai avea?

Codul din repository: S01

Varianta in engleza