CMSC--202 Computer Science II for Majors
Fall 1997 23 September 1997 Exam 1 Review
Exam 1 will be a full-period exam. The exam will be taken entirely from the following questions, although some of the questions may be changed in minor ways. One purpose of these review questions is to guide your studying for the exam. You could work every single problem in the review -- that should guarantee an excellent exam grade (and help you understand the material very well). Alternatively, you could notice that the problems fall into various categories -- be sure you can work representative problems in each category.
Another purpose of these review questions is to eliminate any possibility of ``trick'' questions on the exam. There are no tricks. No question on the exam should be a surprise to you. Every question on the exam will be substantially (or exactly) the same as one of these review questions.
foo.c:
int main() { double x = 4.0; ProcA(x); ProcB(); }
m1.h:
extern void ProcA(double);
m2.h:
extern void ProcB(void);
m1.c:
void ProcA(double y) { printf("%f\n", sqrt(y)); }
m2.c:
void ProcB(void); { int y; scanf("%d",&y); }
#include
,
#ifndef
, etc. needed in any file.
foo
. Each module ( i.e., foo.c
,
m1.c
, and m2.c
) must be separately compiled before linking
into the executable.
/* localMatch * Returns TRUE if, starting at word index word_i, each character of * pattern matches the corresponding character in word. Example: * the pattern "abc" does match the word "qrsabcdef" at word index 3. * Returns FALSE otherwise. */ int localMatch(char * word, char * pattern, int word_i);
localMatch
to test for the occurrence of
pattern at a given index in word.
localMatch
to test for the occurrence of
pattern string at the end of word.
localMatch
to test for the occurrence of
pattern anywhere in word.
stringLength(char * s)
that returns
the length of the string s
. Do not use strlen
anywhere
in the function. You may assume that s
is a null-terminated
array of char
.
int foo(int start, int finish) { if (start == finish) return 0; return (1 + foo(start+1, finish)); }What are the values of the parameters with which your function is to be called?
float Power(float x, unsigned n)that computes
x^n
. n
is a nonnegative integer.
[Hint: x^n
can be defined by the following two
equations:
x^0 = 1.0 x^n = x * x^(n-1) for n >= 1
float Power(float x,unsigned n)
that
works by breaking n
down into halves, squaring
Power(x,n/2)
, and multiplying by x
again if n
was
odd. For example,
x^11 = x^5 * x^5 * x x^10 = x^5 * x^5
int Mult(unsigned m,unsigned n)to multiply two positive integers,
m
and n
, using only
repeated addition.
int Product(int m,int n)
which
gives the product of the integers in the range m:n
(m <= n
)
int Min(int A[], int n)
to find the
smallest integer in the integer array A
. n
is the
number of elements in A
. Hint: define an
auxiliary function Min2(A,k,j)
that finds the smallest integer in
A[k:j]
and let Min(A,n) = Min2(A,0,n-1)
PrintChars
, below, prints the
string S
, character-by-character, and returns the sum of
N
and the number of characters printed. Write a recursive function
int PrintEmBackwards(char S[], int N)which prints the characters in reverse order, returning the same sum.
int PrintChars(char S[], int N) { if (*S == '\0') return N; printf("%c",*S); return PrintChars(S + 1, N + 1); }
PrintChars
is of the form
int F(X) { if (P(X)) return G(X); K(X); return F(H(X)); }Identify
F
, X
, P(X)
, G(X)
, K(X)
,
and H(X)
.
PrintChars
.
int foo (int bar) /* bar is greater than zero */ { if (bar > 0) bar = bar - 1; return foo(bar/2); }
int foo (int bar, int bell) { if (bar >= bell) return foo(bar - bell, bell); return bar; }
int foo (int bar) { int gak; gak = getchar(); if (gak == EOF) return 0; if (gak == 'Q') return foo(bar) + bar; return foo(bar) - bar; }
int change_char (char A[], char old, char new)that takes a
char
array named A
, a char
named old
and a
char
named new
. Each
occurrence of old
in A
is to be replaced by new
.
change_char
returns the number of replacements made.
Assume that A
is null-terminated
( i.e., the last character in A
is the '\0
' character.)
All array manipulations are to be done by pointer arithmetic (do
not use subscript notation).
change_char
to use tail-recursion.
void double_char(char S[], char C, char T[])that copies one string of characters into another one, replacing every instance of a given character with two copies of that character as it proceeds.
Double_char
takes three
arguments: a string S
to copy from (a null-terminated array of
characters);
a character C
to double; and a string T
to copy to
(another array of characters). You may assume that T
is large
enough. For example, if the source string is
"xyzzy"
and the
character to double is 'y'
, the target string ( i.e., the
third argument) should be set to the string "xyyzzyy"
. Don't forget to
terminate the target string with the ASCII null
character ( i.e., with '\0'
). All looping must be accomplished with
recursion---you may not use any of C's iteration constructs. You may
use a helper function if you like, but none is necessary.
void remove_char(char S[], char C, char T[])
that copies string S
into string T
removing every instance of character C
as it proceeds. You may
assume that T
is of the appropriate size.
For example, if S
is "xyzzy"
, and
C
is 'y'
, then T
should be set to the string
"xzz"
. Don't forget to
terminate the target string with the ASCII null
character ( i.e., with '\0'
). All looping must be
accomplished with
recursion---you may not use any of C's iteration constructs. You may
use a helper function if you like, but none is necessary.
int count_digit(int digit, int numb)that returns the number of occurrences of
digit
in the decimal representation of numb
.
digit
is an int
between zero and nine
inclusive.
For example, the call count_digit(8, 18488)
should return
3
, because there are three eights in the decimal representation
of 18488.
Recall that if num
is an integer, then num/10
is the
integer part of num
divided by ten, while num%10
is the
remainder of num
divided by ten. These provide a way to split
the problem into smaller pieces.
All looping in your function must be accomplished with
recursion---you may not use any of C's iteration constructs. You may
use a helper function if you like, but none is necessary.
count_occurrences
should take three arguments: an array of
int
s, the number of elements in the array, and the integer
occurrences of which in the array are to be counted.
count_7s
, which counts the number of
occurrences of the digit 7
in the decimal representation of a
given integer. For example, if the argument to count_7s
is
3762797
, count_7s
should return 3
(because there are
three occurrences of the digit 7
in 3762797
). Hint:
remember that n%10
will give the remainder of n
divided
by ten, while n/10
will give the integer part of n
divided
by ten.
isPalindrome
. The function returns 1 if the string S is a
palindrome (reads the same forward and backward). It returns 0 if
S is not a palindrome. The function is intended to be called
with the parameter left
equal to zero and the parameter
right
equal to strlen(S) - 1.
int isPalindrome(char * S, int left, int right) { if (left >= right) return 1; // true, S is a palindrome if (S[left] != S[right]) return 0; // false, S is not a palindrome return isPalindrome(S, left + 1, right - 1); }
isPalindrome
. The function returns 1 if the string S is a
palindrome (reads the same forward and backward). It returns 0 if
S is not a palindrome. The function is intended to be called
with the parameter left
equal to zero and the parameter
right
equal to strlen(S) - 1.
int isPalindrome(char * S, int left, int right) { if (left >= right) return 1; // true, S is a palindrome if (S[left] != S[right]) return 0; // false, S is not a palindrome return isPalindrome(S, left + 1, right - 1); }
typedef struct gak *gak_ptr; typedef struct gak { gak_ptr field1; gak_ptr field2; } gak_type; gak_type dalloway; gak_type lighthouse; lighthouse.field1 = &dalloway; lighthouse.field1->field2 = malloc(sizeof(gak_type)); dalloway.field2->field2 = lighthouse.field1; lighthouse.field2 = dalloway.field2; lighthouse.field2->field2->field2 = lighthouse.field2->field2; dalloway.field1 = lighthouse.field2; dalloway.field2->field1->field1 = lighthouse.field1->field1;
typedef int *intptr; typedef intptr array[3]; typedef struct { char nose; array elbow; } frenulum; typedef frenulum *anvil; anvil blatz; blatz = malloc(sizeof(frenulum)); (*blatz).nose = 'A'; blatz->elbow[0] = malloc(sizeof(int)); blatz->elbow[1] = malloc(sizeof(int)); blatz->elbow[2] = blatz->elbow[0]; *(blatz->elbow[1]) = 17; blatz->elbow[0] = blatz->elbow[1]; *(blatz->elbow[2]) = 42;
typedef struct click_tag *click_ptr; typedef struct clack_tag *clack_ptr; typedef struct click_tag { clack_ptr boston; click_ptr accent; } click_struct; typedef struct clack_tag { int car; click_ptr guys; } clack_struct; click_struct puzzler; puzzler.boston = malloc(sizeof(clack_struct)); puzzler.accent = malloc(sizeof(click_struct)); puzzler.accent->accent = &puzzler; puzzler.accent->accent->boston->guys = puzzler.accent; puzzler.boston->guys->accent = puzzler.accent; puzzler.accent->accent->boston = puzzler.boston; puzzler.boston->guys->boston->car = 42;
typedef int *intptr; typedef intptr *lamar; typedef intptr bob[3]; typedef bob *phil; lamar alexander; bob dole; phil gramm; gramm = &dole; alexander = dole + 1; dole[1] = malloc(sizeof(int)); (*gramm)[2] = *alexander; *dole = NULL; **(alexander + 1) = 17;
typedef struct charlie { struct charlie *chocolate; int factory; } wonka; typedef wonka *candy; typedef candy bar[3]; typedef candy *willy; willy augustus; bar gloop; gloop[0] = malloc(sizeof(wonka)); gloop[2] = gloop[0]; *(gloop + 1) = malloc(sizeof(wonka)); gloop[1]->chocolate = gloop[0]; augustus = gloop + 2; (*(gloop + 2))->chocolate = gloop[1]; (**augustus).factory = 17; (*augustus)->chocolate->factory = 42;
typedef int *femur; typedef femur tibia[3]; tibia radius; int ulna; radius[1] = malloc(sizeof(int)); radius[0] = &ulna; radius[2] = radius[0]; *radius[0] = 88; ulna = 12; *radius[2] = 17; radius[2] = radius[1]; *radius[1] = 42;
typedef int int3type[3]; typedef int int9type[9]; typedef int3type * iarr3ptr; typedef int9type * iarr9ptr; typedef int * iptr; void main(void) { int9type I; iarr9ptr iap9; iarr3ptr iap3; iptr ip1; int i; iap9 = &I; iap3 = (iarr3ptr) &I; ip1 = I; for (i = 0; i < 9; i++) I[i] = i + 10; ip1++; iap3++; iap9++; }
typedef
s, variable declarations, and statements that will build
the structure depicted. Remember that a plain arrow pointing to a box
represents a pointer to the entire box. An arrow with a circle
at its head represents a pointer to just that one component.
int
argument and returns char *
.
The array should be of size 4.
int add_if(int A[], int asize, BOOL (* f)(int))that returns the number of elements of the array
A
which
satisfy the function f
. The parameter asize
is the
number of elements in the array A
.
typedef
is recommended for this question. Note
that when we say a function ``takes a function'' or ``returns a
function,'' we mean takes or returns a pointer to function.
Write legal C code to declare a function called foo
.
foo
returns a function which takes a float and returns a float.
foo
takes two arguments:
typedef int (* foofunc)(int); int foo1(int x) { return x; } int foo2(int y) { return 2 * y; } foofunc x[] = {foo1, foo2}; printf("%d", x[0](x[1](2)) );
typedef float (* foofunc)(int); float foo1(int x) { return (float) x; } float foo2(int y) { return 2.0 * y; } foofunc foo(int x) { if (x > 0) return foo1; else return foo2; } { foofunc fp; fp = foo(-10); printf("%f",(*fp)(10)); }