Chapter 7: Function (Exercises Solutions)

Exercise 7.1:What is the difference between a parameter and an argument?

The parameters of a function provide named, local storage for use by the function.
An argument is an expression, it might be a variable, a literal constant or an expression involving one or more operators.

Exercise 7.2: Indicate which of the following functions are in error and why. Suggest how you might concern the problems.

(a) int f() {

string s;

// ...

return s;

}

(b) f2(int i) { / . . . / }

(c) int calc(int v1, int v1){ / . . . / }

(d) double square(double x) return x * xi;

(a) Cannot return string instead of int. There is no conversion from string to int.
     string f() {
         string s;
         // ...
         return s;
     }
(b) No explicitly return type.
     void f2(int i)    { /*  ...  */ }
(c) A curly brace is missing and same parameters name. A block is not entirely, no same parameter is allowed.
     int calc(int v1, int v2)    { /* ... */ }
(d) The block is missing. The function body should be closed in a block.
     double square(double x)    { return x * x; }

Exercise 7.3:Write a program to take two int parameters and generate the result of raising the first parameter to the power of the second. Write a program to call your function passing it two ints. Verify the result.

#include <iostream>

using std::cout;
using std::endl;

int power(int v1, int v2)
{
    for (int i = 0; i != v2; ++i)
        v1 *= v2;

    return v1;
}

int main()
{
    int val;
    val = power(2,3);

    cout << val << endl;

    return 0;
}

Exercise 7.4:Write a program to return the absolute value of its parameter.

int abs(int ival)
{
    if (ival < 0)
        return -ival;
    else
        return ival;
}

Exercise 7.5:Write a function that takes an int and a pointer to an int and returns the larger of the int value of the value to which the pointer points. What type should you use for the pointer?

int larger(int v1, const int *v2)
{
    return (v1 < *v2) ? *v2 : v1;
}

Exercise 7.6:Write a function to swap the value pointed by two values pointed to by two pointers to int. Test the function by calling it and printing the swapped values.

void swap(int v1, int v2)
{
    int temp = v2;
    v2 = v1;
    v1 = temp;
}

Exercise 7.7:Explain the difference in the following two parameter declaraions:

void f(T);

void f(T&);

The first parameter declaration shows that the argument will be copied and not changed in the function.
The second parameter declaration shows that the argument will have a reference of it, and can be changed in the function.

Exercise 7.8:Give an example of when a parameter should be a reference type. Give an example of when a parameter should not be a reference.

Reference:
void swap(int &v1, int &v2)
{
    int temp = v2;
    v2 = v1;
    v1 = temp;
}

Nonreference:
int gcd(int v1, int v2)
{
    while (v2) {
        int temp = v2;
        v2 = v1 % v2;
        v1 = temp;
    }
    return v1;
}

Exercise 7.9: Change the declaration of occurs in the parameterlist of find_val (defined on page 234) to be a nonreference argument type and rerun the program. How does the behavior of the program change?

The occur won't be changed, so the function doesn't return the occur.

Exercise 7.10: The following program, although legal, is less useful than it might be. Identify and correct the limitation on this program:

bool test(string& s) { return s.empty(); }

It can only receive the string object, not the string literal or an expression that yields a string.
bool test(const string &s)    { return s.empty(); }

Exercise 7.11:When should reference parameters be const? What problems might arise if we make a parameter a plain reference when it could be a const reference?

When the arguments only need to be read.
They will be less flexible, such parameters cannot be initialized by const objects, or by arguments that are literals or expressions that yield values.

Exercise 7.12:When would you use a parameter that is a pointer? When would you use a parameter that is a reference? Explain the advantages and disadvantages of each.

When getting a parameter that is container or arrays.
When we need to change the value of the objects in the function.
Pointers are good at processing the containers but weak at objects.
References are good at changing the value of the objects but weak at containers.

Exercise 7.13:Write a program to calculate the sum of the elements in an array. Write the functions three times, each one using a different approach to managing the array bounds.

1)
int sumArry(const int *ptr,int marker)
{
    int sum = 0;

    while (*ptr != marker) {
        sum += *ptr;
        ++ptr;
    }
    return sum;
}

int main()
{
    int ia[12] = {1,2,3,4,5,6,7,8,9,10,-1};  
    cout << sumArry(ia, -1) << endl;

    return 0;
}
int sumArry(const int *ptr,int marker)
{
    int sum = 0;

    while (*ptr != marker) {
        sum += *ptr;
        ++ptr;
    }
    return sum;
}

int main()
{
    int ia[12] = {1,2,3,4,5,6,7,8,9,10,-1};  
    cout << sumArry(ia, -1) << endl;

    return 0;
}
2)
int sumArry(const int *beg, const int *end)
{
     int sum = 0;
     while (beg != end) {
          sum += *beg;
          ++beg;
     }
     return sum;
}

int main()
    i
{
    int ia[11] = {1,2,3,4,5,6,7,8,9,10};
    cout << sumArry(ia, ia + 11) << endl;

    return 0;
}

3)
int sumArry(const int ia[], int size)
{
     int sum = 0;

    for (int i = 0; i != size; ++i)
        sum += ia[i];        

    return sum;    
}

int main()
{
    int ia[11] = {1,2,3,4,5,6,7,8,9,10};
    cout << sumArry(ia, 11) << endl;

    return 0;
}

Exercise 7.14:Write a program to sum the elements in a vector.

double sumDvec(vector<double>::const_iterator beg, vector<double>::const_iterator end)
{
    double sum = 0.0;
    while (beg != end) {
        sum += *beg;
        ++beg;
    }
    return sum;
}

int main()
{
    vector<double> dvec(10,9);
    cout << sumDvec(dvec.begin(), dvec.end()) << endl;

    return 0;
}

Exercise 7.15:Write a main function that two values as arguments and print their sum.

int main(int v1, int v2)
{
    cout << v1 + v2 << endl;

    return 0;
}

Exercise 7.16:Write a program that could accept the options presented in this section.

int main(int argc, char **argv)
{
    cout << "arguments passed to main(): " << endl;
    for (int i = 0; i != argc; ++i)
        cout << argv[i] << endl;

    return 0;
}

Exercise 7.17:When is it valid to return a reference? A const reference?

Not return a reference to a local object.
The same as the reference but also it cannot be changed outside the function.

Exercise 7.18: What potential run-time problem does the following function have?

string &processText() {

string text;

while (cin >> text) { / . . . / }

// ...

return text;

}

The return value refers to text is no longer available to the program.

Exercise 7.19: Indicate wheter the following program is legal. If so explain what it does; if not, make it legal 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) = 0;

}

It's legal, it sets every elements in ia to 0.

Exercise 7.20:Rewrite factorial as an iterative function.

int factorial(int val)
{
    int result;
    while (val != 0) {
        result *= val;
        --val;
    }
    return result;
}

Exercise 7.21: What would happen if the stopping condition in factorial were:

if (val != 0)

It will recurse indefinitely when the val is negative.

Exercise 7.22: Write the prototypes for each of the following functions:

(a) A function named compare with two parameters that are references to a class named matrix and with a return value of type bool.

(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.

Hint: When you write these prototypes, use the name of the function as an indicator as to what the functions does. How does this hint affect the types you use?

(a) bool compare(const matrix &m1, const matrix &m2)
(b) vector<int>::iterator change_val(int pos, vector<int>::iterator ivec)

Indicates the function.

Exercise 7.23: 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::iterator, vector::iterator, int);

vector vec(10);

(a) calc(23.4, 55.1);

(b) count("abcda", 'a');

(c) calc(66);

(b) sum(vec.begin(), vec.end(), 3.8);

(a) is illegal, others are legal.
There is only one parameter in calc function.

Exercise 7.24: Which, if any, 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 bckgrd);

(a) There is no error.
(b) wd and bckgrnd should have default arguments if ht has already had.

Exercise 7.25: Given the following function declarations and calls, which, if any, of the calls are illegal? Why? Which, if any, are legal but unlikely to match the programmer's intent? Why?

// declarations

char *init (int ht, int wd = 80, char bckgrnd = ' '};

(a) init();

(b) init(24,10);

(c) init(14,'*');

(a) It is illegal, ht has no default argument so it shouldn't be omitted.
(b) It is legal, and matches the programmer's intent.
(c) It is legal, but '*' is  passed to the bckgrnd parameter not the wd, char is converted to unsigned int.

Exercise 7.26:Write a version of make_plural with a default argument of 's'. Use that version to print sigular and plural versions of the words "success" and "failure".

string make_plural(size_t ctr, const string &word, const string &ending = "s")
{
    return (ctr == 1) ? word : word + ending;
}

int main()
{
    cout << "The singular form of success is " << make_plural(1, "success", "es")
    cout << "The plural form of success is " << make_plural(0, "success", "es")
    cout << "The singular form of failure is " << make_plural(1, "failure")
    cout << "The plural form of success is " << make_plural(0, "failure")

    return 0;
}

Exercise 7.27:Explain the differences between a parameter, a local variable and a static local variable. Give an example of a program in which each might be useful.

A parameter is passed by an argument and is created when the function is called.
A local variable is a object defined inside the function when it is called.
A static local variable, is also a object defined inside the function when it is first called, but it won't be destroyed until the program is terminated.

Exercise 7.28:Write a function that returns 0 when it first called and then generates numbers in sequence each time it is called again.

int f()
{
    static int num = 0;
    return num;
}

Exercise 7.29: Which one of the following declarations and definitions would you put in a header? In a program text file? Explain why,

(a) inline bool eq(const BigInt&, const BigInt&) { . . . }

(b) void putValues(int *arr, int size);

Both in a header. 
First a inline function should be used in several programs, so it should be defined in a header. 
Next a declaration is the same reason.

Exercise 7.30:Rewrite the isShorter function from page 235 as an inline function.

inline bool isShorter(const string &s1, const string &s2)
{
    return (s1.size() < s2.size());
}

Exercise 7.31: Write your own version of the Sales_item class, adding two new public members to read and write Sales_item objects. These functions should operate similarly to the input and output operators used inChapter 1. Transactions should look like the ones defined in that chapter as well. Use this classes to read and write a set of transactions.

-------------------------------------------------------------------------------------------------------------------------
// Sales_item.h
#include <string>

using std::string;

class Sales_item
{
public:
    Sales_item() : units_sold(0), revenue(0.0) { }
    bool same_isbn(const Sales_item &rhs) const;
    double avg_price() const;
    void getTrans() const;
    void setTrans();
private:
    string isbn;
    unsigned units_sold;
    double revenue;
};

--------------------------------------------------------------------------------------------------------------------------
// Sales_item.cpp
#include <iostream>
#include <string>

bool Sales_item::same_isbn(const Sales_item &rhs) const
{ 
    return isbn == rhs.isbn;
}

double Sales_item::avg_price() const
{
    return revenue / units_sold;
}

void Sales_item::getTrans() const
{
    std::cout << isbn << " " << units_sold << " " << revenue << std::endl;
}

void Sales_item::setTrans(const string &new_isbn)
{
    isbn = new_isbn;
}

--------------------------------------------------------------------------------------------------------------------------
// main.cpp
#include <iostream>
#include <string>
#include "test.h"

using std::string;

int main()
{
    Sales_item item1, item2;
    item1.setTrans();
    item2.setTrans();

    if (item1.same_isbn(item2)) {
    item1.getTrans();
    item2.getTrans();
    }

    return 0;
}

Exercise 7.32:Write a header file to contain your version of the Sales_item class. Use ordinary C++ conversions to name the header and any associated file needed to hold non-inline functions defined outside the class.

-------------------------------------------------------------------------------------------------------------------------
// Sales_item.h
#include <string>

using std::string;

class Sales_item
{
public:
    Sales_item() : units_sold(0), revenue(0.0) { }
    bool same_isbn(const Sales_item &rhs) const;
    double avg_price() const;
    void getTrans() const;
    void setTrans();
private:
    string isbn;
    unsigned units_sold;
    double revenue;
};

--------------------------------------------------------------------------------------------------------------------------
// Sales_item.cpp
#include <iostream>
#include <string>

bool Sales_item::same_isbn(const Sales_item &rhs) const
{ 
    return isbn == rhs.isbn;
}

double Sales_item::avg_price() const
{
    return revenue / units_sold;
}

void Sales_item::getTrans() const
{
    std::cout << isbn << " " << units_sold << " " << revenue << std::endl;
}

void Sales_item::setTrans(const string &new_isbn)
{
    isbn = new_isbn;
}

Exercise 7.33:Add a member that adds two Sales_items. Use the revised class to reimplement your solution to the average price problem presented in Chapter 1.

void addTrans(const Sales_item &trans)
{
    units_sold += trans.units_sold;
    revenue += trans.revenue;
}

Exercise 7.34: Define a set of overloaded functions named error that would match the following calls:

int index, upperBound;

char selectVal;

// ...

error("Subscript out of bounds: ", index, upperBound);

error("Division by zero");

error("Invalid selection", selectVal)

void error(const string &msg, int index, int upperBound);
void error(const string &msg);
void error(const string &msg, char selectVal);

Exercise 7.35: 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 );

(a) Redeclaration of calc.
(b) It is illegal, function cannot be declared only differ from return type.
(c) Overloading reset.

Exercise 7.36:What is a candidate function? What is a viable function?

A candidate function is a function with the same name as the function that is called and for which a declaration is visible at the point of the call.
A viable function is the function from the set of candidate function that can be called with arguments specified in the call.

Exercise 7.37: Given the declarations for f, determine whether the following calls are legal. For each call list the viable functions, if any. If the call is illegal, indicate whether there is no match or why the call is ambigious. If the call is legal, indicate which function is the best match.

(a) f(2.56, 42);

(b) f(42);

(c) f(42, 0);

(d) f(2.56, 3.14);

(a) It is illegal, the call is ambiguous.
(b) It is legal, f(int).
(c) It is legal, f(int, int).
(d) It is legal, f(double, double).

Exercise 7.38: Given the following declarations,

void manip(int, int);

double dobj;

what is the rank (Section 7.8.4, p. 272) of each conversion in the following calls?

(a) mainip('a', 'z'); (b) manip(55.4, dobj);

(a) 'a' to int then 'z' to int.
(b) 55.4 to int then dobj to int.

Exercise 7.39: 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);

(a) It is legal, an overload function of first.
(b) It is legal, an overload function of first.
(c) It is legal, redeclaration of first.

Exercise 7.40: Is the following function call legal? If not, why is the call in error?

enum Stat { Fail, Pass };

void test(Stat)'

test(0);

It is illegal, cannot pass an integral constant to a enumeration parameter.






原文链接: https://www.cnblogs.com/alldots/archive/2012/05/12/2497344.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/50104

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 上午1:42
下一篇 2023年2月9日 上午1:44

相关推荐