Uitwerking tentamen Programmeermethoden woensdag 4 januari 2012 OPGAVE 1 a. bool gesorteerd (int A[ ], int n) { int i; for ( i = 0; i < n-1; i++ ) if ( A[i] > A[i+1] ) return false; return true; }//gesorteerd b. void draai (int A[ ], int i, int j) { int temp; while ( i < j ) { temp = A[i]; A[i] = A[j]; A[j] = temp; i++; j--; }//while }//draai c. bool een (int A[ ], int n) { int i, j; for ( i = 0; i < n-1; i++ ) for ( j = i+1; j < n; j++ ) { draai (A,i,j); if ( gesorteerd (A,n) ) { draai (A,i,j); return true; }//if draai (A,i,j); }//for return false; }//een d. void sorteer (int A[ ], int n) { int i = 1, j; bool doorgaan = true; while ( doorgaan) { doorgaan = false; for ( j = 0; j < n-i; j++ ) if ( A[j] > A[j+1] ) { draai (A,j,j+1); doorgaan = true; }//if i++; }//for }//sorteer e. Tussen n-1 en (n-1)+(n-2)+...+3+2+1 = n(n-1)/2 vergelijkingen. 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: x, y in int f (int x, bool y) { ... Actueel: bij aanroep, bijvoorbeeld 7 en y in z = f (7,y); b. Som 3,3 Product 3,12 Product 3,48 3,3,0 (op 7 regels) c. Som 2,3 Product 0,9 0,0,9 (op 5 regels) d. Als ( i < b ) op de plaats staat van een call by reference parameter (met &) mag het niet: daar moet een "l-value" staan. Bij call by value mag het wel. e. De bovengrens van de for-loop wordt dan groter en groter, er ontstaat een oneindige loop, die misschien gebroken wordt doordat a over INT_MAX heen schiet en dan negatief wordt. OPGAVE 3 a. void inverteer (bool P[ ][n]) { int i, j; for ( i = 0; i < m; i++ ) for ( j = 0; j < n; j++ ) P[i][j] = ! P[i][j]; }//inverteer b. int hoogste (bool P[ ][n], int & j) { int gr = -1, i, k, tel; for ( k = 0; k < n; k++ ) { tel = 0; for ( i = 0; i < m; i++ ) if ( P[i][k] ) tel++; if ( tel >= gr ) { gr = tel; j = k; }//if }//for return static_cast( 100 * static_cast(gr) / m + 0.5 ); }//hoogste c. void doerij (bool P[ ][n], int i) { int j, tel = 0; bool eerste = true; for ( j = 0; j < n; j++ ) { if ( P[i][j] ) tel++; else if ( tel > 0 ) { if ( eerste ) { cout << tel; eerste = false; }//if else cout << "," << tel; tel = 0; }//if }//for if ( tel > 0 ) if ( eerste ) cout << tel; else cout << "," << tel; }//doerij OPGAVE 4 a. void verwijder (jaar* & begin) { jaar* weg = begin; if ( begin != NULL && begin->jaartal != 2012 ) { begin = begin->volg; delete weg; }//if }//verwijder b. void verwissel (jaar* begin) { int temp; if ( begin != NULL && begin->volg != NULL && begin->jaartal % 2 == 1 && begin->volg->jaartal % 2 == 0 ) { temp = begin->jaartal; begin->jaartal = begin->volg->jaartal; begin->volg->jaartal = temp; begin->volg2 = begin->volg->volg; begin->volg->volg2 = begin->volg->volg; }//if }//verwissel c. void voegtoe (jaar* & begin, int jr) { jaar* nieuw = new jaar; nieuw->jaartal = jr; nieuw->volg = begin; if ( jr % 2 == 0 ) { if ( begin != NULL ) nieuw->volg2 = begin->volg; else nieuw->volg2 = NULL: }//if else nieuw->volg2 = begin; begin = nieuw; }//voegtoe d. Bij a en c moet er een & bij (de ingangspointer gaat veranderen (bij a niet altijd, overigens)). Bij b hoeft het niet (de pointer begin verandert niet). e. int laatste (jaar* begin) { jaar* p = begin; jaar* q; if ( begin == NULL ) return -1; while ( p->volg2 != NULL ) p = p->volg2; q = p->volg; // 1x if ( q != NULL ) return q->jaartal; else return p->jaartal; }//laatste