Structuur van Computerprogramma’s II: Week 7 Dries Harnie, Coen De Roover 28 oktober 2014 Een eenvoudige tracer Bij het verlaten van een functie wordt de destructor van alle lokale variabelen opgeroepen. Je kan deze gebruiken om “tracer” code te schrijven die de control flow van je code volgt. Stel dat je volgende code hebt geschreven: void g() { Tracer t("Functie g"); cout << "world!" << endl; } void f() { Tracer t("Functie f"); cout << "Hello" << endl; g(); } dan zou de output er als volgt kunnen uit zien1 : >>> Functie Hello >>> Functie world! <<< Functie <<< Functie f g g f Implementeer de Tracer klasse. Voeg tevens een eenvoudig timing mechanisme toe dat bij het verlaten van de functie aangeeft hoelang deze geduurd heeft. Je kan hiervoor de clock() functie gebruiken uit <time.h>, deze functie geeft een stijgende waarde in microseconden terug. 1 rood is output op de standaard error stream 1 Dimensies In de wetenschappen werkt men meestal met gedimensioneerde getallen: dit zijn waarden die bestaan uit een getal en een bijhorende eenheid, bvb. 1 meter, 5 kilogram, 15 meter per seconde. Deze eenheid bestaat op zich uit het product van zowel positieve als negatieve machten van basiseenheden. Voor deze oefening beschouwen we meter (m), kilogram (kg) en seconde (s) als basiseenheden. De voorbeeldjes hierboven kan je dus schrijven als 1 ∗ m1 , 5 ∗ kg1 , en 15 ∗ m1 ∗ s−1 . 1. Definieer de Dim klasse die een gedimensioneerd getal voorstelt. Om het product van machten voor te stellen kan je bijvoorbeeld een std::map<std::string, int> gebruiken: dit is een dictionary die std::strings op ints mapt. Voeg een constructor toe voor een getal en een dimensie, en voeg een constructor toe voor niet-gedimensioneerde getallen (waarbij je eenheid gewoon een lege std::map is). Gebruik deze om de variabelen m, kg en s te definiëren, die overeenkomen met één eenheid van elk. Definieer ook variabelen voor de afgeleide eenheden mm (millimeter) en h (uur). 2. Implementeer een correcte overload voor de << operator, zodanig dat je gedimensioneerde getallen kan printen zoals hierboven. Je kan volgende code gebruiken om door de std::map te lopen: std::map<std::string, int>::iterator it; for (it = eenheden.begin(); it != eenheden.end(); ++it) { const std::string & eenheid = it->first; int aantal = it->second; // doe iets met eenheid en aantal } 3. Implementeer de correcte overload voor operator * zodanig dat je gedimensioneerde getallen kan schalen. Doe hetzelfde voor operator /, maar merk op dat 1 s / 1 == 1 s, terwijl 1 / 1 s = 1 s^-1. 4. Implementeer operator *, operator / nu ook voor gedimensioneerde getallen. Bij het vermenigvuldigen moet je de aantallen optellen, bij delen aftrekken. Merk op dat deze operaties kunnen leiden naar een gedimensioneerd getal voor eenheden met macht nul, probeer dit te voorkomen. 5. Implementeer tenslotte de operator + en operator - voor gedimensioneerde getallen. Om te voorkomen dat de gebruiker twee getallen optelt van verschillende dimensies kan je bijvoorbeeld de assert functie gebruiken uit de <cassert> header. Deze sluit het programma af met een foutmelding als haar argument onwaar is. 2
© Copyright 2024 ExpyDoc