Functions--C++'s Programming Modules

Function Review



// calling.cpp -- defining, prototyping, and calling a function

#include <iostream.h>

void simple(void);	// function prototype

int main(void)
{
	cout << "main() will call the simple() function:\n";
	simple();		// function call
	return 0;
}

// function definition
void simple(void)
{
	cout << "I'm just a simple country function.\n";
}



// protos.cpp -- use prototypes and function calls

#include <iostream.h>
void cheers(int);	// prototype: no return value
double cube(double x);	// prototype: returns a double
int main(void)
{
	cheers(5);             		// function call 
	cout << "Give me a number: ";
	double side;
	cin >> side;
	double volume = cube(side);	// function call
	cout << "A " << side <<"-foot cube has a volume of ";
	cout << volume << " cubic feet.\n";
	cheers(cube(2));     // prototype protection at work
	return 0;
}

void cheers(int n)
{
    for (int i = 0; i < n; i++)
		cout << "Cheers! ";
    cout << "\n";
}

double cube(double x)
{
	return x * x * x;
}



Function Arguments and Passing by Value



// twoarg.cpp -- a function with 2 arguments

#include <iostream.h>
void n_chars(char, int);
int main(void)
{
	int times;
	char ch;

	cout << "Enter a character: ";
	cin >> ch;
	while (ch != 'q')		// q to quit
	{
		cout << "Enter an integer: ";
		cin >> times;
		n_chars(ch, times);	// function with two arguments
		cout << "\nEnter another character or press the"
				" q-key to quit: ";
	   	cin >> ch;
	}
	cout << "The value of times is " << times << ".\n";
	cout << "Bye\n";
	return 0;
}

void n_chars(char c, int n)	// displays c n times
{
	while (n-- > 0)		// continue until n reaches 0
		cout << c;
}



// lotto.cpp -- odds against winning

#include <iostream.h>
// Note: some implementations require double instead of long double
long double odds(unsigned numbers, unsigned picks);
int main(void)
{
    double total, choices;
    cout << "Enter total number of game card choices and\n"
            "number of picks allowed:\n";
    while ((cin >> total >> choices) && choices <= total)
    {
        cout << "You have one chance in ";
        cout << odds(total, choices);      // compute the odds
        cout << " of winning.\n";
        cout << "Next two numbers (q to quit): ";
    }
    cout << "bye\n";
    return 0;
}

// the following function calculates the odds of picking picks
// numbers correctly from numbers choices
long double odds(unsigned numbers, unsigned picks)
{
    long double result = 1.0;  // here come some local variables
    long double n;
    unsigned p;

    for (n = numbers, p = picks; p > 0; n--, p--)
        result = result * n / p ;
    return result;
}


Functions and Arrays



// arrfun1.cpp -- functions with an array argument

#include <iostream.h>
const int ArSize = 8;
int sum_arr(int arr[], int n);		// prototype
int main(void)
{
	int cookies[ArSize] = {1,2,4,8,16,32,64,128};
// some systems require preceding int with static to
// enable array initialization

	int sum = sum_arr(cookies, ArSize);
	cout << "Total cookies eaten: " << sum <<  "\n";
	return 0;
}

// return the sum of an integer array
int sum_arr(int arr[], int n)
{
	int total = 0;                   

	for (int i = 0; i < n; i++)
		total = total + arr[i];
	return total;
}



// arrfun2.cpp -- functions with an array argument

#include <iostream.h>
const int ArSize = 8;
int sum_arr(int arr[], int n);
int main(void)
{
	int cookies[ArSize] = {1,2,4,8,16,32,64,128};
//  some systems require preceding int with static to
//  enable array initialization

	cout << cookies << " = array address, ";
//  some systems require a type cast: unsigned (cookies)

	cout << sizeof cookies << " = sizeof cookies\n";
	int sum = sum_arr(cookies, ArSize);
	cout << "Total cookies eaten: " << sum <<  "\n";
	sum = sum_arr(cookies, 3);		// a lie
	cout << "First three eaters ate " << sum << " cookies.\n";
	sum = sum_arr(cookies + 4, 4);	// another lie
	cout << "Last four eaters ate " << sum << " cookies.\n";
	return 0;
}

// return the sum of an integer array
int sum_arr(int arr[], int n)
{
	int total = 0;    
	cout << arr << " = arr, ";
// some systems require a type cast: unsigned (arr)

	cout << sizeof arr << " = sizeof arr\n";
	for (int i = 0; i < n; i++)
		total = total + arr[i];
	return total;
}



// arrfun3.cpp -- array functions and const

#include <iostream.h>
const int Max = 5;

// function prototypes
int fill_array(double ar[], int limit);
void show_array(const double ar[], int n);  // don't change data
void reassess(double r, double ar[], int n);

int main(void)
{
	double properties[Max];

	int size = fill_array(properties, Max);
	show_array(properties, size);
	cout << "Enter reassessment rate: ";
	double rate;
	cin >> rate;
	reassess(rate, properties, size);
	show_array(properties, size);
	return 0;
}

int fill_array(double ar[], int limit)
{
	double temp;
	for (int i = 0; i < limit; i++)
	{
		cout << "Enter value #" << i + 1 << ": ";
		cin >> temp;
		if (temp < 0)
			break;
		ar[i] = temp;
	}
	return i;
}

// the following function can use, but not alter,
// the array whose address is ar
void show_array(const double ar[], int n)
{
	for (int i = 0; i < n; i++)
    {
		cout << "Property #" << i + 1 << ": $";
		cout << ar[i] << "\n";
	}
}

// multiplies each element of ar[] by r
void reassess(double r, double ar[], int n)
{
	for (int i = 0; i < n; i++)
		ar[i] *= r;
}



Functions and Strings



// strgfun.cpp -- functions with a string argument

#include <iostream.h>
int c_in_str(const char * str, char ch);
int main(void)
{
	char mmm[15] = "minimum";	// string in an array
// some systems require preceding char with static to
// enable array initialization

	char *wail = "ululate";	// wail points to string

	int ms = c_in_str(mmm, 'm');
	int us = c_in_str(wail, 'u');
	cout << ms << " m characters in " << mmm << "\n";
	cout << us << " u characters in " << wail << "\n";
	return 0;
}

// this function counts the number of ch characters
// in the string str
int c_in_str(const char * str, char ch)
{
	int count = 0;

	while (*str)		// quit when *str is '\0'
	{
		if (*str == ch)
			count++;
		str++;		// move pointer to next char
	}
	return count;
}



// strgback.cpp -- a function returning a pointer to char

#include <iostream.h>
char * buildstr(char c, int n);			// prototype
int main(void)
{
	int times;
	char ch;

	cout << "Enter a character: ";
	cin >> ch;
	cout << "Enter an integer: ";
	cin >> times;
	char *ps = buildstr(ch, times);
	cout << ps << "\n";
	delete [] ps;					// free memory
	ps = buildstr('+', 20);			// reuse pointer
	cout << ps << "-DONE-" << ps << "\n";
	return 0;
}

// builds string made of n c characters
char * buildstr(char c, int n)
{
	char * pstr = new char[n + 1];
    pstr[n] = '\0';		// terminate string
	while (n-- > 0)
		pstr[n] = c;		// fill rest of string
	return pstr;
}



Functions and Structures



// travel.cpp -- using structures with functions

#include <iostream.h>
struct travel_time
{
	int hours;
	int mins;
};
const int Mins_per_hr = 60;

travel_time sum(travel_time t1, travel_time t2);
void show_time(travel_time t);

int main(void)
{

	travel_time day1 = {5, 45};		// 5 hrs, 45 min
	travel_time day2 = {4, 55};		// 4 hrs, 55 min
// Some implementations require using static travel_time
// to allow structure initialization

	travel_time trip = sum(day1, day2);
	cout << "Two-day total: ";
	show_time(trip);

	travel_time day3= {4, 32};
	cout << "Three-day total: ";
	show_time(sum(trip, day3));

	return 0;
}

travel_time sum(travel_time t1, travel_time t2)
{
	travel_time total;

	total.mins = (t1.mins + t2.mins) % Mins_per_hr;
	total.hours = t1.hours + t2.hours +
					(t1.mins + t2.mins) / Mins_per_hr;
	return total;
}

void show_time(travel_time t)
{
	cout << t.hours << " hours, "
		 << t.mins << " minutes\n";
}



// strctfun.cpp -- functions with a structure argument

#include <iostream.h>
#include <math.h>

// structure templates
struct polar
{
	double distance;	// distance from origin
	double angle;		// direction from origin
};
struct rect
{
	double x;		// horizontal distance from origin
	double y;		// vertical distance from origin
};

// prototypes
polar rect_to_polar(rect xypos);
void show_polar(polar dapos);

int main(void)
{
	rect rplace;
	polar pplace;

	cout << "Enter the x and y values: ";
	while (cin >> rplace.x >> rplace.y)  // slick use of cin
	{
		pplace = rect_to_polar(rplace);
		show_polar(pplace);
		cout << "Next two numbers (q to quit): ";
	}
	return 0;
}

// convert rectangular to polar coordinates
polar rect_to_polar(rect xypos)
{
	polar answer;

	answer.distance =
		sqrt( xypos.x * xypos.x + xypos.y * xypos.y);
	answer.angle = atan2(xypos.y, xypos.x);
	return answer;      // returns a polar structure
}

// show polar coordinates, converting angle to degrees
void show_polar (polar dapos)
{
	const double Rad_to_deg = 57.29577951;

	cout << "distance = " << dapos.distance;
	cout << ", angle = " << dapos.angle * Rad_to_deg;
	cout << " degrees\n";
}



// strctptr.cpp -- functions with pointer to structure arguments

#include <iostream.h>
#include <math.h>

// structure templates
struct polar
{
	double distance;	// distance from origin
	double angle;		// direction from origin
};
struct rect
{
	double x;		// horizontal distance from origin
	double y;		// vertical distance from origin
};

// prototypes
void rect_to_polar(const rect * pxy, polar * pda);
void show_polar (const polar * pda);

int main(void)
{
	rect rplace;
	polar pplace;

	cout << "Enter the x and y values: ";
	while (cin >> rplace.x >> rplace.y)
	{
		rect_to_polar(&rplace, &pplace);	// pass addresses
		show_polar(&pplace);		// pass address
		cout << "Next two numbers (q to quit): ";
	}
	return 0;
}

// convert rectangular to polar coordinates
void rect_to_polar(const rect * pxy, polar * pda)
{
	pda->distance =
		sqrt(pxy->x * pxy->x + pxy->y * pxy->y);
	pda->angle = atan2(pxy->y, pxy->x);
}

// show polar coordinates, converting angle to degrees
void show_polar (const polar * pda)
{
	const double Rad_to_deg = 57.29577951;

	cout << "distance = " << pda->distance;
	cout << ", angle = " << pda->angle * Rad_to_deg;
	cout << " degrees\n";
}



Recursion



// recur.cpp -- use recursion

#include <iostream.h>
void countdown(int n);

int main(void)
{
	countdown(4); 			// call the recursive function
	return 0;
}

void countdown(int n)
{
	cout << "Counting down ... " << n << "\n";
	if (n > 0)
		countdown(n-1);	// function calls itself
	cout << n << ": Kaboom!\n";
}



// ruler.cpp - use recursion to subdivide a ruler

#include <iostream.h>
const int Len = 66;
const int Divs = 6;
void subdivide(char ar[], int low, int high, int level);
int main(void)
{
	char ruler[Len];
	for (int i = 1; i < Len - 2; i++)
		ruler[i] = ' ';
	ruler[Len - 1] = '\0';
	int max = Len - 2;
	int min = 0;
	ruler[min] = ruler[max] = '|';
	cout << ruler << "\n";
	for (i = 1; i <= Divs; i++)
	{
		subdivide(ruler,min,max, i);
		cout << ruler << "\n";
		for (int i = 1; i < Len - 2; i++)
			ruler[i] = ' ';  // reset to blank ruler
	}

	return 0;
}
void subdivide(char ar[], int low, int high, int level)
{
	if (level == 0)
		return;
	int mid = (high + low) / 2;
	ar[mid] = '|';
	subdivide(ar, low, mid, level - 1);
	subdivide(ar, mid, high, level - 1);
}



Pointers to Functions



// fun_ptr.cpp -- pointers to functions

#include <iostream.h>
double betsy(int);
double pam(int);

// second argument is pointer to a type double function that
// takes a type int argument
void estimate(int lines, double (*pf)(int));

int main(void)
{
	int code;

	cout << "How many lines of code do you need? ";
	cin >> code;
	cout << "Here's Betsy's estimate:\n";
	estimate(code, betsy);
	cout << "Here's Pam's estimate:\n";
	estimate(code, pam);
	return 0;
}

double betsy(int lns)
{
	return 0.05 * lns;
}

double pam(int lns)
{
	return 0.03 * lns + 0.0004 * lns * lns;
}

void estimate(int lines, double (*pf)(int))
{
	cout << lines << " lines will take ";
	cout << (*pf)(lines) << " hour(s)\n";
}