Adventures in Functions |
|---|
// inline.cpp -- use an inline function
#include <iostream.h>
// an inline function must be defined before first use
inline double square(double x) { return x * x; }
int main(void)
{
double a, b;
double c = 13.0;
a = square(5.0);
b = square(4.5 + 7.5); // can pass expressions
cout << "a = " << a << ", b = " << b << "\n";
cout << "c = " << c;
cout << ", c squared = " << square(c++) << "\n";
cout << "Now c = " << c << "\n";
return 0;
}
// firstref.cpp -- defining and using a reference
#include <iostream.h>
int main(void)
{
int rats = 101;
int & rodents = rats; // rodents is a reference
cout << "rats = " << rats;
cout << ", rodents = " << rodents << "\n";
rodents++;
cout << "rats = " << rats;
cout << ", rodents = " << rodents << "\n";
// some implementations require type casting the following
// addresses to type unsigned
cout << "rats address = " << &rats;
cout << ", rodents address = " << &rodents << "\n";
return 0;
}
// secref.cpp -- defining and using a reference
#include <iostream.h>
int main(void)
{
int rats = 101;
int & rodents = rats; // rodents is a reference
cout << "rats = " << rats;
cout << ", rodents = " << rodents << "\n";
// some implementations require type casting the following
// addresses to type unsigned
cout << "rats address = " << &rats;
cout << ", rodents address = " << &rodents << "\n";
int bunnies = 50;
rodents = bunnies; // can we change the reference?
cout << "bunnies = " << bunnies;
cout << ", rats = " << rats;
cout << ", rodents = " << rodents << "\n";
// some implementations require type casting the following
// addresses to type unsigned
cout << "bunnies address = " << &bunnies;
cout << ", rodents address = " << &rodents << "\n";
return 0;
}
// swaps.cpp -- swapping with references and with pointers
#include <iostream.h>
void swapr(int & a, int & b); // a, b are aliases for ints
void swapp(int * p, int * q); // p, q are addresses of ints
void swapv(int a, int b); // a, b are new variables
int main(void)
{
int wallet1 = 300;
int wallet2 = 350;
cout << "wallet1 = $" << wallet1;
cout << " wallet2 = $" << wallet2 << "\n";
cout << "Using references to swap contents:\n";
swapr(wallet1, wallet2); // pass variables
cout << "wallet1 = $" << wallet1;
cout << " wallet2 = $" << wallet2 << "\n";
cout << "Using pointers to swap contents:\n";
swapp(&wallet1, &wallet2); // pass addresses of variables
cout << "wallet1 = $" << wallet1;
cout << " wallet2 = $" << wallet2 << "\n";
cout << "Trying to use passing by value:\n";
swapv(wallet1, wallet2); // pass values of variables
cout << "wallet1 = $" << wallet1;
cout << " wallet2 = $" << wallet2 << "\n";
return 0;
}
void swapr(int & a, int & b) // use references
{
int temp;
temp = a; // use a, b for values of variables
a = b;
b = temp;
}
void swapp(int * p, int * q) // use pointers
{
int temp;
temp = *p; // use *p, *q for values of variables
*p = *q;
*q = temp;
}
void swapv(int a, int b) // try using values
{
int temp;
temp = a; // use a, b for values of variables
a = b;
b = temp;
}
// cubes.cpp -- regular and reference arguments
#include <iostream.h>
double cube(double a);
double refcube(double &ra);
int main (void)
{
double x = 3.0;
cout << cube(x);
cout << " = cube of " << x << "\n";
cout << refcube(x);
cout << " = cube of " << x << "\n";
return 0;
}
double cube(double a)
{
a *= a * a;
return a;
}
double refcube(double &ra)
{
ra *= ra * ra;
return ra;
}
// strtref.cpp -- using structure references
#include <iostream.h>
struct sysop
{
char name[26];
char quote[64];
int used;
};
sysop & use(sysop & sysopref); // function with a reference return type
int main(void)
{
// NOTE: some implementations require using the keyword static
// in the two structure declarations to enable initialization
sysop looper =
{
"Rick \"Fortran\" Looper",
"I'm a goto kind of guy.",
0
};
use(looper); // looper is type sysop
cout << looper.used << " use(s)\n";
use (use(looper)); // use(looper) is type sysop
cout << looper.used << " use(s)\n";
sysop morf =
{
"Polly Morf",
"Polly's not a hacker.",
0
};
use(looper) = morf; // can assign to function!
cout << looper.name << " says:\n" << looper.quote << '\n';
return 0;
}
// use() returns the reference passed to it
sysop & use(sysop & sysopref)
{
cout << sysopref.name << " says:\n";
cout << sysopref.quote << "\n";
sysopref.used++;
return sysopref;
}
// left.cpp -- string function with a default argument
#include <iostream.h>
const int ArSize = 80;
char * left(const char * str, int n = 1);
int main(void)
{
char sample[ArSize];
cout << "Enter a string:\n";
cin.get(sample,ArSize);
char *ps = left(sample, 4);
cout << ps << "\n";
delete [] ps; // free old string
ps = left(sample);
cout << ps << "\n";
return 0;
}
// This function returns a pointer to a new string
// consisting of the first n characters in the str string.
char * left(const char * str, int n)
{
if(n < 0)
n = 0;
char * p = new char[n+1];
for (int i = 0; i < n && str[i]; i++)
p[i] = str[i]; // copy characters
while (i <= n)
p[i++] = '\0'; // set rest of string to '\0'
return p;
}
// leftover.cpp -- overloading the left() function
#include <iostream.h>
unsigned long left(unsigned long num, unsigned ct);
char * left(const char * str, int n = 1);
int main(void)
{
char * trip = "Hawaii!!"; // test value
unsigned long n = 12345678; // test value
int i;
for (i = 1; i < 10; i++)
{
cout << left(n, i) << "\n";
cout << left(trip, i) << "\n";
}
return 0;
}
// This function returns the first ct digits of the number num.
unsigned long left(unsigned long num, unsigned ct)
{
unsigned digits = 1;
unsigned long n = num;
if (ct == 0 || num == 0)
return 0; // return 0 if no digits
while (n /= 10)
digits++;
if (digits > ct)
{
ct = digits - ct;
while (ct--)
num /= 10;
return num; // return left ct digits
}
else // if ct >= number of digits
return num; // return the whole number
}
// This function returns a pointer to a new string
// consisting of the first n characters in the str string.
char * left(const char * str, int n)
{
if(n < 0)
n = 0;
char * p = new char[n+1];
for (int i = 0; i < n && str[i]; i++)
p[i] = str[i]; // copy characters
while (i <= n)
p[i++] = '\0'; // set rest of string to '\0'
return p;
}
// funtemp.cpp -- using a function template #include <iostream.h> // function template prototype templatevoid swap(Any &a, Any &b); int main(void) { int i = 10, j = 20; cout << "i, j = " << i << ", " << j << ".\n"; cout << "Using compiler-generated int swapper:\n"; swap(i,j); // generates void swap(int &, int &) cout << "Now i, j = " << i << ", " << j << ".\n"; double x = 24.5, y = 81.7; cout << "x, y = " << x << ", " << y << ".\n"; cout << "Using compiler-generated double swapper:\n"; swap(x,y); // generates void swap(double &, double &) cout << "Now x, y = " << x << ", " << y << ".\n"; return 0; } // function prototype definition template void swap(Any &a, Any &b) { Any temp; temp = a; a = b; b = temp; }; // twotemps.cpp -- using overloaded template functions #include <iostream.h> template // original template void swap(Any &a, Any &b); template // new template void swap(Any *a, Any *b, int n); void show(int a[]); const int Lim = 8; int main(void) { int i = 10, j = 20; cout << "i, j = " << i << ", " << j << ".\n"; cout << "Using compiler-generated int swapper:\n"; swap(i,j); // matches original template cout << "Now i, j = " << i << ", " << j << ".\n"; int d1[Lim] = {0,7,0,4,1,7,7,6}; int d2[Lim] = {0,6,2,0,1,9,6,9}; cout << "Original arrays:\n"; show(d1); show(d2); swap(d1,d2,int(Lim)); // matches new template cout << "Swapped arrays:\n"; show(d1); show(d2); return 0; } template void swap(Any &a, Any &b) { Any temp; temp = a; a = b; b = temp; }; template void swap(Any a[], Any b[], int n) { Any temp; for (int i = 0; i < n; i++) { temp = a[i]; a[i] = b[i]; b[i] = temp; } }; void show(int a[]) { cout << a[0] << a[1] << "/"; cout << a[2] << a[3] << "/"; for (int i = 4; i < Lim; i++) cout << a[i]; cout << "\n"; } // twoswap.cpp -- function overrides a template #include <iostream.h> template void swap(Any &a, Any &b); struct job { char name[40]; double salary; int floor; }; void swap(job &j1, job &j2); // void swap (job &j1, job &j2); // new form void show(job &j); int main(void) { cout.precision(2); cout.setf(ios::fixed, ios::floatfield); int i = 10, j = 20; cout << "i, j = " << i << ", " << j << ".\n"; cout << "Using compiler-generated int swapper:\n"; swap(i,j); // generates void swap(int &, int &) cout << "Now i, j = " << i << ", " << j << ".\n"; job sue = {"Susan Yaffee", 56235.99, 5}; job sunny = {"Sunny Yazzi", 58309.54, 7}; cout << "Before job swapping:\n"; show(sue); show(sunny); swap(sue, sunny); // uses void swap(job &, job &) cout << "After job swapping:\n"; show(sue); show(sunny); return 0; } template void swap(Any &a, Any &b) // general version { Any temp; temp = a; a = b; b = temp; }; void swap(job &j1, job &j2) // specialized version // void swap (job &j1, job &j2) // new form // swaps just the salary and floor fields of a job structure { double t1; int t2; t1 = j1.salary; j1.salary = j2.salary; j2.salary = t1; t2 = j1.floor; j1.floor = j2.floor; j2.floor = t2; } void show(job &j) { cout << j.name << ": $" << j.salary << " on floor " << j.floor << "\n"; }
// coordin.h -- structure templates and function prototypes
// 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);
// file1.cpp -- example of a two-file program
#include <iostream.h>
#include "coordin.h" // structure templates, function prototypes
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;
}
// file2.cpp -- contains functions called in file1.cpp
#include <iostream.h>
#include <math.h>
#include "coordin.h" // structure templates, function prototypes
// 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";
}
// auto.cpp -- illustrating scope of automatic variables
#include <iostream.h>
void oil(int x);
int main(void)
{
// NOTE: some implementations require that you type cast the
// addresses in this program to type unsigned
int texas = 31;
int year = 1992;
cout << "In main(), texas = " << texas << ", &texas =";
cout << &texas << "\n";
cout << "In main(), year = " << year << ", &year =";
cout << &year << "\n";
oil(texas);
cout << "In main(), texas = " << texas << ", &texas =";
cout << &texas << "\n";
cout << "In main(), year = " << year << ", &year =";
cout << &year << "\n";
return 0;
}
void oil(int x)
{
int texas = 5;
cout << "In oil(), texas = " << texas << ", &texas =";
cout << &texas << "\n";
cout << "In oil(), x = " << x << ", &x =";
cout << &x << "\n";
{ // start a block
int texas = 113;
cout << "In block, texas = " << texas;
cout << ", &texas = " << &texas << "\n";
cout << "In block, x = " << x << ", &x =";
cout << &x << "\n";
} // end a block
cout << "Post-block texas = " << texas;
cout << ", &texas = " << &texas << "\n";
}
// external.cpp -- external variables
#include <iostream.h>
// external variable
double warming = 0.3;
// function prototypes
void update(double dt);
void local(void);
int main(void) // uses global variable
{
cout << "Global warming is " << warming << " degrees.\n";
update(0.1); // call function to change warming
cout << "Global warming is " << warming << " degrees.\n";
local(); // call function with local warming
cout << "Global warming is " << warming << " degrees.\n";
return 0;
}
void update(double dt) // modifies global variable
{
extern double warming; // optional redeclaration
warming += dt;
cout << "Updating global warming to " << warming;
cout << " degrees.\n";
}
void local(void) // uses local variable
{
double warming = 0.8; // new variable hides external one
cout << "Local warming = " << warming << " degrees.\n";
// Access global variable with the
// scope resolution operator
cout << "But global warming = " << ::warming;
cout << " degrees.\n";
}
// static.cpp -- using a static local variable
#include <iostream.h>
// constants
const int ArSize = 80;
// function prototype
void strcount(char *str);
int main(void)
{
char input[ArSize];
cout << "Enter a line:\n";
// NOTE: if your implementation doesn't support getline(), you'll
// have to rewrite the program using get(char *, int) and
// get(char)
cin.getline(input, ArSize);
while (input[0] != '\0')
{
strcount(input);
cout << "Enter next line (empty line to quit):\n";
cin.getline(input, ArSize);
}
cout << "Bye\n";
return 0;
}
void strcount(char * str)
{
static int total = 0; // static local variable
int count = 0; // automatic local variable
while (*str++) // go to end of string
count++;
total += count;
cout << count << " characters in this string\n";
cout << total << " characters total\n";
}
// twofile1.cpp -- external and static external variables
#include <iostream.h> // to be compiled with two file2.cpp
int tom = 3; // external variable definition
int dick = 30; // external variable definition
static int harry = 300; // static external variable definition
// function prototype
void remote_access(void);
int main(void)
{
// NOTE: some implementations require that you type cast
// the addresses to type unsigned
cout << "main() reports the following addresses:\n";
cout << &tom << " = &tom, " << &dick << " = &dick, ";
cout << &harry << " = &harry\n";
remote_access();
return 0;
}
// twofile2.cpp -- external and static external variables
#include <iostream.h>
extern int tom; // tom defined elsewhere
static int dick = 10; // overrides external dick
int harry = 200; // external variable definition,
// no conflict with twofile1 harry
void remote_access(void)
{
// NOTE: some implementations require that you type cast
// the addresses to type unsigned
cout << "remote_access() reports the following addresses:\n";
cout << &tom << " = &tom, " << &dick << " = &dick, ";
cout << &harry << " = &harry\n";
}