Argument Passing by Value or Reference


#include 
// To read from the standard input, we write std::cin. These names use the 
// scope operatro(::), which says that the compiler should look in the scop
// of the left-hand operand for the name of the right-hand operand. Thus, 
// std::cin says that we want to use the name string from the namespace std.
// Referring to library names with this notation can be cumbersome. 
// Fortunately, there are easier ways to use namespace members. The safest
// way is a **using declaration.**
// A using declaration lets us use a name from a namespace without 
// qualifying the name with a namespace_name::prefix. A using declaration 
// has the form 
// using namespace::name:
// Once the using declaration has been made, we can access name directly:
// #include 
// uisng std::cin;
// int main()
// {
//     int i;
//     cin >> i;  // ok: cin is a synonym for std::cin
//     cout << i; // error: no using declaration; we must use the full name
//     std::cout << i; // ok: explicitly use cout from namespace std
//     return 0;
// }
using std::cout;
using std::endl;

// A string is a variable-length sequence of characters. To use the string
// type, we must include the string header. Because it is part of the 
// library, string is defined in the std namespace. Our example assume the
// following code:
#include 
using std::string; 

// Passing arguments by value
void reset_passed_by_value(int *ip)
{
    *ip = 0; // changes the value of the object to which ip points
    ip = 0;  // changes only the local copy of ip; the argument is unchanged
}

// Programmers accustomed to programming in C often use pointer parameters
// to access objects outside a function. In C++, programmers generally use
// reference parameers instead.

// Passing argumens by reference
void reset_passed_by_reference(int &i)
{
    i = 0;
}

// Reference paramters that are not changed inside a function should be 
// reference to const.
//
// compare the length of two strings
bool isShorter(const string &s1, const string &s2)
{
    return s1.size() < s2.size();
}

// Using reference parameters to return additional information

// returns the index of the first occurrence of c in s
// the reference parameter occurs counts how often c occurs
string::size_type find_char(const string &s, char c,
        string::size_type &occurs)
{
    // size_type Name of types defined by the string and vector classes 
    // that are capable of containing the size of any string or vector,
    // respectively. Library classes that define size_type define it as
    // an unsigned type.

    // It is not uncommon to want to store the value of an expression in
    // a variable. To declare the variable, we have to know the type of 
    // that expression. When we write a program, it can be surprisingly
    // difficult -- and sometimes even impossible -- to determine the 
    // type of an expression. Under the new standard, we can let the 
    // compiler figure out the type for us by using the auto type specifier.
    // Unlike type specifiers, such as double, that name a specific type, 
    // auto tells the compiler to deduce the type from the initializer. By
    // implication, a variable that uses auto as its type specifier mush
    // have an initializer:
    // the type of item is deduced from the type of the result of adding 
    // val1 and val2
    // auto item = val1 + val2; // item initialized to the result of val1 + val2
    auto ret = s.size();    // position of the first occurrence, if any
    occurs = 0;             // set the occurrence count parameter

    // Sometimes we want to define a variable with a type that the compiler
    // deduces from an expression but do not want to use that expression to
    // initialize the variable. For such cases, the new standard introduced
    // a second type specifier, decltype, which returns the type of its 
    // operand. The compiler analyzes the expression to determine its type
    // but does not evaluate the expression:
    // decltype(f()) sum = x; // sum has whatever type f returns
    for (decltype(ret) i = 0; i != s.size(); ++i) {
        if (s[i] == c) {
            if (ret == s.size())
                ret = i;    // remember the first occurrence of c
            ++occurs;       // increment the occurrence count parameter
        }
    }
    return ret;             // count is returned implicitly in occurs
}

int main(void)
{
    int i = 42;
    int j = 42;
    string::size_type ctr = 0;

    cout << "before reset i = " << i << endl;
    reset_passed_by_value(&i);    // changes i but not the address of i
    cout << "i = " << i << endl;  // prints i = 0

    cout << "before reset j = " << j << endl;
    reset_passed_by_reference(j); // j is passed by reference; the value in j is changed
    cout << "j = " << j << endl; // prints j = 0

    // When we supply a string literal, the characters from the literal-up
    // to but not including the null character at the end of the literal--
    // are copied into the newly created string.
    string s1 = "hello, world!";    // s1 is a copy of the string literal

    string s2("hello, world!");  // direct initialization
    string s3(10,'c'); // s3 is cccccccccc direct initialization
    string s4 = s3;    // s4 is a copy of s3
    auto index = find_char(s2, 'o', ctr);
    cout << "index = " << index <<", occurs = " << ctr << endl;

    return 0;
}

posted @ 2022-04-05 23:32  enjoy_jun  阅读(33)  评论(0编辑  收藏  举报