MCMASTER UNIVERSITY
HAMILTON, ONTARIO, CANADA
DEPARTMENT OF ELECTRICAL AND COMPUTER ENGINEERING
COE2SH4 - PRINCIPLES OF PROGRAMMING
1ST
MIDTERM EXAMINATION (1.5 HOURS) FALL, 2007
Instructions:
1. Write your name, student ID, section number and signature in the spaces indicated below.
2. The examination booklet has 8 pages in total. 3. All answers should be written in pen.
4. This is a closed book examination. No reference notes and books are allowed. No calculators are allowed.
5. Return the whole examination booklet after the test.
N a m e ( p l e a s e p r i n t ) : _ _ _ _ _ _ _ _ _ _ _ _ _
S t u d e n t I D : _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
T u t o r i a l S e c t i o n : _ _ _ _ _ _ _ _ _ _ _ _ _
S i g n a t u r e : _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
I Fill in the blanks Write the output
Correct the errors A1)-A3), B1)-B4), C
40 points
II Programming question D1)
20 points
III Programming question D2)
20 points
IV Programming question D3)
20 points
Total 100
F
ILL IN
T
HE BLANKS
A1) – A3) Evaluate the following expressions, and write the values in the blanks.
A1)(2 points) int a=4, b=6, c; c = ( (a/b) && ( b++ ));
c = 0 b = 6
A2)(2 points)
int n=(int)98765.3%100/10;
n = 6
A3)(7 points) int a[ ] = {3,6,9,12,15,18,21,24}; int *p = a;
int **pp = &p;
a[3]/5= 2 p[2]= 9
*(a+4)= 15 *(*pp+6)= 21
(p+2)[3]= 18
W
RITE
T
HE
O
UTPUT
B1) (6 points) Read the following C program and write the output on the screen:
#include <stdio.h>
{
int i = 1; while( i < 7 ) {
i = function1(i); }
printf("%d\n", i); return 0;
}
int function1( int a ) {
static int b = 1; b = b + 2;
return a + b; }
ANSWER: 9
B2) (6 points) Read the following C program and write the output on the screen:
#include <stdio.h>
int function2( int a, int *bp ); int main( )
{
int m = 10, n = 20, k = 30; k = function2(m, &n);
printf( “%d\n%d\n%d\n”, m,n,k ); return 0;
}
int function2( int a, int *bp ) {
a *= 5; *bp -=3; return a; }
B3) (6 points) Read the following C program and write the output on the screen:
#include <stdio.h>
char *mystery(char *s );
int main() {
char *s=mystery(”Abracadabra”); printf(“%c,%c,”, s[4], (s-3)[1]); printf(“%c\n”, *(++s));
printf(“%s\n”, s+3); return 0;
}
char *mystery(char *str ) {
while(*str!=0) {
if( *str==’c’ ) break;
str++; }
printf(“%s\n”, str); return str;
}
ANSWER: cadabra b,r,a bra
B4) (6 points) Read the following C program and write the output on the screen:
#include<stdio.h> struct point2D
{
double x; double y; };
double mystery2(struct point2D ap, struct point2D *bp){ double alpha;
alpha=(ap.x – bp->x)*(ap.x – bp->x)+(ap.y - bp->y)*(ap.y - bp->y); return alpha;
}
int main(){
struct point2D a={ 2.0, 3.0 }, b={ 5.0,7.0 }; double c=mystery2( a, &b);
printf( “%5.2f\n”, c); }
ANSWER: 25.00
C
ORRECT
T
HE
E
RRORS
C) (5 points) Function max_array should receive an integer array a and its size length, as parameters. It should return the index of the largest element in the array. If there are several indeces achieving the maximum, it should return the first one.
Correct the logical errors if any. Mark your correction on the code below. If there are no errors, write “NO ERROR”
int max_array ( int a[], int length ){ int i;
int max=a[0], /* max will store the largest element */
i_max=0; /*i_max will store the index of the largest element*/
for (i =0; i < length; i++ ) if(a[i+1] < a[i])
{
max=a[i]; i_max=i; }
Correct: int max_array ( int a[], int length ) {
int i; int max=a[0],i_max=0; for (i =0; i < length; i++ )
if(max < a[i]) {
max=a[i]; i_max=i; }
return i_max;
} /* end of function */
P
ROGRAMMING
Q
UESTIONS
D1)(20 points)
a)Write a function my_strlen to compute the length of a string. The function prototype should be
int my_strlen( char *string );
The function should return the length of string.
b)Write a function my_strcat to concatenate two strings. The function prototype should be
char *my_strcat( char *string1, char *string2);
The function creates a new string by concatenating string1 and string2. The function should dynamically allocate memory for the new string. The function has to return the new string (in other words, the address of the first array element).
Function my_strcat should invoke the function my_strlen to compute the length of string1 and string2.
Start your code on this page and continue on the back of this page.
Solution:
int my_strlen( char *string ){ int length=0;
while( *string != 0) {
length++; string++; }
char *my_strcat( char *string1, char *string2){ int m,n,i;
char *str=NULL;
m=my_strlen(string1); n=my_strlen(string2);
str=(char *)calloc(m+n+1, sizeof(char)); for(i=0;i<m;i++)
str[i]=string1[i]; for(i=0; i<n; i++)
str[m+i]=string2[i]; return str;
}
D2)(20 points) A squared matrix is called diagonally dominant if for each row, the absolute value of the diagonal element on that row is strictly larger than the sum of the absolute values of all other elements in the row. In other words, the n-by-n matrix A, with elements aij, where i=1,2,…, n, and j=1,2,…,n, is diagonally dominant if the following inequality
∑
≠ =
> n
j i j
ij
ii a
a
, 1
| | | |
is satisfied for each row index i=1,2,…, n.
Write a program which inputs a squared matrix of integers and checks if it is diagonally dominant. The size of the matrix is also input by the user, therefore you need to dynamically allocate memory to store the matrix. After checking if the matrix is diagonally dominant or not you have to deallocate the memory.
You may assume that the user first inputs the number of matrix rows and then the matrix elements row after row.
You are allowed to use the function fabs(double x) in the C math library (use #include<math.h>) which returns the absolute value of x.
Solution: #include<math.h> #include<stdio.h> #include<stdlib.h>
int main(){
int n,i,j; /* number of rows */ int check=1;
int sum;
scanf(“%d”, &n); /* input number of rows */ int **ptr=(int **)calloc(n, sizeof(int *)); for(i=0; i<n; i++)
ptr[i]=(int *)calloc(n, sizeof(int)); /* input matrix */
for(i=0;i<n;i++) for(j=0;j<n;j++)
scanf(“%d”, &ptr[i][j]);
for(i=0;i<n;i++) {
sum=0;
for(j=0;j<n;j++) {
if(j==i) continue; else
sum +=fabs(ptr[i][j]); }
if(fabs(ptr[i][i]) <= sum) { check =0; break; }
}
if(check == 1)
printf(“The matrix is diagonally dominant.\n” ); else
printf(“The matrix is not diagonally dominant.\n” );
for(i=0; i<n; i++) free(ptr[i]); free(ptr);
D3)(20 points )
Write a function to perform efficient search in a table of integers with the following property. The integers on each row are strictly increasing from left to right. The integers on each column are strictly increasing from top to bottom.
Assume that the table is represented in memory using an one dimensional array (the table rows are stored consecutively).
The function prototype should be
int efficient_search( int *t, int n, int key );
where t is a pointer to the first element of the array representing the table, n is the number of rows, which coincides with the number of columns, and key is the search key. The function should return the value (i-1)*n+j if key is found on row i and column j in the table, and -1 otherwise. If the search key matches more elements in the table, it does not matter which one of these positions is returned.
Briefly justify your algorithm. Provide the number of table elements accessed in the worst case, with justification.
The mark for your solution will be commensurate with its efficiency. The maximum mark (20 points) will be awarded if your algorithm accesses at most 2n-1 table elements. No mark is awarded if your algorithm performs sequential search.
Solution
Algorithm: Check top right corner of the table. If this value matches the key STOP. Else, if the value is smaller than key, remove the first row from the table and proceed the search in the reduced size table. On the other hand, if the value is larger than key remove the last column from the table and proceed the search in the new table. Stop when either the key is found or the current table to be searched becomes empty.
a column are removed from the table. The table becomes empty after removing n rows and k columns, with 0<=k<=n-1, or after removing n columns and k rows with 0<=k<=n-1. Since at each iteration only one table element is accessed, we conclude that the largest number of elements accessed is 2n-1 (when k=n-1).
int efficient_search( int *t, int n, int key ){
int row=1; col=n;
while( row <= n && col > 0){
if( key == t[(row-1)*n+col-1])//key matches the element on
//the top right corner
return (row-1)*n+col;
else if( key <= t[(row-1)*n+col-1] ) col--; //remove last column
else