Sei sulla pagina 1di 5

CS 11

Exam 2
Due: HTRU - February 11, 2014; FWRU - February 12, 2014, both at 9:00am

General Instructions
ˆ Answer the items completely. Show your solutions and/or justifications when asked.

ˆ Write as legibly as possible. Illegible or unreadable answers and solutions may not merit any points.

ˆ If you have consulted references (books, journal articles, online materials, other people), cite them as “endnotes”
to the specific item where you used the resource/s as reference.
ˆ Use sheets of yellow pad paper for your answer sheets. Computer generated print-outs will not be
accepted.
ˆ Take note of the due dates of the answer sheets based on your section as specified above. No late submissions
will be accepted.
ˆ If you have any questions regarding an item (EXCEPT the answer and solution) in the problem set, do not
hesitate to e-mail me to ask them.

Part 1 - Objective-Type
1. Create a C function named reset_matrix that takes in a two-dimensional array of integers as input and sets
all the entries of the array to zero. (2 pts.)
ANSWER: (NOTE: This is just one of many possible answers to this problem)

void reset_matrix(int x[][], int rows, int columns) {


int i, j;
for (i = 0; i < rows; i++) {
for (j = 0; j < columns; j++) {
x[i][j] = 0;
}
}
}

2. What does the mysterious_function intend to do? (2 pts.)

int mysterious_function(int x, int y) {


return (y == 0? x: mysterious_function(y, (x % y)));
}

ANSWER: It computes and returns the greatest common factor of (the original values of) x and y.

1
3. We’ve seen that we can declare a pointer and use it to access the elements of a one-dimensional array. Provide
a C code fragment to demonstrate the declaration and usage of a pointer (you may choose any primitive data
type that you want) to access the elements of a two-dimensional array. (2 pts.)
ANSWER: (NOTE: This is just one of many possible answers to this problem)

int x[30][40];
int i = 12, j = 20;
int *ptr;

ptr = *x;

/*The statement below is similar to the statement x[12][20] = 23.*/


*(ptr + (i*40) + j) = 23;

4. Why is it good practice to always initialize pointers in C to point to NULL? (2 pts.)


ANSWER: Because as with normal variables, uninitialized pointers still hold some value, i.e. point to some
address in memory, of which might be critical to a process in the operating system. Hence, modification of the
contents pointed to by the pointer may cause serious repercussions.
5. Is it possible for 2 or more functions within the same C source code to have the same function name (e.g.
int func() and void func(int x))? Why or why not? (2 pts.)
ANSWER: No, as this results to conflict in the naming, similar to when one declares two variables of the same
name. (SIDENOTE: The feature of having several similarly-named function with different input parameters
(type and number) is called overloading a function, which aims to handle differing number and types of input
arguments. This feature is present in some programming languages.)

6. Is it possible for a C function to return a pointer, i.e. the return data type in the function header is a pointer?
If yes, provide a valid sample code, if not, provide an explanation. (2 pts.)
ANSWER: Yes.

int *return_pointer() {
int *x;
return x;
}

7. Is it possible for a C function to return an array, i.e. the return data type in the function header is an array?
If yes, provide a valid sample code, if not, provide an explanation. (2 pts.)
ANSWER: No. C only provides a way to return a reference to an array.

8. Is there always an equivalent iterative version to a recursive function? Justify your answer. (2 pts.)
ANSWER: Yes. Recursions involve some form of looping, which iterative statements typically handle.
9. Is there always an equivalent recursive version to an iterative function? Justify your answer. (2 pts.)
ANSWER: Yes. Remember that ,recursions are functions that call itself, and in the right manner, does so
if a looping condition is satisfied . Hence, if one identifies the looping condition of an iterative statement, one
should be able to determine its recursion equivalent.

2
10. The intention of this C source code is to make the pointer ptr point to a variable with value 3 when passed to
the function do_something:

#include <stdio.h>

void do_something(int *x) {


int y = 3;
x = &y;
}

main() {
int *ptr = NULL;
do_something(ptr);
printf("The value of *ptr is %d.\n", *ptr);
}

However, this will not work as intended. Explain why. (2 pts.)


ANSWER: The ”lifetime” of the variable y is only up until the end of the scope its enclosing function
(do_something). This means that after the execution of do_something is finished, y is essentially nullified,
and subsequent reference to that variable will no longer hold.
11. Consider the following C source code fragment:

typedef struct Person {


char name[100];
struct Person *mother;
struct Person *father;
struct Person *brother;
struct Person *sister;
} Person;

Additionally, assume that a variable named child of type Person has been declared and relationships have
been established prior.
(a) Write a C expression to get the name of child’s aunt, father side. (1 pt.)
ANSWER: child.father->sister->name
(b) Write a C expression to get the name of child’s uncle, mother side. (1 pt.)
ANSWER: child.mother->brother->name
(c) Write a C expressions to get the name of both child’s grand-uncles, mother side (2 pts.)
ANSWER: child.mother->mother->brother->name, child.mother->father->brother->name
(d) Is it possible to get the names of child’s first-degree cousins? Why or why not? (2 pts.)
ANSWER: No, because the declaration of the Person only allows to get the ancestry of a Person.
(e) If the answer to the previous question is yes, how do you get the names of child’s first-degree cousins?
If the answer to the previous question is no, what can we do for us to enable to get the names of child’s
first-degree cousins? (2 pts.)
ANSWER: At the very least, provide an offspring attribute to the declaration of the Person object.
12. In establishing homogenous relationships when declaring structs in C, why is it that we need to have pointers
instead of just declaring a variable with the custom data type or with the struct name? (2 pts.)
ANSWER: Because as of the point where the homogenous relationship is to be established within the struct-
based data type, its structure is still incomplete, and hence the variable cannot be constituted yet. A pointer
does not need to have a “body” and only refers/points to an object, and hence is suitable for use in this case.

3
Part 2 - Problem Solving
For this part, you have to write C codes to solve the given problems. In designing your solutions, assume correct
input by the user. This part is worth 20 pts. You are to create a program that checks the validity of a suggested
move of a single chess piece (apart from the pawn) on an empty chess board. First, ask the user what chess piece
s/he wishes to place in the chess board. The valid chess piece names are “rook”, “knight”, “bishop”, “king”, and
“queen”. Next, prompt the user to enter the initial position of the piece. The position is a combination of an English
letter (small caps) from a to h inclusive, followed by a single-digit number from 1 to 8 inclusive. For example, “a8”,
“b5”, and “h1”. Afterwards, prompt the user to enter the position where s/he wishes to move the piece. Use the
following image as reference on how to know the position within the chessboard:

Once the position on where the piece should be placed has been entered, you are to print out a message on whether
the move is valid or not. As an additional specification, 5 functions are to be written where all functions will check if
the suggested move is valid or not, but each function differs in the specific chess piece they will be using as basis for
a valid move. Name the functions check_rook_move, check_knight_move, check_bishop_move, check_king_move,
and check_queen_move. Here’s a sample run:

Enter chess piece (rook, knight, bishop, king, queen): knight


Enter piece’s initial position: a8
Enter piece’s final position: b4
That move is invalid.

Enter chess piece (rook, knight, bishop, king, queen): queen


Enter piece’s initial position: f7
Enter piece’s final position: c4
That move is valid.

4
ANSWER: (NOTE: This is just one of many possible answers to this problem)
/* Here, we also assume that no movement, i.e. same start and end position, is also a valid move. */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int check_rook_move(char start_pos[], char end_pos[]) {


if (((end_pos[0] - start_pos[0]) == 0) || ((end_pos[1] - start_pos[1]) == 0)) {
return 1;
} else {
return 0;
}
}

int check_bishop_move(char start_pos[], char end_pos[]) {


if (abs(end_pos[0] - start_pos[0]) == abs(end_pos[1] - start_pos[1])) {
return 1;
} else {
return 0;
}
}

int check_queen_move(char start_pos[], char end_pos[]) {


if (check_bishop_move(start_pos, end_pos) || check_rook_move(start_pos, end_pos)) {
return 1;
} else {
return 0;
}
}

int check_king_move(char start_pos[], char end_pos[]) {


if ((abs(end_pos[0] - start_pos[0]) < 2) && (abs(end_pos[1] - start_pos[1]) < 2)) {
return 1;
} else {
return 0;
}
}

int check_knight_move(char start_pos[], char end_pos[]) {


if ((abs(end_pos[0] - start_pos[0]) == 1) && (abs(end_pos[1] - start_pos[1]) == 2)) ||
((abs(end_pos[0] - start_pos[0]) == 2) && (abs(end_pos[1] - start_pos[1]) == 1)) ||
((abs(end_pos[0] - start_pos[0]) == 0) && (abs(end_pos[1] - start_pos[1]) == 0)) {
return 1;
} else {
return 0;
}
}

main() {
char chess_piece[10], start_pos[3], end_pos[3];
int move_valid;
printf("Enter chess piece (rook, knight, bishop, king, queen):");
gets(chess_piece);
printf("Enter piece’s initial position:");
gets(start_pos);
printf("Enter piece’s final position:");
gets(end_pos);
if (strcmp(chess_piece, "rook") == 0) {
move_valid = check_rook_move(start_pos, end_pos);
} else if (strcmp(chess_piece, "knight) == 0) {
move_valid = check_knight_move(start_pos, end_pos);
} else if (strcmp(chess_piece, "bishop") == 0) {
move_valid = check_bishop_move(start_pos, end_pos);
} else if (strcmp(chess_piece, "queen") == 0) {
move_valid = check_queen_move(start_pos, end_pos);
} else {
move_valid = check_king_move(start_pos, end_pos);
}
printf("That move is %s.\n" (move_valid? "valid": "invalid"));
}

Potrebbero piacerti anche