Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

7: Technicalities: Functions, etc.

Compile the three examples above to see how the compiler complains. Then add a definition of f() to get a running version.

Type in the example above and indent it properly. What suspicious constructs and bugs can you now find?

Try examples like the ones above converting all combinations of an int, a double, and a char. Use values 1001, 7.7, and 'x'. Try with implicit conversion and narrow. Write out the results for the cases where the program compiles. What errors and warnings did you get?

Write three functions swap_v(int,int), swap_r(int&,int&), and swap_cr(const int&, const int&). Each should have the body

{ int temp; temp = a, a=b; b=temp; }

where aand b are the names of the arguments.

Try calling each swap like this

int x = 7;
int y = 9;
swap_?(x,y);        // replace ? by v, r, or cr
swap_?(7,9);
const int cx = 7;
const int cy = 9;
swap_?(cx,cy);
swap_?(7.7,9.9);
double dx = 7.7;
double dy = 9.9;
swap_?(dx,dy);
swap_?(7.7,9.9);

Which functions and calls compiled, and why? After each swap that compiled, print the value of the arguments after the call to see if they were actually swapped. If you are surprised by a result, consult §7.5.

Write a program using a single file containing three namespaces X, Y, and Z so that the following main() works correctly:

int main()
{
    X::var = 7;
    X::print();         // print X's var
    using namespace Y;
    var = 9;
    print();            // print Y's var
    {
        using Z::var;
        using Z::print;
        var = 11;
        print();        // print Z's var
    }
    print();            // print Y's var
    X::print(); // print X's var

Each namespace needs to define a variable called var and a function called print() that outputs the appropriate var using cout.

Drill 3

Create a module foo with the suffix appropriate to your system:

int foo = 0;
export void print_foo() { ... };
export void set_foo(int x} { foo = x; }
export int get_foo() { return x; }

Add what it takes to get the ... part to print foo. Write file use.cpp that imports foo and tests it. Get the resulting program to compile and run.

Create a header file: foo.h:

extern int foo;
void print_foo();
void print(int);

Write a file foo.cpp that implements the functions declared in foo.h. Write file use.cpp that #includes foo.h and tests it. Get the resulting program to compile and run.

What is the difference between a declaration and a definition?

How do we syntactically distinguish between a function declaration and a function definition?

How do we syntactically distinguish between a variable declaration and a variable definition?

Why can’t you use the functions in the calculator program from Chapter 5 without declaring one or more of them first?

Is int a; a definition or just a declaration?

Why is it a good idea to initialize variables as they are declared?

What can a function declaration consist of?

What is the suffix return type notation, and why might you use it?

What good does indentation do?

What is the scope of a declaration?

What kinds of scope are there? Give an example of each.

What is the difference between a class scope and local scope?

Why should a programmer minimize the number of global variables?

What is the difference between pass-by-value and pass-by-reference?

What is the difference between pass-by-reference and pass-by-const-reference?

What is a swap()?

Would you ever define a function with a vector<double> as a by-value parameter?

Give an example of undefined order of evaluation. Why can undefined order of evaluation be a problem?

What do x&&y and x||y, respectively, mean?

Which of the following is standard-conforming C++: functions within functions, functions within classes, classes within classes, classes within functions?

What goes into an activation record?

What is a call stack and why do we need one?

What is the purpose of a namespace?

How does a namespace differ from a class?

What is a using declaration?

Why should you avoid using directives in a header?

What is namespace std?

Modify the calculator program from Chapter 6 to make the input stream an explicit parameter (as shown in §7.4.8), rather than simply using cin. Also give the Token_stream constructor (§6.8.2) an istream& parameter so that when we figure out how to make our own istreams (e.g., attached to files), we can use the calculator for those. Hint: Don’t try to copy an istream.

Write a function print() that prints a vector of ints to cout. Give it two arguments: a string for “labeling” the output and a vector.

Create a vector of Fibonacci numbers and print them using the function from exercise 2. To create the vector, write a function, fibonacci(x,y,v,n), where integers x and y are ints, v is an empty vector<int>, and n is the number of elements to put into v; v[0] will be x and v[1] will be y. A Fibonacci number is one that is part of a sequence where each element is the sum of the two previous ones. For example, starting with 1 and 2, we get 1, 2, 3, 5, 8, 13, 21, ... . Your fibonacci() function should make such a sequence starting with its x and y arguments.

An int can hold integers only up to a maximum number. Find an approximation of that maximum number by using fibonacci().

Write two functions that reverse the order of elements in a vector<int>. For example, 1, 3, 5, 7, 9 becomes 9, 7, 5, 3, 1. The first reverse function should produce a new vector with the reversed sequence, leaving its original vector unchanged. The other reverse function should reverse the elements of its vector without using any other vectors (hint: swap).

Write versions of the functions from exercise 5, but with a vector<string>.

Read five names into a vector<string> name, then prompt the user for the ages of the people named and store the ages in a vector<double> age. Then print out the five (name[i],age[i]) pairs. Sort the names (sort(name.begin(),name.end())) and print out the (name[i],age[i]) pairs. The tricky part here is to get the age vector in the correct order to match the sorted name vector. Hint: Before sorting name, take a copy and use that to make a copy of age in the right order after sorting name.

Do the previous exercise but allow an arbitrary number of names.

Write a function that given two vector<double>s price and weight computes a value (an “index”) that is the sum of all price[i]*weight[i]. Make sure to have weight.size()==price.size().

Write a function maxv() that returns the largest element of a vector argument.

Write a function that finds the smallest and the largest element of a vector argument and also computes the mean and the median. Do not use global variables. Either return a struct containing the results or pass them back through reference arguments. Which of the two ways of returning several result values do you prefer and why?

Improve print_until_s() from §7.4.2. Test it. What makes a good set of test cases? Give reasons. Then, write a print_until_ss() that prints until it sees a second occurrence of its quit argument.

Write a function that takes a vector<string> argument and returns a vector<int> containing the number of characters in each string. Also find the longest and the shortest string and the lexicographically first and last string. How many separate functions would you use for these tasks? Why?

Can we declare a non-reference function argument const (e.g., void f(const int);)? What might that mean? Why might we want to do that? Why don’t people do that often? Try it; write a couple of small programs to see what works.