Skip to content

1. C++ Basics

:material-circle-edit-outline: 约 2310 个字 :fontawesome-solid-code: 421 行代码 :material-clock-time-two-outline: 预计阅读时间 13 分钟

This chapter explains the features, technical details and syntaxes of the C++ programming language.

To be a proficient programmer, you need to master two things:

(1) the syntax of the programming language, and

(2) the core libraries (i.e., API) associated with the language.


英文单词记录

  1. procedural-oriented 面向过程
  2. object-oriented(OO) 面向对象
  3. generic programming 泛型编程:一种计算机编程风格,其中算法是以待指定的类型编写的,当需要为特定类型提供参数时,这些类型会被实例化。
  4. STL(Standard Template Library) 标准模板库
  5. Pitfall 隐患
  6. entity 实体/统一体
  7. identifier 标识符
  8. underscore 下划线
  9. Convention 公约
  10. prudently 慎重

技巧记录

  1. it is really not meant for dummies.
  2. 这可不是给傻瓜玩的。
  3. C++ Standards
  4. 'bool valid = false;'
  5. 'bool gameOver = false;'

1. Introduction to C++

C++ is standardized as ISO/IEC 14882. Currently, there are many versions.

C++ Features

  1. C++ is C.
    1. C++ supports (almost) all the features of C.
    2. Like C, C++ allows programmers to manage the memory directly.
  2. C++ is OO.
    1. C++ enhances the procedural-oriented C language with the object-oriented extension.
  3. Template C++.
    1. C++ introduces generic programming, via the so-called template. You can apply the same algorithm to different data types.
  4. STL.
    1. C++ provides a huge set of reusable standard libraries, in particular, the Standard Template Library (STL).

C++ Strength and Pitfall

C++ is a powerful language for high-performance applications, including writing operating systems and their subsystems, games and animation.

C++ is also a complex and difficult programming language, which is really not meant for dummies.

C++ is performance centric. The C++ compiler does not issue warning/error message for many obvious programming mistakes, undefined and unspecified behaviors, such as array index out of range, using an uninitialized variable, etc, due to the focus on performance and efficiency rather than the ease of use - it assumes that those who choose to program in C++ are not dummies.

2. Basic Syntaxes

英文单词记录

  1. closing brace 后大括号
  2. semicolon 分号
  3. Token 文本中的最小单位,如 字/词/符号 等等
  4. i.e.(“that is” , "in other words")
  5. semi-colon (;) 分号
  6. period(.) 句号
  7. decimal point (.) 小数点
  8. contiguous 连续的
  9. Indentation 缩进

技巧记录

  1. Use comments liberally.
  2. Use extra whitespaces and newlines liberally.

2.1 Revision

std

The names cout and endl belong to the std namespace.

They can be referenced via fully qualified name std::cout and std::endl, or simply as cout and endl with a "using namespace std;" statement.

return 0

C++ compiler will automatically insert a "return 0;" at the end of the the main() function, thus, it statement can be omitted.

Instead of using numeric value of zero and non-zero, you can also use EXIT_SUCCESS or EXIT_FAILURE, which is defined in the cstdlib header (i.e., you need to "#include <cstdlib>".

2.3 Statements and Blocks

Statement

A programming statement is the smallest independent unit in a program.

It performs a piece of programming action.

Why not ends with a period like an english sentence?

This is because period crashes with decimal point - it is hard for the dumb computer to differentiate between period and decimal point!

Block

A block (or a compound statement) is a group of statements surrounded by braces { }.

All the statements inside the block is treated as one unit.

Blocks are used as the body in constructs like function, if-else and loop, which may contain multiple statements but are treated as one unit.

There is no need to put a semi-colon after the closing brace to end a complex statement.

Empty block (without any statement) is permitted.

2.4 White Spaces and Formatting Source Codes

White Spaces

Blank, tab and new-line are collectively called white spaces.

C++, like most of the computing languages, ignores extra white spaces. That is, multiple contiguous white spaces are treated as a single white space.

3. Variables and Types

英文单词记录

  1. LHS left-hand-side
  2. rvalue right-value
  3. intuitive 直觉的

3.2 Identifiers

An identifier is needed to name a variable (or any other entity such as a function or a class).

Identifiers beginning with an underscore are typically reserved for system use.

Variable Naming Convention

The first word is in lowercase, while the remaining words are initial-capitalized, with no spaces between words.

his convention is also known as camel-case.(骆驼式命名法)

Recommendations

  1. Do NOT use meaningless names like a, b, c, d, i, j, k, i1, j99.
  2. Avoid single-alphabet names, which is easier to type but often meaningless, unless they are common names like x, y, z for coordinates, i for index.
  3. It is perfectly okay to use long names of says 30 characters to make sure that the name accurately reflects its meaning!
  4. Use singular and plural nouns prudently to differentiate between singular and plural variables.

3.3 Variable Declaration

C++ is a "strongly-type" language. A variable takes on only one type. Once the type of a variable is declared, it can only store a value belonging to this particular type.

The concept of type was introduced into the early programming languages to simplify interpretation of data made up of 0s and 1s. Knowing the type of a piece of data greatly simplifies its interpretation and processing.

It is recommended that your declare a variable just before it is first used.

declare vs initialize

surely.

Uninitialized Variables

When a variable is declared, it contains garbage until you assign an initial value. It is important to take note that C/C++ does not issue any warning/error if you use a variable before initialize it - which certainly leads to some unexpected results.

3.4 Constants (const)

const must be initialized during declaration

Constant Naming Convention

Use uppercase words, joined with underscore. For example, MIN_VALUE, MAX_SIZE.

3.6 Assignment (=)

The symbol "=" is known as the assignment operator.

It denotes assignment instead of equality.

3.7 Fundamental Types

Integers

char, short, int, long, long long in a non-decreasing order of size.

The actual size depends on the implementation.

Characters

char could be signed or unsigned, depending on the implementation

You can use signed char or unsigned char to explicitly declare signed or unsigned char.

Floating-point Numbers

float, double and long double, for single, double and long double precision floating point numbers.

A float can represent a number between ±1.40239846×10^-45 and ±3.40282347×10^38, approximated. A double can represented a number between ±4.94065645841246544×10^-324 and ±1.79769313486231570×10^308, approximated.

Take note that not all real numbers can be represented by float and double, because there are infinite real numbers. Most of the values are approximated.

Boolean Numbers

A special type called bool (for boolean), which takes a value of either true or false.

In addition, many C++ library functions use a type called size_t, which is equivalent (typedef) to a unsigned int, meant for counting, size or length, with 0 and positive integers.

image-20240224222027980

*The sizeof Operator

sizeof(char) is 1 bytes
sizeof(short) is 2 bytes
sizeof(int) is 4 bytes
sizeof(long) is 4 bytes
sizeof(long long) is 8 bytes
sizeof(float) is 4 bytes
sizeof(double) is 8 bytes
sizeof(long double) is 12 bytes
sizeof(bool) is 1 bytes

The results may vary among different systems.

The climits header (ported to C++ from C's limits.h) contains information about limits of integer type. For example,

/* Test integer limits in <climits> header */
#include <iostream>
#include <climits>   // integer limits
using namespace std;

int main() {
   cout << "int max = " << INT_MAX << endl;
   cout << "int min = " << INT_MIN << endl;
   cout << "unsigned int max = " << UINT_MAX << endl;
   cout << "long long max = " << LLONG_MAX << endl;
   cout << "long long min = " << LLONG_MIN << endl;
   cout << "unsigned long long max = " << ULLONG_MAX << endl;
   cout << "Bits in char = " << CHAR_BIT << endl;
   cout << "char max = " << CHAR_MAX << endl;
   cout << "char min = " << CHAR_MIN << endl;
   cout << "signed char max = " << SCHAR_MAX << endl;
   cout << "signed char min = " << SCHAR_MIN << endl;
   cout << "unsigned char max = " << UCHAR_MAX << endl;
   return 0;
}
int max = 2147483647
int min = -2147483648
unsigned int max = 4294967295
long long max = 9223372036854775807
long long min = -9223372036854775808
unsigned long long max = 18446744073709551615
Bits in char = 8
char max = 127
char min = -128
signed char max = 127
signed char min = -128
unsigned char max = 255

Again, the outputs depend on the system.

Header <cfloat>Similarly.

Header <limits> The climits and cfloat headers are ported over from C's limit.h and float.h. C++ added a new header called limits.

*The typedef Statement

Many C/C++ compilers define a type called size_t, which is a typedef of unsigned int.

typedef unsigned int size_t;

4.7 Implicit Type-Conversion vs. Explicit Type-Casting

Converting a value from one type to another type is called type casting (or type conversion). There are two kinds of type casting:

  1. Implicit type-conversion performed by the compiler automatically,
  2. Explicit type-casting via an unary type-casting operator in the form of (*new-type*)*operand* or *new-type*(*operand*).

C++ will not perform automatic type conversion, if the two types are not compatible.

注意不是四舍五入,而是截断

Operator static-cast<type>

C++ introduces a new operator called static_cast<*type*> to perform type conversion (because the regular cast mentioned earlier is too lax and could produce expected results). static_cast

signal an error if conversion fails. For example,

double d = 5.5;
int i = static_cast<int>(d);
float f = static_cast<float>(i);
long l = static_cast<logn>(d);

5.5 Terminating Program

exit()

You could invoke the function exit(int exitCode), in <cstdlib> (ported from C's "stdlib.h"), to terminate the program and return the control to the Operating System. By convention, return code of zero indicates normal termination; while a non-zero exitCode (-1) indicates abnormal termination. For example,

abort()

The header <cstdlib> also provide a function called abort(), which can be used to terminate the program abnormally.

The "return" Statement

You could also use a "return *returnValue*" statement in the main() function to terminate the program and return control back to the Operating System. For example,

if (errorCount > 10) {
   cout << "too many errors" << endl;
   exit(-1);  // Terminate the program
              // OR abort();
              //return -1;  // Terminate and return control to OS from main()
                            //终止并将控制权从main()返回给操作系统
}

5.7 Dangling else

if (i == 0)
   if (j == 0)
      cout << "i and j are zero" << endl;
else cout << "i is not zero" << endl;   // intend for the outer-if

The else clause in the above codes is syntactically applicable to both the outer-if and the inner-if. The C++ compiler always associate the else clause with the innermost if (i.e., the nearest if).

7. Strings

C++ supports two types of strings:

  1. the original C-style string: A string is a char array, terminated with a NULL character '\0' (Hex 0). It is also called Character-String or C-style string.
  2. the new string class introduced in C++98.

The "high-level" string class is recommended, because it is much easier to use and understood. However, many legacy programs used C-strings; many programmers also use "low-level" C-strings for full control and efficiency; furthermore, in some situation such as command-line arguments, only C-strings are supported.

Hence, you may have to understand both sets of strings. However, avoid C-string unless it is absolutely necessary.

7.1 String Declaration and Initialization

To use the string class, include the <string> header and "using namespace std".

#include <string>
using namespace std;

string str1("Hello");  // Initialize with a string literal (Implicit initialization)
string str2 = "world"; // Initialize with a string literal (Explicit initialization via assignment operator)
string str3;           // Initialize to an empty string
string str4(str1);     // Initialize by copying from an existing string object

7.2 String Input/Output

  • We need to "#include <string>" to use the string class, and "using namespace std" as string is defined under std namespace.
  • "cin >> *aStr*" reads a word (delimited by space) from cin (keyboard), and assigns to string variable *aStr*.
  • getline(cin, *aStr*) reads the entire line (up to '\n') from cin, and assigns to *aStr*. The '\n' character is discarded.
  • To flush cin, you could use ignore(numeric_limits<streamsize>::max(), '\n') function to discard all the characters up to '\n'. numeric_limits is in the <limits> header.

7.3 String Operations

调用形式得先调用对象,用.连接,如str1.function()

  • Checking the length of a string:

    int length();
    int size();
    //   both of them return the length of the string
    
    #include <string>
    string str("Hello, world");
    cout << str.length() << endl;  // 12
    cout << str.size()   << endl;  // 12
    
  • Check for empty string:

    bool empty();
    //   Check if the string is empty.
    
    string str1("Hello, world");
    string str2;                   // Empty string
    cout << str1.empty() << endl;  // 0 (false)
    cout << str2.empty() << endl;  // 1 (true)
    
  • Copying from another string: Simply use the assignment (=) operator.

    string str1("Hello, world"), str2;
    str2 = str1;
    cout << str2 << endl;   // Hello, world
    
  • Concatenated with another string: Use the plus (+) operator, or compound plus (+=) operator.

    string str1("Hello,");
    string str2(" world");
    cout << str1 + str2 << endl;  // "Hello, world"
    cout << str1 << endl;         // "Hello,"
    cout << str2 << endl;         // " world"
    str1 += str2;
    cout << str1 << endl;  // "Hello, world"
    cout << str2 << endl;  // " world"
    string str3 = str1 + str2;
    cout << str3 << endl;  // "Hello, world world"
    str3 += "again";
    cout << str3 << endl;  // "Hello, world worldagain"
    
  • Read/Write individual character of a string:

    char& at(int index);
    //   Return the char at index, index begin at 0. Perform index bound check.
    
    []
    //   indexing (subscript) operator, no index bound check
    
    string str("Hello, world");
    cout << str.at(0) << endl;  // 'H'
    cout << str[1] << endl;     // 'e'
    cout << str.at(str.length() - 1) << endl;  // 'd'
    
    str.at(1) = 'a';  // Write to index 1
    cout << str << endl;  // "Hallo, world"
    
    str[0] = 'h';
    cout << str << endl;  // "hallo, world"
    
  • Extracting sub-string:

    string substr(int beginIndex, int size);
    //   Return the sub-string starting at beginIndex, of size
    
    string str("Hello, world");
    cout << str.substr(2, 6) << endl;  // "llo, w"
    
  • Comparing with another string:

    int compare(string another);
    //   Compare the content of this string with the given another. 
    //   Return 0 if equals; a negative value if this string is less than another; positive value otherwise.
    
    == and != Operators
    //   Compare the contents of two strings
    
    string str1("Hello"), str2("Hallo"), str3("hello"), str4("Hello");
    cout << str1.compare(str2) << endl;   // 1   'e' > 'a'
    cout << str1.compare(str3) << endl;   // -1  'h' < 'H'
    cout << str1.compare(str4) << endl;   // 0
    
    // You can also use the operator == or !=
    if (str1 == str2) cout << "Same" << endl;
    if (str3 != str4) cout << "Different" << endl;
    cout << boolalpha;  // print bool as true/false
    cout << (str1 != str2) << endl;
    cout << (str1 == str4) << endl;
    
  • Search/Replacing characters:

    #include <algorithm>
    ......
    string str("Hello, world");
    replace(str.begin(), str.end(), 'l', '_');
    cout << str << endl;      // "He__o, wor_d"
    
  • Many others.
/* Example on C++ string function (TestStringOp.cpp) */
#include <iostream>
#include <string>    // use string class
using namespace std;

int main() {
   string msg = "hello, world!";
   cout << msg << endl;
   cout << msg.length() << endl;  // length of string
   cout << msg.at(1) << endl;     // char at index 1
   cout << msg[1] << endl;        // same as above
   cout << msg.empty() << endl;   // test for empty string
   cout << msg.substr(3, 3) << endl; // sub-string begins at
                                     // pos 3 of size 3
   cout << msg.replace(3, 3, "why") << endl; // replace sub-string
   cout << msg.append("end") << endl;        // append behind
   cout << msg + "end" << endl;              // same as above
   cout << msg.insert(3, "insert") << endl;  // insert after pos 3

   string msg1;
   msg1 = msg;   // copy
   cout << msg1 << endl;

   cout << "Enter a line: ";
   getline(cin, msg);   // read a line of input
   cout << msg << endl;
}

8. Formatting Input/Output using IO Manipulators (Header <iomanip>)

8.1 Output Formatting

/* Test Formatting Output (TestFormattedOutput.cpp) */
#include <iostream>
#include <iomanip>    // Needed to do formatted I/O
using namespace std;

int main() {
   // Floating point numbers
   double pi = 3.14159265;
   cout << fixed << setprecision(4); // fixed format with 4 decimal places
   cout << pi << endl;
   cout << "|" << setw(8) << pi << "|" << setw(10) << pi << "|" << endl;
      // setw() is not sticky, only apply to the next operation.
   cout << setfill('-');
   cout << "|" << setw(8) << pi << "|" << setw(10) << pi << "|" << endl;
   cout << scientific;  // in scientific format with exponent
   cout << pi << endl;

   // booleans
   bool done = false;
   cout << done << endl;  // print 0 (for false) or 1 (for true)
   cout << boolalpha;     // print true or false
   cout << done << endl;
   return 0;
}

8.2 Input Formatting

cp/* Test Formatting Input (TestFormattedInput.cpp) */
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;

int main() {
   string areaCode, phoneCode;
   string inStr;

   cout << "Enter your phone number in this format (xxx)xxx-xxxx : ";
   cin.ignore();   // skip '('
   cin >> setw(3) >> areaCode;
   cin.ignore();   // skip ')'
   cin >> setw(3) >> phoneCode;
   cin.ignore();   // skip '-'
   cin >> setw(4) >> inStr;
   phoneCode += inStr;

   cout << "Phone number is (" << areaCode << ")"
        << phoneCode.substr(0, 3) << "-"
        << phoneCode.substr(3, 4) << endl;
   return 0;
}

9. Arrays

9.1 Array Declaration and Usage

int main() {
   int const SIZE = 5;

   int a1[SIZE];   // Uninitialized
   for (int i = 0; i < SIZE; ++i) cout << a1[i] << " ";
   cout << endl;   // ? ? ? ? ?

   int a2[SIZE] = {21, 22, 23, 24, 25}; // All elements initialized
   for (int i = 0; i < SIZE; ++i) cout << a2[i] << " ";
   cout << endl;   // 21 22 23 24 25

   int a3[] = {31, 32, 33, 34, 35};   // Size deduced from init values
   int a3Size = sizeof(a3)/sizeof(int);
   cout << "Size is " << a3Size << endl;   // 5
   for (int i = 0; i < a3Size; ++i) cout << a3[i] << " ";
   cout << endl;   // 31 32 33 34 35

   int a4[SIZE] = {41, 42};  // Leading elements initialized, the rests to 0
   for (int i = 0; i < SIZE; ++i) cout << a4[i] << " ";
   cout << endl;   // 41 42 0 0 0

   int a5[SIZE] = {0};  // First elements to 0, the rests to 0 too
   for (int i = 0; i < SIZE; ++i) cout << a5[i] << " ";
   cout << endl;   // 0 0 0 0 0

   int a6[SIZE] = {};   // All elements to 0 too
   for (int i = 0; i < SIZE; ++i) cout << a6[i] << " ";
   cout << endl;   // 0 0 0 0 0
}

C/C++ does not perform array index-bound check. In other words, if the index is beyond the array's bounds, it does not issue a warning/error. For example,

const int size = 5;
int numbers[size];  // array index from 0 to 4

// Index out of bound!
// Can compiled and run, but could pose very serious side effect!
numbers[88] = 999;
cout << numbers[77] << endl;

9.3 Range-based for loop (C++11)

/* Testing For-each loop (TestForEach.cpp) */
#include <iostream>
using namespace std;

int main() {
   int numbers[] = {11, 22, 33, 44, 55};

   // For each member called number of array numbers - read only 
   for (int number : numbers) {
      cout << number << endl;
   }

   // To modify members, need to use reference (&)
   for (int &number : numbers) {
      number = 99;
   }

   for (int number : numbers) {
      cout << number << endl;
   }
   return 0;
}

9.5 Array of Characters - C-String

/* Test C-string (TestCString.cpp) */
#include <iostream>
using namespace std;

int main() {
   char msg[256]; // Hold a string of up to 255 characters (terminated by '\0')

   cout << "Enter a message (with space)" << endl;
   cin.getline(msg, 256);  // Read up to 255 characters into msg
   cout << msg << endl;

   // Access via null-terminated character array
   for (int i = 0; msg[i] != '\0'; ++i) {
      cout << msg[i];
   }
   cout << endl;

   cout << "Enter a word (without space)" << endl;
   cin >> msg;
   cout << msg << endl;

   // Access via null-terminated character array
   for (int i = 0; msg[i] != '\0'; ++i) {
      cout << msg[i];
   }
   cout << endl;
   return 0;
}

10.3 Default Arguments

C++ introduces so-called default arguments for functions. These default values would be used if the caller omits the corresponding actual argument in calling the function.

/* Test Function default arguments (functionDefaultArgument.cpp) */
#include <iostream>
using namespace std;

// Function prototype - Specify the default arguments here
int fun1(int = 1, int = 2, int = 3);
int fun2(int, int, int = 3);

int main() {
   cout << fun1(4, 5, 6) << endl; // No default
   cout << fun1(4, 5) << endl;    // 4, 5, 3(default)
   cout << fun1(4) << endl;       // 4, 2(default), 3(default)
   cout << fun1() << endl;        // 1(default), 2(default), 3(default)

   cout << fun2(4, 5, 6) << endl; // No default
   cout << fun2(4, 5) << endl;    // 4, 5, 3(default)
// cout << fun2(4) << endl;
      // error: too few arguments to function 'int fun2(int, int, int)'
}

int fun1(int n1, int n2, int n3) {
      // cannot repeat default arguments in function definition
   return n1 + n2 + n3;
}

int fun2(int n1, int n2, int n3) {
   return n1 + n2 + n3;
}

10.4 Function Overloading

C++ introduces function overloading (or function polymorphism, which means many forms), which allows you to have multiple versions of the same function name, differentiated by the parameter list (number, type or order of parameters).

The version matches the caller's argument list will be selected for execution.

Overloaded functions cannot be differentiated by the return-type (compilation error).

/* Test Function Overloading (FunctionOverloading.cpp) */
#include <iostream>
using namespace std;

void fun(int, int, int);  // Version 1
void fun(double, int);          // Version 2
void fun(int, double);          // Version 3

int main() {
   fun(1, 2, 3);   // version 1
   fun(1.0, 2);    // version 2
   fun(1, 2.0);    // version 3
   fun(1.1, 2, 3); // version 1 - double 1.1 casted to int 1 (without warning)

   // fun(1, 2, 3, 4);
      // error: no matching function for call to 'fun(int, int, int, int)'
   // fun(1, 2);
      // error: call of overloaded 'fun(int, int)' is ambiguous
      // note: candidates are:
      //    void fun(double, int)
      //    void fun(int, double)
   // fun(1.0, 2.0);
      // error: call of overloaded 'fun(double, double)' is ambiguous
}

void fun(int n1, int n2, int n3) {  // version 1
   cout << "version 1" << endl;
}

void fun(double n1, int n2) { // version 2
   cout << "version 2" << endl;
}

void fun(int n1, double n2) { // version 3
   cout << "version 3" << endl;
}

C/C++ does not allow functions to return an array.

10.10 Generating Random Numbers

The cstdlib header (ported from C's stdlib.h) provides a function rand(), which generates a pseudo-random integral number between 0 and RAND_MAX (inclusive).

RAND_MAX is a constant defined in cstdlib (typically the maximum value of 16-/32-bit signed integer, such as 32767).

You can generate a random number between [0,n) via rand() % n.

rand() generates the same squence of pseudo-random numbers on different invocations.

The cstblib also provides a srand() function to seed or initialize the random number generator. We typically seed it with the current time obtained via time(0) function (in <ctime> header), which returns the number of seconds since January 1st, 1970.

一个神奇的指针传参方式↓

#include <iostream>
using namespace std;

void squareByReference (int & number); // Pass-by-reference

int main() {
   int n2 = 9;
   squareByReference(n2);  // side-effect
}

void squareByReference (int & number) {
   number = number * number;
}

11. File Input/Output (Header )

The <fstream> header provides ifstream (input file stream) and ofstream (output file stream) for file input and output. The steps for file input/output are:

  1. Create a ifstream for input, or ofstream for output.
  2. Connect the stream to an input or output file via open(*filename*).
  3. Perform formatted output via stream insertion operator <<, or input via stream extraction operator >>, similar to cout << and cin >>.
  4. Close the file and free the stream.
/* Test File I/O (TestFileIO.cpp)
   Read all the integers from an input file and
   write the average to an output file        */
#include <iostream>
#include <fstream>   // file stream
#include <cstdlib>
using namespace std;

int main() {
   ifstream fin;   // Input stream
   ofstream fout;  // Output stream

   // Try opening the input file
   fin.open("in.txt");
   if (!fin.is_open()) {
      cerr << "error: open input file failed" << endl;
      abort();  // Abnormally terminate the program (in <cstdlib>)
   }

   int sum = 0, number, count = 0;
   while (!(fin.eof())) {
      // Use >> to read
      fin >> number;
      sum += number;
      ++count;
   }
   double average = double(sum) / count;
   cout << "Count = " << count << " average = " << average << endl;
   fin.close();

   // Try opening the output file
   fout.open("out.txt");
   if (!fout.is_open()) {
      cerr << "error: open output file failed" << endl;
      abort();
   }
   // Write the average to the output file using <<
   fout << average;
   fout.close();
   return 0;
}

12. Namespace

all the identifiers in the C++ standard libraries (such as cout, endl and string) are placed under the namespace called std.

To reference an identifier under a namespace, you have three options:

  1. Use the fully qualified names, such as std::cout, std::endl, std::setw() and std::string. For example,
std::cout << std::setw(6) << 1234 << std::endl;

Missing the "std::" results in "error: 'xxx' was not declared in this scope".

  1. Use a using declaration to declare the particular identifiers. For example,
using std::cout;
using std::endl;
......
cout << std::setw(6) << 1234 << endl;

You can omit the "std::" for cout and endl, but you still have to use "std::" for setw.

  1. Use a using namespace directive. For example,
using namespace std;
......
cout << setw(6) << 1234 << endl;

The using namespace directive effectively brings all the identifiers from the specified namespace to the global scope, as if they are available globally. You can reference them without the scope resolution operator. Take note that the using namespace directive may result in name crashes with identifier in the global scope.

  1. For long namespace name, you could define a shorthand (or alias) to the namespace, as follows:
namespace shorthand = namespace-name;

You can now refer to your class as *shorthand*::*entityName*.

这语句还可以放在函数内以限制作用域