Uitwerking tentamen Programmeermethoden 28 maart 2013 OPGAVE 1 a. bool uniek (int A[ ], int i, int n) { int j; for ( j = 0; j < n; j++ ) if ( i != j && A[i] == A[j] ) return false; return true; }//uniek b. bool som (int A[ ], int X, int & i, int & j, int n) { for ( i = 0; i < n; i++ ) for ( j = i+1; j < n; j++ ) if ( X == A[i] + A[j] ) return true; i = -1; j = -1; return false; }//som c. void sorteer (int A[ ], int n) { int i, ronde, temp; for ( ronde = 1; ronde < n; ronde++ ) for ( i = 0; i < n-ronde; i++ ) if ( A[i] < A[i+1] ) { temp = A[i]; A[i] = A[i+1]; A[i+1] = temp; } }//sorteer d. bool uniek2 (int A[ ], int i, int n) { if ( ( i > 0 && A[i-1] == A[i] ) || ( i+1 < n && A[i] == A[i+1] ) ) return false; return true; }//uniek2 OPGAVE 2 a. Globale variabelen gelden in het gehele programma, en worden helemaal bovenin aangemaakt. Locale variabelen gelden (tijdelijk) alleen in de functie waarin ze aangemaakt zijn. Variabelen kunnen call by value en call by reference worden meegegeven aan een functie. Bij call by value gaat alleen de waarde van de parameter naar de functie, alwaar een locale variabele deze waarde opvangt, en er met deze locale variabele wordt verder gerekend. De oorspronkelijk variabele behoudt zijn waarde. Bij call by reference (&) gaat als het ware de variabele zelf naar de functie, en kan dan ook blijvend veranderd worden. Eigenlijk wordt het adres (de reference) doorgegeven. Formeel: in functieheading, bijvoorbeeld x, y in int f (int x, bool y) { Actueel: bij aanroep, bijvoorbeeld r en y in z = f (r,y); b. B2,3,7 B13,3,8 F1,4,24 24 1,4,8 c. B2,3,7 B13,2,8 F1,2,23 23 1,2,8 B2,3,7 B13,3,8 F1,3,24 24 1,3,8 d. Fout. Op de plek van eerste parameter van plus moet een call by value parameter staan in verband met aanroep ben (ben (x,y),y); ben (x,y) is geen l-value. e. Het is geen recursie: de functie roept zichzelf niet (direct of indirect) aan. OPGAVE 3 a. int rij (in G[ ][n], int i) { int waarde = 0, j; for ( j = 0; j < n; j++ ) waarde = 10*waarde + G[i][j]; return waarde; }//rij b. void telop (int G[ ][n], int i, int j, int k) { int waarde = rij (G,i) + rij (G,j), ell; for ( ell = n-1; ell >= 0; ell-- ) { G[k][ell] = waarde % 10; waarde = waarde / 10; }//for }//telop c. int groot (int G[ ][n]) { int i, gr = 0; for ( i = 1; i < m; i++ ) if ( rij (G,i) >= rij (G,gr) ) // niet zo efficient gr = i; return gr; }//groot d. void doe (int G[ ][n]) { int i, j, k; for ( i = 0; i < m; i++ ) { k = 0; while ( G[i][k] == 0 ) k++; // dit stopt omdat getal >= 1 for ( j = 0; j < n-k; j++ ) G[i][j] = G[i][k+j]; for ( j = n-k; j < n; j++ ) G[i][j] = 10; }//for }//doe OPGAVE 4 a. void voegtoe (persoon* & begin, int nr, int lt) { persoon* nieuw = new persoon; nieuw->rechts = begin; if ( nr != -1 ) { nieuw->nummer = new int; *(nieuw->nummer) = nr; } else nieuw->nummer = NULL; nieuw->leeftijd = lt; begin = nieuw; }//voegtoe b. void verwijder (persoon* & begin) { persoon* weg = begin; if ( begin != NULL ) { begin = begin->rechts; if ( weg->nummer != NULL ) delete weg->nummer; delete weg; }//if }//verwijder c. void ruilom (persoon* begin) { int* temp; if ( begin != NULL && begin->rechts != NULL ) { temp = begin->nummer; begin->nummer = begin->rechts->nummer; begin->rechts->nummer = temp; }//if }//ruilom d. Bij a en b moet er een & bij, want de beginpointer kan gaan veranderen. Bij c hoeft het niet, de beginpointer verandert niet. Het mag hier wel. (Het maakt bij c niet uit of je pointers of integers verwisselt.) e. void indewar (persoon* begin) { persoon* p = begin; persoon* q = NULL; while ( p != NULL ) { if ( p->leeftijd != -1 ) { if ( q != NULL ) q->leeftijd = p->leeftijd; q = p; }//if p = p->rechts; }//while }//indewar