Høgskolen i Gjøvik Kontinuasjonseksamen FAGNAVN: FAGNUMMER: Grunnleggende datakunnskap, programmering og datastrukturer L 176 A EKSAMENSDATO: 5. januar 1999 KLASSE: 97HINDA / 97HINDB / 97HDMUA TID: 09.00-14.00 FAGLÆRER: Frode Haug ANTALL SIDER UTLEVERT: 8 (inkludert denne forside) TILLATTE HJELPEMIDLER: - Kontroller at alle oppgavearkene er tilstede. Alle trykte og skrevne. - Innføring med penn, evnt. trykkblyant som gir gjennomslag. Pass på at du ikke skriver på mer enn ett innføringsark om gangen (da det blir uleselige gjennomslag om flere ark ligger oppå hverandre når du skriver). - Ved innlevering skilles hvit og gul besvarelse og legges i hvert sitt omslag. Oppgavetekst, kladd og blå kopi beholder kandidaten. - Ikke skriv noe av din besvarelse på oppgavearkene. - Husk kandidatnummer på alle ark.
NB: Oppgave 1a, 1b, 1c og 2 er totalt uavhengige og kan derfor løses separat. Oppgave 1 (35%) a) Hva blir utskriften fra følgende program (litt hjelp: det blir 3 linjer) #include <iostream> #include <cstring> using namespace std; enum Dag { Man, Tirs, Ons, Tors, Fre, Loer, Soen ; char* omform(dag d) { char* dd = new char[5]; switch(d) { case Man: strcpy(dd, "Man"); break; case Tirs: strcpy(dd, "Tirs"); break; case Ons: strcpy(dd, "Ons"); break; case Tors: strcpy(dd, "Tors"); break; case Fre: strcpy(dd, "Fre"); break; case Loer: strcpy(dd, "Lør"); break; case Soen: strcpy(dd, "Søn"); return dd; break; void skriv(char* d1, char* d2, int n) { cout << "\nmellom " << d1 << "dag og " << d2 << "dag" << " er det " << n << " dager."; int main() { char *p1, *p2; int d; Dag dag1 = Dag(int(Tirs)-1), dag2 = Dag(int(Tors)+1); skriv(omform(dag1), omform(dag2), int(dag2-dag1)); dag2 = Loer; p1 = omform(dag1); p2 = omform((dag(d = int(dag2)))); skriv(p1, p2, int(dag2-dag1)); dag1 = Dag(int(dag1) + 4); dag2 = Dag(int(dag2) - 4); skriv(omform(dag2), omform(dag1), int(dag1-dag2)); return 0; 2
b) Hva blir utskriften fra følgende program (litt hjelp: det blir 10 linjer) #include <iostream> using namespace std; void gjor1(char* t1, char* t2, char c = ':', int n = 1) { for (int i = 1; i <= n; i++) cout << t1 << c << t2 << '\t'; void gjor2(char* t1, char* t2) { for (int i = 1; i <= 2; i++) cout << t1 << ':' << t2 << '\t'; void gjor2(char* t1, char c) { for (int i = 1; i <= 3; i++) cout << t1 << c << '\t'; void gjor2(char* t1, char* t2, int n) { for (int i = 1; i <= n; i++) cout << t1 << '-' << t2 << '\t'; int main() { gjor1("10", "23"); gjor1("17", "34", '-', 2); gjor2("tarzan", '!'); gjor1("18", "59", ','); gjor2("jo", "Ove", 4); gjor1("21", "00", 'x', 3); gjor2("class A", "public B"); gjor2("flo", "Jo", 2); gjor1("flo", "Jo"); gjor1("tarzan", "Jane", '&', 1); return 0; 3
c) Hva blir utskriften fra følgende program (litt hjelp: det blir 9 linjer) #include <iostream> using namespace std; class A { public: A() { cout << "A1" << '\t'; void skriv() { cout << "A2" << '\t'; ; class B : public A { public: B() { cout << "B1" << '\t'; B(int b) { cout << "B2" << '\t'; void skriv() { cout << "B3" << '\t'; A::skriv(); ; class C : public A { public: C() { cout << "C1" << '\t'; C(int c) { cout << "C2" << '\t'; void skriv() { cout << "C3" << '\t'; ; class D : public B { public: D() { cout << "D1" << '\t'; D(int d) : B(d) { cout << "D2" << '\t'; void skriv() { cout << "D3" << '\t'; ; int main() { B b1; D d1; D d2(4); C c1(7); c1.skriv(); d2.skriv(); b1.skriv(); A* ap = &d1; ap->skriv(); D* dp = &d1; dp->skriv(); return 0; 4
Oppgave 2 (65%) NB: Les hele teksten for denne oppgaven nøye, før du begynner å besvare noe som helst. Studer spesielt vedlegget (klasser, global variabel, hovedprogram og les-funksjoner), slik at du får mer klarhet i hvordan det ferdige programmet skal fungere. Innledning Oppgaven går i korthet ut på å lage et dataprogram som holder orden på hvilke personer som til enhver tid har hvilke blader av de som sirkuleres rundt blant de ansatte. Når et blad sendes videre mellom to personer, så leveres det ikke direkte til mottakeren, men til sekretæren. Hun/han foretar en oppdatering vha. det programmet du her skal lage (kommandoen R ). Deretter legger sekretæren bladet i mottakerens posthylle eller på et egnet sted i det fysiske arkivet. Det er kun sekretæren som bruker det programmet du her skal lage! Datastrukturen Datastrukturen består av en liste av alle de personene som er med på sirkulasjonsordningen. Om hver person er det kun lagret vedkommendes navn. Ingen duplikater finnes, dvs. ingen personer skal ha samme navn. Listen er sortert på personens navn. Hver person har en egen (side)liste med de bladene som vedkommende for øyeblikket har til lesning. Disse (side)listene er organisert etter FIFO-prinsippet. Om hvert blad er det kun lagret dets navn/tittel (se under Annet (klargjørende?) ). Oppgaven a) Tegn opp datastrukturen. Dvs. tegn opp eksempler på lister, objekter og datamedlemmer. Gjør alt dette detaljert og pent! b) Skriv innmaten til funksjonen void ny_person() Først spørres det etter den nye personens navn (vha. funksjonen les( ) ). Om det allerede finnes en person med dette navnet, så kommer det en melding om dette. I motsatt fall så opprettes det et nytt Person-objekt og dette legges så inn i datastrukturen. c) Skriv innmaten til funksjonen void slett_person() Her spørres det også etter navnet til den personen som skal slettes. Om vedkommende ikke finnes, så kommer en melding om dette. Ellers så fjernes vedkommende fra lista med personer. Før vedkommende slettes helt fra hukommelsen, så blir de bladene som vedkommende har hatt til lesning lagt direkte i arkivet. Dette gjøres for vårt programs del ved å skrive bladets navn/tittel på en egen linje bakerst på filen ARKIVET.DTA vha. append. (Pluss at sekretæren legger bladet på et fysisk sted i arkivet.) Dvs. bladene blir ikke sirkulert videre, men arkivert. (Dette siste er selvsagt noe urealistisk, men for å forenkle programmeringen noe gjør vi det slik her.) 5
d) Skriv innmaten til funksjonen void nytt_blad() Et nytt blad er kommet i posten. Programmet spør om navnet på den første som skal ha dette bladet på sirkulasjon. Om vedkommende ikke finnes, så kommer en melding om dette. I motsatt fall så spørres det så etter bladets navn/tittel, et nytt Blad-objekt opprettes og bladet legges inn i lånerens (side)liste av blader. NB: Husk at de lånte bladene legges inn i en FIFO-liste hos vedkommende person. Rent konkret vil dette si at alle de ansatte har en egen bunke med blader til lesning. Nye blader legges alltid nederst i denne bunken. Når vedkommende ønsker å lese et blad, så tar hun/han alltid det øverste bladet, leser dette og leverer det deretter til sekretæren. Dermed vil rekkefølgen på bladene som kommer fra en og samme person alltid stemme med rekkefølgen i FIFO-listen i programmet. (Alt dette med FIFO-liste er også selvsagt helt urealistisk, men for denne oppgavens del så antar vi at dette er gjennomførbart.) e) Skriv innmaten til funksjonen void returner_blad() Programmet spør om navnet til den som returnerer bladet. Om vedkommende ikke finnes, så kommer en melding om dette. Ellers så hentes det første bladet i vedkommendes FIFO-liste. Om ingen blad finnes, så kommer en melding. I motsatt fall så spørres det etter navnet til neste på sirkulasjonslisten. (Hvordan sekretæren vet hvem neste er, trenger du i denne oppgaven ikke å bekymre deg med.) Om vedkommende ikke finnes, eller om navnet er blankt, så arkiveres bladet (skrives bakerst på filen ARKIVET.DTA, se oppgave 2c), og slettes deretter fra hukommelsen. Om mottakeren finnes, så legges bladet inn i vedkommendes FIFO-liste av blader. Annet (klargjørende?): Du skal bruke LISTTOOL ved løsning av denne oppgaven. Du må helt sikkert lage mer innmat til de to klassene. F.eks. slik som: datamedlemmer, constructor, destructor, display, arkivere/skrive til fil, Bruk void les(char* t1, char* t2) alle steder det er naturlig. I forbindelse med et blads navn/tittel, så oppgis også dets nummer og årgang som en del av dette. F.eks: Computerworld 36/98, PC World 8/98 eller Byte 11/98. Vi forutsetter at det er plass til alle personene og deres blader i datamaskinens primærhukommelse. Vi forutsetter dessuten at strømbrudd aldri skjer, siden vi ikke lagrer noe av dataene om personer og deres blader på fil (unntatt det som er arkivert). Gjør dine egne forutsetninger og presiseringer av oppgaven, dersom du skulle finne dette nødvendig. Gjør i så fall klart rede for disse i starten av din besvarelse av oppgaven. Godt nytt år og lykke til med denne dagen! FrodeH 6
Vedlegg (halvferdig programkode): #include <iostream> #include <fstream> #include <cctype> #include "listtool.h" using namespace std; const int STRLEN = 80; // cout, cin // ofstream // toupper // Ulike "verktøy" fra "Listtool". // CONST: // KLASSER: class Blad : public Text_element { // Klassen "Blad". // Her må du lage litt mer innmat... ; class Person : public Text_element { // Klassen "Person". // Her må du lage en god del mer innmat... ; // DEKLARASJON AV FUNKSJONER: void skriv_meny(); char les(); void les(char* t1, char* t2); void ny_person(); void slett_person(); void nytt_blad(); void returner_blad(); List* Personer; // GLOBALE VARIABLE: int main() { // HOVEDPROGRAMMET: char kommando; Personer = new List(Sorted); skriv_meny(); kommando = les(); while (kommando!= 'Q') { switch(kommando) { case 'P': ny_person(); break; // Oppgave 2b case 'S': slett_person(); break; // Oppgave 2c case 'B': nytt_blad(); break; // Oppgave 2d case 'R': returner_blad(); break; // Oppgave 2e case 'L': Personer->display_list(); break; default: skriv_meny(); kommando = les(); return 0; break; 7
// DEFINISJON AV FUNKSJONER: void skriv_meny() { cout << "Følgende kommandoer er lovlig:"; cout << "\n\tp - Ny person"; cout << "\n\ts - person som Slutter"; cout << "\n\tb - nytt Blad kommer inn"; cout << "\n\tr - Returner/arkiver et blad fra en person (til en annen)"; cout << "\n\tl - Listen av personer (og deres blader) skrives"; cout << "\n\tq - Quit / avslutt"; char les() { // Leser og returnerer ETT upcaset tegn. char kommando; cout << "\n\nkommando: "; cin >> kommando; cin.ignore(); return (toupper(kommando)); // Skriver en ledetekst. Returnerer tekstlig svar. void les(char* t1, char* t2) { cout << "\n\t" << t1 << ": "; cin.getline(t2, STRLEN); void ny_person() { // Legger (om mulig) inn en ny person. // Oppgave 2b: Skriv innmaten void slett_person() { // Sletter (om mulig) en person fra lista. // Oppgave 2c: Skriv innmaten void nytt_blad() { // Nytt blad er kommet, lånes umiddelbart av en person. // Oppgave 2d: Skriv innmaten // Retur av et blad. Det lånes ut videre eller arkiveres. void returner_blad() { // Oppgave 2e: Skriv innmaten 8