Functions
Exercises
Question 9.1
The following function, which computes the area of a triangle, contains two errors. Locate the errors and show how to fix them. (Hint: There are no errors in the formula.)
double triangle_area(double base, height)
double product;
{
product = base * height;
return product / 2;
}
- Answer
- Program
Some problems that I can detect are:
- The type of height is not defined, the compiler defaults the type of height to
int - There is a declaration for the parameter product, but the function does not have a parameter named product.
#include <stdio.h>
double triangle_area (base, height) double base; double height; {
double product;
product = base * height;
return product / 2;
}
Question 9.2
Write a function check (x, y, n) that returns 1 if both x and y fall between 0 and n - 1, inclusive. The function should return 0 otherwise. Assume that x, y, and n are all of type int.
- Program
#include <stdio.h>
int check (int x, int y, int n);
int main (void) {
int num_1, num_2, n;
int res;
Question 9.3
Write a function gcd(m, n) that calculates the greatest common divisor of the integers m and n. (Programming Project 2 in Chapter 6 describes Euclid's algorithm for computing the GCD.)
- Program
#include <stdio.h>
int gcd (int m, int n);
int main (void) {
int n, m;
printf("Enter two integers: ");
Question 9.4
Write a function day_of_year(month, day, year) that returns the day of the year (an integer between 1 and 366) specified by the three arguments.
- Program
#include <stdio.h>
int day_of_month (int month, int day, int year);
int main (void) {
int month, day, year;
printf("Enter the date (yy/mm/dd): ");
scanf("%d/%d/%d", &year, &month, &day);
Question 9.5
Write a function num_digits(n) that returns the number of digits in n(a positive integer). Hint: To determine the number of digits in a number n, divide it by 10 repeatedly. When n reaches 0. the number of divisions indicates how many digits n originally had.
- Program
#include <stdio.h>
int num_digits (int num);
int main (void) {
int n;
int digit_count = 0;
Question 9.6
Write a function digit(n, k) that returns the kth digit (from the right) in n (a positive integer). For example, digit(829, 1) returns 9, digit(829, 2) returns 2, and digit(829, 3) returns 8. If k is greater than the number of digits in n, have the function return 0.
- Program
#include <stdio.h>
int digit (int num, int location);
int main (void) {
int num;
int k = 0;
int fetched_digit = 0;
Question 9.7
Suppose that the function f has the following definition:
int f(int a, int b) { ... }
Which of the following statements are legal? (Assume that i has type int and x has type double.)
i = f(83, 12);x = f(83, 12);i = f(3.15, 9.28);x = f(3.15, 9.28);f(83, 12);
- Answer
All of the statements above are legal. (a) is the ideal form the function can have. (b) goes in steps. Since f returns an integer, the value returned is implicitly converted to a type of double (since x is of type double). (c) goes as follows: the function expects two int arguments but two double arguments were provided. Given that the function f is already defined, the compiler knows that the function takes two int arguments, so it implicitly converts the two double arguments into int arguments (see #20 of notes). (d) is a mixture of (b) and (c). (e) is a form of expression statement (see #13 of notes).
Question 9.8
Which of the following would be valid prototypes for a function that returns nothing and has one double parameter?
void f(double x);void f(double);void f(x);f(double x);
- Answer
In the following Options, (c) is illegal since there is no type specified for x in the function protoype, also, even though (d) is legal (pre C99), but if we were to have the function f return void, it would not work as intended since the compiler defaults the return type of the function which does not have a return type specified to int.
Question 9.9
What will be the output of the following program?
#include <stdio.h>
void swap(int a, int b);
int main(void)
{
int i = 1, j = 2;
swap(i, j);
printf("i = %d, j = %d\n", i, j);
return 0;
}
void swap(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
- Answer
The output will be:
i = 1, j = 2
This is because arguments are passed by values (see #18 of notes). This means that when swap is called, the function parameter a and b copies the value of i and j. Even though swapping is done correctly inside the function body, the values stored in i and j are unaffected. Even after the function call, the variable i and j holds 1 and 2 respectively. One way to change it is by the use of pointers which we'll learn in the later chapters.
Question 9.10
Write functions that return the following values. (Assume that a and n are parameters, where a is an array of int values and n is the length of the array.)
- The largest element in
a. - The average of all elements in
a. - The number of positive elements in
a.
- Program
#include <stdio.h>
// this program does not work for pre C-99 compiler as it utilizes the Variable Length Arrays (VLA)
// a function that takes in variable length array, it is mandatory to have the len parameter precede the array parameter
// see #31 of Chapter's notes
int largest_element (int arr_len, int arr[arr_len]);
// another way to represent a function prototype that has VLA as a parameter, the * represents that
// one of the function parameter gives the length of the array
Question 9.11
Write the following function:
float compute_GPA(char grades [], int n);
The grades array will contain letter grades (A, B, C, D, or F, either upper-case or lower¬case); n is the length of the array. The function should return the average of the grades (assume that A=4, B=3, C=2, D=1, and F=0).
- Program
#include <stdio.h>
#define LEN 5
float compute_GPA (char grades[], int n);
int main (void) {
char grades[LEN];
Question 9.12
Write the following function:
double inner_product(double a[], double b[], int n);
The function should return a[0] * b[0] + a[1] * b[1] + ... + a[n-1] * b[n-1].
- Program
#include <stdio.h>
#define LEN 5
double inner_product (double arr_1[], double arr_2[], int n);
int main (void) {
double arr_1[LEN] = {0.0};
Question 9.13
Write the following function, which evaluates a chess position:
int evaluate_position(char board[8][8]);
board represents a configuration of pieces on a chessboard, where the letters K, Q, R, B, N, P represent White pieces, and the letters k, q, r, b, n, and p represent Black pieces, evaluate_position should sum the values of the White pieces (Q = 9, R = 5, B = 3, N = 3, P = 1). It should also sum the values of the Black pieces (done in a similar way). The function will return the difference between the two numbers. This value will be positive if White has an advantage in material and negative if Black has an advantage.
- Program
#include <stdio.h>
#define LEN 8
// it is not illegal to define the row length in the funtion prototype (see #67 of Chapter's notes)
// it essentially does not have any meaning, as the compiler doesn't know how many rows will the array board has
// but it is essential to provide the column length which helps calculate the row size of the array (see #68 of Chapter's notes)
int evaluate_position (char board[LEN][LEN]);
Question 9.14
The following function is supposed to return true if any element of the array a has the value 0 and false if all elements are nonzero. Sadly, it contains an error. Find the error and show how to fix it:
bool has_zero(int a[], int n)
{
int i;
for (i = 0; i < n; i++)
if (a[i] == 0)
return true;
else
return false;
}
- Answer
The error in the given code is in the logic inside the for loop. When a[i] is checked and found that it's value is non-zero, it simply returns false without checking other elements of the array. This should not happen and the value of other elements should be checked as there might be a possibility of having zero in other elements. The correct code would look like:
bool has_zero (int a[], int n) {
int i;
for (i = 0; i < n; i++)
if (a[i] == 0)
return true;
return false;
}
The for loop only checks if the element is zero, if all the elements are nonzero, then the condition is never met, hence it goes out of the loop body and simply returns false.
Question 9.15
The following (rather confusing) function finds the median of three numbers. Rewrite the function so that it has just one return statement.
double median(double x, double y, double z)
{
if (x <= y)
if (y <= z) return y;
else if (x <= z) return z;
else return x;
if (z <= y) return y;
if (x <= z) return x;
return z;
}
- Answer
Using only one return statement (and using braces since I prefer that style), the code would look like:
double median (double x, double y, double z) {
double median_value;
if (x <= y) {
if (y <= z) {
median_value = y;
} else if (x <= z) {
median_value = z;
} else {
median_value = x;
}
} else if (z <= y) {
median_value = y;
} else if (x <= z) {
median_value = x;
} else {
median_value = z;
}
return median_value;
}
The logic of the code is preserved as much as possible, but the last return statemnt from the question cannot just be translated to a variable, but it still will hold true.
Question 9.16
Condense the fact function in the same way we condensed power.
- Answer
The updated code is:
int fact (int n) {
return n <= 1 ? 1 : n * fact(n - 1);
}
Question 9.17
Rewrite the fact function so that it's no longer recursive.
- Answer
The fact function without recursion is:
int fact (int n) {
int fact_result = 1;
if (n <= 1) {
return fact_result;
} else {
for (int i = n; i > 0; i--) {
fact_result = fact_result * i;
}
return fact_result;
}
}
Question 9.18
Write a recursive version of the gcd function (see Exercise 3). Here's the strategy to use for computing gcd(m, n): If n is 0, return m. Otherwise, call gcd recursively, passing n as the first argument and m % n as the second.
- Program
#include <stdio.h>
int gcd (int num_1, int num_2);
int main (void) {
int num_1, num_2;
int gcd_value;
Question 9.19
Consider the following "mystery" function:
void pb(int n)
{
if(n != 0) {
pb(n / 2);
putchar('O' + n % 2);
}
}
Trace the execution of the function by hand. Then write a program that calls the function, passing it a numher entered by the user. What does the function do?
- Answer
- Program
Trace (taking
nas 10):
pb(10)is called, sincenis not equal to 0, the body inside if statement runs, callingpb(5)first;pb(5)is called, sincenis not equal to 0, the body inside if statement runs, callingpb(2)first;pb(2)is called, sincenis not equal to 0, the body inside the if statement runs, callingpb(1)first;pb(1)is called, sincenis not equal to 0, the body inside the if statement runs, callingpb(0)first;pb(0)is called, sincenis equal to 0, the if statement does not hold true, so the function ends here and resumes topb(1);pb(1)is resumed, theputcharstatement is executed:putchar('0' + 1 % 2)→putchar('0' + 1)→1, and the function ends, and resumes topb(2);pb(2)is resumed, theputcharstatement is executed:putchar('0' + 2 % 2)→putchar('0' + 0)→0, and the function ends, and resumes topb(5);pb(5)is resumed, theputcharstatement is executed:putchar('0' + 5 % 2)→putchar('0' + 1)→1, and the function ends, and resumes topb(10);pb(10)is resumed, theputcharstatement is executed:putchar('0' + 10 % 2)→putchar('0' + 0)→0, and the function ends, and the function call from main/other-function ends.The final result of calling
pb(10)is:1010(which is essentially a binary representation of the decimal number 10) The pb most probably stands forprint_binarylol
#include <stdio.h>
void pb (int decimal_number);
int main (void) {
int num;
printf("Enter a number: ");
Programming Projects
Project 9.1
Write a program that asks the user to enter a series of integers (which it stores in an array), then sorts the integers by calling the function selection_sort. When given an array with n elements, selection_sort must do the following:
- Search the array to find the largest element, then move it to the last position in the array.
- Call itself recursively to sort the first n - 1 elements of the array.
- Program
#include <stdio.h>
void selection_sort (int arr_len, int unsort_arr[arr_len]);
int main (void) {
int n;
printf("Enter the number of elements that needs to be sorted: ");
Project 9.2
Modify Programming Project 5 from Chapter 5 so that it uses a function to compute the amount of income tax. When passed an amount of taxable income, the function will return the tax due.
- Program
#include <stdio.h>
double calculate_tax (double taxable_income);
int main (void) {
double income = 0.0;
double tax_amount = 0.0;
Project 9.3
Modify Programming Project 9 from Chapter 8 so that it includes the following functions:
void generate_random_walk(char walk[10][10]);
void print_array(char walk[10][10]);
main first calls generate_random_walk, which initializes the array to contain ' . ' characters and then replaces some of these characters by the letters A through Z, as described in the original project, main then calls print_array to display the array on the screen.
- Program
#include <stdio.h>
#include <stdbool.h>
#include <time.h>
#include <stdlib.h>
void generate_random_walk (int row, int col, char walk[row][col]);
void print_array (int row, int col, char walk[row][col]);
int main (void) {
Project 9.4
Modify Programming Project 16 from Chapter 8 so that it includes the following functions:
void read_word(int counts[26]);
bool equal_array(int counts1[26], int counts2[26]);
main will call read_word twice, once for each of the two words entered by the user. As it reads a word, read_word will use the letters in the word to update the counts array, as described in the original project, (main will declare two arrays, one for each word. These arrays are used to track how many times each letter occurs in the words.) main will then call equal_array, passing it the two arrays, equal_array will return true if the elements in the two arrays are identical (indicating that the words are anagrams) and false otherwise.
- Program
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
// providing the array subscipt isn't really necessary but it does help document the code
// see #67 of Chapter's note
void read_word (int counts[26]);
bool equal_array (int counts1[26], int counts2[26], int arr_len);
Project 9.5
Modify Programming Project 17 from Chapter 8 so that it includes the following functions:
void create_magic_square(int n, char magic_square[n][n]);
void print_magic_square(int n, char magic_square[n][n]);
After obtaining the number n from the user, main will call create_magic_square, passing it an x array that is declared inside main, create_magic_square will fill the array with the numbers as described in the original project, main will then call print_magic_square, which will display the array in the format described in the original project. Note: If your compiler doesn't support variable-length arrays, declare the array in main to be 99 x 99 instead of x and use the following prototypes instead:
void create_magic_square(int n, char magic_square[99][99]);
void print_magic_square(int n, char magic_square[99][99]);
- Program
// using the char type for the multidimensional array has some limitation
// mainly, how do i assing two digit number as an array element?
// For this reason, i'll be using the type int instead of char
#include <stdio.h>
#include <stdbool.h>
void create_magic_square (int n, int magic_square[n][n]);
void print_magic_square (int n, int magic_square[n][n]);
Project 9.6
Write a function that computes the value of the following polynomial:
Write a program that asks the user to enter a value for , calls the function to compute the value of the polynomial, and then displays the value returned by the function.
- Program
#include <stdio.h>
double calculate_polynomial (double x);
int main (void) {
double x = 0.0;
double result = 0.0;
Project 9.7
The power function of Section 9.6 can be made faster by having it calculate in a different way. We first notice that if is a power of 2, then can be computed by squaring. For example, is the square of , so can be computed using only two multiplications instead of three. As it happens, this technique can be used even when is not a power of 2. If is even, we use the formula . If is odd, then . Write a recursive function that computes . (The recursion ends when , in which case the function returns 1.) To test your function, write a program that asks the user to enter values for and , calls power to compute ,and then displays the value returned by the function.
- Program
#include <stdio.h>
int power (int number, int power);
int main (void) {
int num, pow;
num = 1;
pow = 0;
Project 9.8
Write a program that simulates the game of craps, which is played with two dice. On the first roll, the player wins if the sum of the dice is 7 or 11. The player loses if the sum is 2, 3, or 12. Any other roll is called the "point" and the game continues. On each subsequent roll, the player wins if he or she rolls the point again. The player loses by rolling 7. Any other roll is ignored and the game continues. At the end of each game, the program will ask the user whether or not to play again. When the user enters a response other than y or Y, the program will display the number of wins and losses and then terminate.
You rolled: 8
Your point is 8
You rolled: 3
You rolled: 10
You rolled: 8
You win!
Play again? y
You rolled: 6
Your point is 6
You rolled: 5
You rolled: 12
You rolled: 3
You rolled: 7
You lose!
Play again? y
You rolled: 11
You win!
Play again? n
Wins: 2 Losses: 1
Write your program as three functions: main, roll_dice, and play_game. Here are the prototypes for the latter two functions:
int roll_dice(void);
bool play_game(void);
roll_dice should generate two random numbers, each between 1 and 6, and return their sum. play_game should play one craps game (calling roll_dice to determine the outcome of each dice roll); it will return true if the player wins and false if the player loses. play_game is also responsible for displaying messages showing the results of the player's dice rolls, main will call play_game repeatedly, keeping track of the number of wins and losses and displaying the "you win" and "you lose" messages. Hint: Use the rand function to generate random numbers. See the deal.c program in Section 8.2 for an example of how to call rand and the related srand function.
- Program
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
int roll_dice (void);
bool play_game (void);
int main (void) {