#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;
}