>

The final skinny on bool, true, false

The bool type was a late additional to the C++ ANSI standard. Not all compilers support it in their standard libraries. The College Board wants your AP CS students to be able to use bool as a type and true and false as boolean constants. If your compiler does not support the bool type, there is a file bool.h available at the College Board Web site to implement it. Your students will need to #include this file in their programs; you will also have to make sure that file also gets #included in the AP class files.

The entire contents of the file are as follows:


#ifndef _BOOL_H

#define _BOOL_H



typedef int bool;

const int false = 0;

const int true = 1;



#endif


The what and why of functions

What is a function?

Why functions?


Using a standard function library, the math library


#include "math.h"

Useful functions:

NameArgument(s)Returns
sqrt(x)doubledouble, square root of x
pow(x, y)doubledouble, x to the power y
fabs(x)doubledouble, absolute value of x
ceil(x)doubledouble, largest integer <= x
floor(x)doubledouble, smallest integer >= x

Library also includes trig functions (sin, cos, tan, etc.). There are also two functions from stdlib.h mentioned in the book (abs, labs).

The functions specifically required by the AP CS curriculum are sqrt, pow, and fabs.


Sample math function calls


root3 = sqrt(3.0);

distance = sqrt(x * x + y * y);

distance = sqrt(pow(x, 2.0) + pow(y, 2.0));

absValue = fabs(-8.5);

fifthPower = pow(x, 5.0);

squareRoot = pow(x, 0.5);

What do you think happens here?


int x = 8;

double fifthPower = pow(x, 5);


Function declarations (Prototypes)

To make a legal call to a function, you just need to know its name, argument types, and return value type.

Function prototype format:

result-type function-name(formal-parameter-specifiers);

Examples:


	double sqrt(double);

	double pow(double base, double exponent);

	int abs(int num);

	int GimmeFive();

	bool IsEven(int number);

	double CelsiusToFahrenheit(double c);

	void PrintInDollarFormat(double amount);


Defining a function

Function definition:


	return-type function-name(formal-parameter-specifiers)

	{

		function-body

	}

To return a value:


	return(expression);


Examples


double CelsiusToFahrenheit(double c)

{

    return( 9.0 / 5.0 * c + 32 );

}

Calling this function:


    double x = 12.35;

    cout << x << " C = " << CelsiusToFahrenheit(x) << " F" << endl;



int abs(int num)

{

    if (num < 0) {

        return(-n);

    } else {

        return(n);

    }

}



void PrintInDollarFormat(double amount)

{

    cout.setf(ios::fixed);

    cout.setf(ios::showpoint);

    cout.precision(2);

    cout << "$" << amount;

    return;

}


Full program example


// File: c2ftable.cpp

// This program generates a table of Celsius to Fahrenheit conversions.



#include "iostream.h"



// Function prototypes



double CelsiusToFahrenheit(double c);



int main()

{

    const int LowerLimit = 0;

    const int UpperLimit = 100;

    const int StepSize = 10;



    int c;



    cout << "Celsius to Fahrenheit table" << endl;

    cout << "C\tF" << endl;

    for (c = LowerLimit; c <= UpperLimit; c += StepSize)

        cout << c << "\t" << CelsiusToFahrenheit(c) << endl;

    return 0;

}



// Function: CelsiusToFahrenheit

// This function returns the Fahrenheit equivalent of the Celsius temperature c



double CelsiusToFahrenheit(double c)

{

    return( 9.0 / 5.0 * c + 32);

}


Function with a boolean return value

Also called a predicate function.


bool IsLeapYear(int year)

{

    return ( ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0) );

}

Use in main program:


int main()

{

    int year;



    cout << "Enter year: ";

    cin >> year;

    if (IsLeapYear(year))

        cout << year << " is a leap year." << endl;

    else

        cout << year << " is not a leap year." << endl;

}


Factorial function


int Factorial(int n)

{

    int product, i;



    product = 1;

    for (i = 1; i <= n; i++) {

        product *= i;

    }

    return product;

}

Note declaration and use of local variables. These are available for use only inside this function, not in any other functions or even the main function.

Use in main program:


int main()

{

    int i;



    for (i = 0; i <= 7; i++)

        cout << i << "! = " << Factorial(i);

    return 0;

}

The i in main is different from the i in Factorial! Also note i as argument, n as parameter name.


Program that needs a function


int main()

{

    int height1, height2, weight1, weight2;

    int minHeight, minWeight;



    cout << "Player 1's height and weight ? ";

    cin >> height1 >> weight1;

    cout << "Player 2's height and weight ? ";

    cin >> height2 >> weight2;



    if (height1 < height2)

        minHeight = height1;

    else

        minHeight = height2;



    if (weight1 < weight2)

        minWeight = weight1;

    else

        minWeight = weight2;



    cout << "Minimum height is " << minHeight << endl;

    cout << "Minimum weight is " << minWeight << endl;



    return 0;

}


With function to eliminate redundancy


int min(int a, int b);



int main()

{

...

    minHeight = min(height1, height2);

    minWeight = min(weight1, weight2);

...

}



int min(int a, int b)

{

    if (a < b)

        return(a);

    else

        return(b);

}

OR


int min(int a, int b)

{

    if (a < b)

        return(a);



    return(b);

}


Local variables and parameter passing

Use boxes to demonstrate local variables, which exist only during function execution. Formal parameters are essentially just local variables, with their initial values provided by the argument values of the function call.


int main()

{

    int n = 17;



    cout << "Before calling redFish, n = " << n << endl;

    redFish(n);

    cout << "After calling redFish, n = " << n << endl;

    cout << "Before calling blueFish, n = " << n << endl;

    blueFish(n);

    cout << "After calling blueFish, n = " << n << endl;

    return 0;

}



void redFish(int i)

{

    int n = 14;

    i = 2;

    cout << "  In redFish, i = " << i << ", n = " << n << endl;

    return;

}



void blueFish(int n)

{

    n = 72;

    cout << "  In blueFish, n = " << n << endl;

    return;

}


Functions calling other functions


int Combinations(int n, int k);

int Factorial(int n);



int main()

{

    int n, k;

    cout << "Enter number of objects in the set (n) : ";

    cin >> n;

    cout << "Enter number to be chosen (k) : ";

    cin >> k;

    cout << "C(" << n << ", " << k << ") = " << Combinations(n, k) << endl;

    return 0;

}



int Combinations(int n, int k)

{

    return( Factorial(n) / ( Factorial(k) * Factorial(n - k) ) );

}



int Factorial(int n)

{

    as before

}


Lab: Parameter passing practice

Determine by hand, then enter and run to confirm, the output of this program.


int orange(int);

int apple(int);



int main()

{

    int a = 1, b = 3, c = 5;



    c = apple(b);

    b = orange(a);

    a = orange( apple(c) );

    cout << "main: a = " << a << ", b = " << b << ", c = " << c << endl;

}



int orange(int b)

{

    int a, c;



    a = apple(b);

    c = b++;

    cout << "orange: a = " << a << ", b = " << b << ", c = " << c << endl;

    return(c);

}



int apple(int c)

{

    int a, b;



    a = c + 10;

    b = 2 * a;

    cout << "apple: a = " << a << ", b = " << b << ", c = " << c << endl;

    return(a);

}


Program design strategies

Top-down design, also called stepwise refinement: start with general structure, work down towards details

Bottom-up design: work on the details, build up into full solution

Stub function: write the prototype of the function and a definition that just returns a constant value

A stub function can be called by other parts of a program in development, then fleshed out when the other parts have been tested. It also helps to get the general structure of the program in place, and makes you think about what parameters and return values you're going to want.

Module testing: test individual functions or modules, by writing a main program explicitly for testing them

Both top-down and bottom-up design are generally informal design methods. Most projects use a combination of design techniques. Formal design is, unfortunately, often a foregone luxury in the software industry. Sigh...


A bottom-up case study, with module testing: Display a Calendar Year

Desired output:


year ? 1998



       Jan 1998

 Su Mo Tu We Th Fr Sa

              1  2  3

  4  5  6  7  8  9 10

 11 12 13 14 15 16 17

 18 19 20 21 22 23 24

 25 26 27 28 29 30 31



       Feb 1998

 Su Mo Tu We Th Fr Sa

  1  2  3  4  5  6  7

  8  9 10 11 12 13 14

 15 16 17 18 19 20 21

 22 23 24 25 26 27 28



       Mar 1998

  1  2  3  4  5  6  7

  8  9 10 11 12 13 14

 15 16 17 18 19 20 21

 22 23 24 25 26 27 28

 29 30 31

etc.

Print out one month, given number of days and starting day of week


void PrintOneMonth(int start, int days);



int main()

{

    int start, days;

    cout << "Enter start day (0 = Sunday, 6 = Saturday) : ";

    cin >> start;

    cout << "Enter number of days in month : ";

    cin >> days;

    PrintOneMonth(start, days);

    return 0;

}



void PrintOneMonth(int start, int days)

{

    int i;



    // indent the first line

    for (i = 0; i < start; i++)

        cout << "   ";



    for (i = 1; i <= days; i++) {

        cout << setw(3) << i;



        // Check for end of week

        if ( (i + start) % 7 == 0)

            cout << endl;

    }



    // Newline at end of month only if necessary

    if ( (i + start) % 7 != 1 )

        cout << endl;

}


Increment modulo weekdays

Next, a function to increment modulo weekdays (to determine what weekday next month starts on)


int AddDay(int weekday, int inc);



int main()

{

    int weekday, inc, next;

    cout << "weekday ? ";

    cin >> weekday;

    cout << "inc ? ";

    cin >> inc;

    next = AddDay(weekday, inc);

    cout << "next = " << next << endl;

    return 0;

}



int AddDay(int weekday, int inc)

{

    return( (weekday + inc) % 7 );

}


Print a few 31-day months in a row, given starting weekday

Third, combine the first two parts to print a few 31-day months in a row, given starting weekday


void PrintOneMonth(int start, int days);

int AddDay(int weekday, int inc);



int main()

{

    int start, months;



    cout << "start ? ";

    cin >> start;

    cout << "months ? ";

    cin >> months;

    for (int i = 0; i < months; i++) {

        PrintOneMonth(start, 31);

        start = AddDay(start, 31);

    }

    return 0;

}



void PrintOneMonth(int start, int days)

{

    ...

}



int AddDay(int weekday, int inc) {

    ...

}


Lab: Define functions DaysInYear, DaysInMonth, IsLeapYear

Define the functions prototyped here, to determine the number of days in a given month and year. Be sure to test on a well chosen set of values (different months, leap years and not).


int DaysInYear(int year);

int DaysInMonth(int month, int year);

bool IsLeapYear(int year);



int main()

{

    int year, month;

    int daysInYear, daysInMonth;



    cout << "year ? ";

    cin >> year;

    cout << "month ? ";

    cin >> month;

    daysInYear = DaysInYear(year);

    daysInMonth = DaysInMonth(month, year);

    cout << "days in year = " << daysInYear << endl;

    cout << "days in month = " << daysInMonth << endl;

    return 0;

}


Lab: Write final main program

Given these two final functions, modify the main program from part 3 to print an entire year.


int FirstDayOfYear(int year);

void PrintMonthAbbr(int month);



int FirstDayOfYear(int year)

{

    int start = 1;



    // January 1900 starts on Monday

    for (int i = 1900; i < year; i++)

        start = AddDay(start, DaysInYear(i));

    return(start);

}



void PrintMonthAbbr(int month)

{

    switch (month) {

        case 1:        cout << "Jan"; break;

        case 2:        cout << "Feb"; break;

            you get the gist...

        default:       cout << "???"; break;

    }

    return;

}


Creating a library of calendar functions: Create header file (.h)


// File: calendar.h

// This file contains function prototypes for the calendar library.



int FirstDayOfYear(int year);

// Precondition: year must be 1900 or later.

// Postcondition: returns weekday of Jan. 1 in given year, as value from 0 to 6



int AddDay(int weekday, int inc);

// Precondition: weekday is value from 0 to 6

// Postcondition: returns weekday value of day inc days after given weekday



void PrintOneMonth(int start, int days);

// Precondition: start is value from 0 to 6

// Postcondition: prints a one-month calendar with given number of days, starting

//   on the given weekday.  No headings are printed.



int DaysInYear(int year);

// Precondition: year should be positive

// Postcondition: returns total number of days in given year



int DaysInMonth(int month, int year);

// Precondition: month is value from 1 to 12, year should be positive

// Postcondition: returns number of days in given month of given year



void PrintMonthAbbr(int month);

// Precondition: month is value from 1 to 12

// Postcondition: prints three-letter abbreviation of given month



bool IsLeapYear(int year);

// Precondition: year should be positive

// Postcondition: returns true if given year is a leap year


Create library source file (.cpp)


// File: calendar.cpp

// This file contains the definitions of the functions described in calendar.h



#include "iostream.h"

#include "iomanip.h"

#include "calendar.h"



int FirstDayOfYear(int year) {

    int start = 1;

    // January 1900 starts on Monday

    for (int i = 1900; i < year; i++)

        start = AddDay(start, DaysInYear(i));

    return(start);

}

Et cetera...

Calendar printing program structure:


// File calprint.cpp



#include "calendar.h"



int main()

{

	body

}

Must include calendar.cpp in your project. (In Borland C++, use "Add Node...")


A handy addition to our calendar library: day names

One way: define constant variables in calendar.h like so:


const int SUNDAY = 0;

const int MONDAY = 1;

...

const int SATURDAY = 6;

Another way, and a new concept: use an enumeration type


enum WeekDay {

	SUNDAY = 0,

	MONDAY = 1,

	...

	SATURDAY = 6

};					// Note that semicolon!

Defines 7 named constants, AND ALSO defines a new type WeekDay that we can use when declaring variables, or defining function parameters or return values.


WeekDay AddDay(WeekDay weekday, int inc);



if (AddDay(start, i) == SUNDAY) { ...


More enumeration type info

Disadvantages of using an enumeration type


WeekDay AddDay(WeekDay weekday, int inc) {

    return ( WeekDay((weekday + inc) % 7) );

}



if ( WeekDay((i + start) % 7) == SUNDAY) { ...

In either case, the constant variables or the enumerated type can be defined in calendar.h and then be used by other calendar-related programs. I prefer the constant variables in this case; having an enumerated type doesn't seem to gain me very much.


Friday the Thirteenth program


// File: Friday13.cpp

// Prints out occurrences of Friday the thirteenth in a given year.



#include "iostream.h"

#include "calendar.h"



int main()

{

    int year, month, startDay, dayThirteen;



    cout << "year ? ";

    cin >> year;

    startDay = FirstDayOfYear(year);

    for (month = 1; month <= 12; month++)

    {

        dayThirteen = AddDay(startDay, 12);

        if (dayThirteen == FRIDAY)

        {

            cout << "Beware, Friday, ";

            PrintMonthAbbr(month);

            cout << " 13th, " << year << "!" << endl;

        }

        startDay = AddDay(startDay, DaysInMonth(month, year));

    }

    return 0;

}


Lab: Determine date of Thanksgiving

Write a program that determines and displays the date of Thanksgiving in a given year (fourth Thursday in November) and also displays the calendar for the month of November. Create a new project in Borland C++ to contain your main program; don't forget to include calendar.cpp too!