- Exercise 6.1
- Exercise 6.2
- Exercise 6.3
- Exercise 6.4
- Exercise 6.5
- Exercise 6.6
- Exercise 6.7
- Exercise 6.8
- Exercise 6.9
- Exercise 6.10
- Exercise 6.11
- Exercise 6.12
- Exercise 6.13
- Exercise 6.14
- Exercise 6.15
- Exercise 6.16
- Exercise 6.17
- Exercise 6.18
- Exercise 6.19
- Exercise 6.20
- Exercise 6.21
- Exercise 6.22
- Exercise 6.23
- Exercise 6.24
- Exercise 6.25
- Exercise 6.26
- Exercise 6.27
- Exercise 6.28
- Exercise 6.29
- Exercise 6.30
- Exercise 6.31
- Exercise 6.32
- Exercise 6.33
- Exercise 6.34
- Exercise 6.35
- Exercise 6.36
- Exercise 6.37
- Exercise 6.38
- Exercise 6.39
- Exercise 6.40
- Exercise 6.41
- Exercise 6.42
- Exercise 6.43
- Exercise 6.44
- Exercise 6.45
- Exercise 6.46
- Exercise 6.47
- Exercise 6.48
- Exercise 6.49
- Exercise 6.50
- Exercise 6.51
- Exercise 6.52
- Exercise 6.53
- Exercise 6.54
- Exercise 6.55
- Exercise 6.56
What is the difference between a parameter and an argument?
Arguments are the initializers for a function's parameters. We define a function with parameter(s), while we call a function with argument(s). If the number of parameters are zero, so is arguments'.
Indicate which of the following functions are in error and why. Suggest how you might correct the problems.
(a) int f() { // return type should be string
string s;
// ...
return s;
}
(b) f2(int i) { /* ... */ } // return type is essential
(c) int calc(int v1, int v1) { /* ... */ } // parameters must have different identifiers
(d) double square (double x) return x * x; // function body must be closed by curly bracesWrite and test your own version of fact.
Write a function that interacts with the user, asking for a number and generating the factorial of that number. Call this function from main.
Write a function to return the absolute value of its argument.
Explain the differences between a parameter, a local variable, and a local static variable. Give an example of a function in which each might be useful.
-
differences
-
parameter: local variables declared inside the function parameter list. Parameters are initialized by arguments provided in each function call. So parameter is a kind of local variable.
-
local variable: variables defined in a function body, only accessible to that function and hiding declarations of the same name made in an outer scope. Parameter is a kind of special local variable. They are automatic objects.
-
local static variable: local variables whose lifetime continues across calls to the function.
-
-
example
-
parameter: for many function calls we need pass info from outside the function. Such as
valinint fact(int val) -
local variable: we don't want those variables only useful to the execution of a function to exist through the execution of the program. So we define those as local variables. Such as
retinint fact(int val) -
local static variable: some variables are necessary if we want to know the status of calls to a function. For example, we have a function to turn on/off lights. We can define a static variable to represent the status of lights. Every time we call it, we turn on/off lights, depending on we turned off/on lights last time.
-
Write a function that returns 0 when it is first called and then generates numbers in sequence each time it is called again.
Write a header file named Chapter6.h that contains declarations for the functions you wrote for the exercises in § 6.1 (p. 205).
Write your own versions of the fact.cc and factMain.cc files. These files should include your Chapter6.h from the exercises in the previous section. Use these files to understand how your compiler supports separate compilation.
Using pointers, write a function to swap the values of two ints. Test the function by calling it and printing the swapped values.
Write and test your own version of reset that takes a reference.
Rewrite the program from exercise 6.10 in § 6.2.1 (p. 210) to use references instead of pointers to swap the value of two ints. Which version do you think would be easier to use and why?
Here reference is better than pointer. If we use pointer, we have to copy value, we have to write address-of operator before every argument. Once we omit anything, our program won't work.
Using reference, on the other hand, is more convenient. Except special declarations of the parameter list, we can use every parameter a plain variable. In addition, when we pass argument, we don't have to worry about omitting anything.
Assuming T is the name of a type, explain the difference between a function declared as void f(T) and void f(T&).
We call the function f(T) by passing value; we call f(T&) by passing reference. When we change the parameter of f(T), the argument isn't effected. When we change the parameter of f(T&), the argument is changed.
Give an example of when a parameter should be a reference type. Give an example of when a parameter should not be a reference.
If we want to swap two arguments, we must use reference:
void swap(int &a, int &b);If we want to return the bigger one of two variables, we have to use non reference:
int max(int a, int b)
{
return ((a > b) ? a : b));
}Explain the rationale for the type of each of find_char’s parameters In particular, why is s a reference to const but occurs is a plain reference? Why are these parameters references, but the char parameter c is not? What would happen if we made s a plain reference? What if we made occurs a reference to const?
-
s is a reference to const because we don't want to change contents of argument passed to s incidentally. Reference parameters that are not changed in a function should be references to const. We use references because we don't want to copy objects, which is not efficient and sometimes not allowed.
-
occurs is a plain reference because we want and need to change its value. We use reference as to return the results. If we don't use reference, we don't know the results, because find_char doesn't return it. If we use reference to const, we can't change the value of the argument, thus we cannot get intended result.
-
We don't use reference but char because neither do we need to change the argument passed to c nor keep the value of the argument. We just need a copy of the argument. And for built-in type, copy is efficient enough(Please refer to Effective C++).
-
If we made s a plain reference, we might change the value of the argument by accident.
-
If we made occurs a reference to const, we would not be able to change the argument's value.
The following function, although legal, is less useful than it might be. Identify and correct the limitation on this function:
bool is_empty(string& s) { return s.empty(); }The parameter is a plain reference, thus we can not pass string literal. Correction:
bool is_empty(const string& s) { return s.empty(); }Write a function to determine whether a string contains any capital letters. Write a function to change a string to all lowercase. Do the parameters you used in these functions have the same type? If so, why? If not, why not?
- Function:
bool contain_upper(const string &s)
{
for (auto c: s) {
if (isupper(c))
return true;
}
return false;
}void to_lower_str(string &s)
{
for (auto &c: s) {
c = tolower(c);
}
}- Difference:
- The former takes a reference to const string because we know we won't change the argument.
- The latter takes a plain reference to string because we need to change the argument.
Write declarations for each of the following functions. When you write these declarations, use the name of the function to indicate what the function does. (a) A function named compare that returns a bool and has two parameters that are references to a class named matrix. (b) A function named change_val that returns a vector iterator and takes two parameters: One is an int and the other is an iterator for a vector.
(a) bool compare(const matrix&, const matrix&);
(b) vector<int>::iterator change_val(int, vector<int>::iterator);Given the following declarations, determine which calls are legal and which are illegal. For those that are illegal, explain why.
double calc(double);
int count(const string &, char);
int sum(vector<int>::iterator, vector<int>::iterator, int);
vector<int> vec(10);
(a) calc(23.4, 55.1);
(b) count("abcda", 'a');
(c) calc(66);
(d) sum(vec.begin(), vec.end(), 3.8);- (a) illegal, offer two arguments but only requires one.
- (b) legal.
- (c) legal, 66 is converted to double.
- (d) legal, 3.8 is truncated to 3.
When should reference parameters be references to const? What happens if we make a parameter a plain reference when it could be a reference to const?
Write a function that takes an int and a pointer to an int and returns the larger of the int value or the value to which the pointer points. What type should you use for the pointer?
Write a function to swap two int pointers.
Write your own versions of each of the print functions presented in this section. Call each of these functions to print i and j defined as follows:
int i = 0, j[2] = {0, 1};Explain the behavior of the following function. If there are problems in the code, explain what they are and how you might fix them.
void print(const int ia[10])
{
for (size_t i = 0; i != 10; ++i)
cout << ia[i] << endl;
}Write a main function that takes two arguments. Concatenate the supplied arguments and print the resulting string.
Write a program that accepts the options presented in this section. Print the values of the arguments passed to main.
Write a function that takes an initializer_list and produces the sum of the elements in the list.
In the second version of error_msg that has an ErrCode parameter, what is the type of elem in the for loop?
When you use an initializer_list in a range for would you ever use a reference as the loop control variable? If so, why? If not, why not?
Compile the version of str_subrange as presented on page 223 to see what your compiler does with the indicated errors.
When is it valid to return a reference? A reference to const?
Indicate whether the following function is legal. If so, explain what it does; if not, correct any errors and then explain it.
int &get(int *arry, int index) { return arry[index]; }
int main() {
int ia[10];
for (int i = 0; i != 10; ++i)
get(ia, i) = i;
}Write a recursive function to print the contents of a vector.
What would happen if the stopping condition in factorial were
if (val != 0)the recursive function will always use
valas the parameter. a recursion loop would happen.
Write the declaration for a function that returns a reference to an array of ten strings, without using either a trailing return, decltype, or a type alias.
Write three additional declarations for the function in the previous exercise. One should use a type alias, one should use a trailing return, and the third should use decltype. Which form do you prefer and why?
Revise the arrPtr function on to return a reference to the array.
Explain the effect of the second declaration in each one of the following sets of declarations. Indicate which, if any, are illegal.
(a) int calc(int, int);
int calc(const int, const int);
(b) int get();
double get();
(c) int *reset(int *);
double *reset(double *);Which, if either, of the following declarations are errors? Why?
(a) int ff(int a, int b = 0, int c = 0);
(b) char *init(int ht = 24, int wd, char bckgrnd);Which, if any, of the following calls are illegal? Why? Which, if any, are legal but unlikely to match the programmer’s intent? Why?
char *init(int ht, int wd = 80, char bckgrnd = ' ');
(a) init();
(b) init(24,10);
(c) init(14, '*');Give the second parameter of make_plural (§ 6.3.2, p.
- a default argument of 's'. Test your program by printing singular and plural versions of the words success and failure.
Which one of the following declarations and definitions would you put in a header? In a source file? Explain why.
(a) inline bool eq(const BigInt&, const BigInt&) {...}
(b) void putValues(int *arr, int size);Rewrite the isShorter function from § 6.2.2 (p. 211) to be inline.
Review the programs you’ve written for the earlier exercises and decide whether they should be defined as inline. If so, do so. If not, explain why they should not be inline.
Would it be possible to define isShorter as a constexpr? If so, do so. If not, explain why not.
Revise the program you wrote in the exercises in § 6.3.2 (p.
- that used recursion to print the contents of a vector to conditionally print information about its execution. For example, you might print the size of the vector on each call. Compile and run the program with debugging turned on and again with it turned off.
Explain what this loop does and whether it is a good use of assert:
string s;
while (cin >> s && s != sought) { } // empty body
assert(cin);What is a candidate function? What is a viable function?
Given the declarations for f from page 242, list the viable functions, if any for each of the following calls. Indicate which function is the best match, or if the call is illegal whether there is no match or why the call is ambiguous.
(a) f(2.56, 42)
(b) f(42)
(c) f(42, 0)
(d) f(2.56, 3.14)Write all four versions of f. Each function should print a distinguishing message. Check your answers for the previous exercise. If your answers were incorrect, study this section until you understand why your answers were wrong.
Given the following declarations,
void manip(int, int);
double dobj;what is the rank (§ 6.6.1, p. 245) of each conversion in the following calls?
(a) manip('a', 'z');
(b) manip(55.4, dobj);
Explain the effect of the second declaration in each one of the following sets of declarations. Indicate which, if any, are illegal.
(a) int calc(int&, int&);
int calc(const int&, const int&);
(b) int calc(char*, char*);
int calc(const char*, const char*);
(c) int calc(char*, char*);
int calc(char* const, char* const);Write a declaration for a function that takes two int parameters and returns an int, and declare a vector whose elements have this function pointer type.
int fun(int, int);Way 1:
vector<int(*)(int, int)> vec;Way 2:
using fp = int(*)(int, int);
vector<fp> vec;Way 3:
using fp = int(int, int);
vector<fp*> vec;Write four functions that add, subtract, multiply, and divide two int values. Store pointers to these values in your vector from the previous exercise.
Call each element in the vector and print their result.