Skip to main content

Program Organization

Exercises

Question 10.1

The following program outline shows only function definitions and variable declarations,

int a;
void f(int b)
{
int c;
}
void g(void)
{
int d;
{
int e;
}
}
int main(void)
{
int f;
}

For each of the following scopes, list all variable and parameter names visible in that scope:

  1. The f function
  2. The g function
  3. The block in which e is declared
  4. The main function
  1. The function f has a parameter b, and the function block has a variable c declared as well. Since a is an external variable, it too is visible for the function f.

  2. The function g has access to the variables to the variable a, and variable d throughout the function block. Since the variable e is declared inside another small block inside the function block, it is not visible to the function g.

  3. The block in which e is declared, the block has access to the external variable a, the parent function blocks variable d, and the variable e declared inside the block.

  4. The main function has access to the external variable a, and the variable f declared inside the function block.


Question 10.2

The following program outline shows only function definitions and variable declarations.

int b, c;
void f(void)
{
int b, d;
}
void g(int a)
{
int c;
{
int a, d;
}
}
int main(void)
{
int c, d;
}

For each of the following scopes, list all variable and parameter names visible in that scope. If there's more than one variable or parameter with the same name, indicate which one is visible.

  1. The f function
  2. The g function
  3. The block in which a and d are declared
  4. The main function
  1. The function f has variable b and d declared inside the function block. Since there is an external variable b declared as well, the declaration of the variable b inside the function block "hides" the external variable b. This means that any side effects done on the variable b done inside the function block of f has no impact on the external variable b.

  2. The function g, the variable c is declared, so it is accessible to the function g. Also since c is also an external variable, the external variable is hidden to the function block of g. Also, the variable b (which is defined as external variable) is accessible to the function g.

  3. Since it is a nested block inside the function g, it has access to the variable declared in the function block of function g (granted, any variables declared after the nested block won't be visible to that nested block, which is possible in C99), so the nested block has access to the variable c (not the external variable), the variables a and d declared inside the nested block.

  4. The main function has the variable c and d declared. Since c is also an identifier for an external variable, the external variable is hidden for function main as main also has a variable named c.


Question 10.3

Suppose that a program has only one function (main). How many different variables named i could this program contain?

Theoretically, infinite. We could define nested blocks as much as we like inside the function main. This program illustrates the point:

#include <stdio.h>

int main (void) {

int i = 1;

{
int i = 10;
printf("The value of i (in first nested block) is: %d\n", i);

{
int i = 20;
printf("The value of i (in second nested-nested block) is: %d\n", i);
}
}

{
int i = 30;
printf("The value of i (in third nested block) is: %d\n", i);
}

printf("The value of i (in main function block) is: %d\n", i);

return 0;
}

If you compile this program, we get the output:

The value of i (in first nested block) is: 10 The value of i (in second nested-nested block) is: 20 The value of i (in third nested block) is: 30 The value of i (in main function block) is: 1

We can go on further, by adding blocks and declaring the variable i.

Programming Projects

Project 10.1

Modify the stack example of Section 10.2 so that it stores characters instead of integers. Next, add a main function that asks the user to enter a series of parentheses and/or braces, then indicates whether or not they're properly nested:

Enter parentheses and/or braces: ((){}{()})
Parentheses/braces are nested properly

Hint: As the program reads characters, have it push each left parenthesis or left brace. When it reads a right parenthesis or brace, have it pop the stack and check that the item popped is a matching parenthesis or brace. (If not. the parentheses/braces aren't nested properly.) When the program reads the new-line character, have it check whether the stack is empty; if so, the parentheses/braces are matched. If the stack isn't empty (or if stack_underflow is ever called), the parentheses/braces aren't matched. If stack_overflow is called, have the program print the message Stack overflow and terminate immediately.

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

#define STACK_SIZE 100

// external/global variable declaration and initialization.
char contents[STACK_SIZE];
int top = 0;

Project 10.2

Modify the poker.c program of Section 10.5 by moving the num_in_rank and num_in_suit arrays into main, which will pass them as arguments to read_cards and analyze_hand.

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

#define NUM_RANKS 13
#define NUM_SUITS 4
#define NUM_CARDS 5

void read_cards (int num_in_rank[], int num_in_suit[]);

Project 10.3

Remove the num_in_rank, num_in_suit, and card_exists arrays from the poker.c program of Section 10.5. Have the program store the cards in a 5 x 2 array instead. Each row of the array will represent a card. For example, if the array is named hand, then hand[0][0] will store the rank of the first card and hand[0][1] will store the suit of the first card.

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <ctype.h>

#define NUM_RANKS 13
#define NUM_SUITS 4
#define NUM_CARDS 5

Project 10.4

Modify the poker.c program of Section 10.5 by having it recognize an additional category, "royal flush" (ace, king, queen, jack, ten of the same suit). A royal flush ranks higher than all other hands.

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <ctype.h>

#define NUM_RANKS 13
#define NUM_SUITS 4
#define NUM_CARDS 5

Project 10.5

Modify the poker.c program of Section 10.5 by allowing "ace-low" straights (ace, two, three, four, five).

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <ctype.h>

#define NUM_RANKS 13
#define NUM_SUITS 4
#define NUM_CARDS 5

Project 10.6

Some calculators (notably those from Hewlett-Packard) use a system of writing mathematical expressions known as Reverse Polish Notation (RPN). In this notation, operators are placed after their operands instead of between their operands. For example, 1 + 2 would be written 1 2 + in RPN, and 1 + 2 * 3 would be written 1 2 3 * +. RPN expressions can easily be evaluated using a stack. The algorithm involves reading the operators and operands in an expression from left to right, performing the following actions:

  • When an operand is encountered, push it onto the stack.
  • When an operator is encountered, pop its operands from the stack, perform the operation on those operands, and then push the result onto the stack.

Write a program that evaluates RPN expressions. The operands will be single-digit integers. The operators are +, -, *, /, and =. The = operator causes the top stack item to be displayed; afterwards, the stack is cleared and the user is prompted to enter another expression. The process continues until the user enters a character that is not an operator or operand:

Enter an RPN expression: 1 2 3 * + =
Value of expression: 7
Enter an RPN expression: 5 8 * 4 9 - / =
Value of expression: -8
Enter an RPN expression: q

If the stack overflows, the program will display the message Expression is too complex and terminate. If the stack underflows (because of an expression such as 1 2 + +), the program will display the message Not enough operands in expression and terminate. Hints: Incorporate the stack code from Section 10.2 into your program. Use scanf(" %c", &ch) to read the operators and operands.

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

#define STACK_SIZE 5

// external/global variable declaration and initialization.
int contents[STACK_SIZE] = {0};
int top = 0;

Project 10.7

Write a program that prompts the user for a number and then displays the number, using characters to simulate the effect of a seven-segment display:

Enter a number: 491-9014

     _     _   _
|_| |_| | |_| | | | |_|
| _| | _| |_| | |

Characters other than digits should be ignored. Write the program so that the maximum number of digits is controlled by a macro named MAX_DIGITS, which has the value 10. If the number contains more than this number of digits, the extra digits are ignored. Hints: Use two external arrays. One is the segments array (see Exercise 6 in Chapter 8), which stores data representing the correspondence between digits and segments. The other array, digits, will be an array of characters with 4 rows (since each segmented digit is four characters high)and MAX_DIGITS * 4 columns (digits are three characters wide, but a space is needed between digits for readability). Write your program as four functions: main, clear_digits_array, process_digit, and print_digits_array. Here are the prototypes for the latter three functions:

void clear_digits_array(void);
void process_digit(int digit, int position);
void print_digits_array(void);

clear_digits_array will store blank characters into all elements of the digits array. process_digit will store the seven-segment representation of digit into a specified position in the digits array (positions range from 0 to MAX_DIGITS - 1). print_digits_array will display the rows of the digits array, each on a single line, producing output such as that shown in the example.

#include <stdio.h>
#include <ctype.h>

#define MAX_DIGITS 10

const int segments[10][7] = {{1, 1, 1, 1, 1, 1, 0},
{0, 1, 1, 0, 0, 0, 0},
{1, 1, 0, 1, 1, 0, 1},
{1, 1, 1, 1, 0, 0, 1},