本系列呢,目前是我个人学习 C++ Primer 这本书的学习纪录,整本书 19 章,顺利的话这个系列大概会持续 1 个月左右,尽量每天一章那个样子吧,可能记的没什么逻辑格式等等等等,毕竟,只是个笔记,太注重格式感觉本末倒置了,尽量持续更新吧,希望不鸽。

# 1. 函数

函数的定义包含四部分:返回类型(return type)、函数名(function name)、一个括号包围的形参列表(parameter list,允许为空)以及函数体(function body)。
main 函数是比较特殊的,操作系统需要通过调用 main 来运行 C++ 程序,但它在定义上与其他函数是一样的。
main 函数的返回类型必须为 int,即整数类型。int 类型是一种内置类型(built-in type),即语言自身定义的类型。
函数定义的最后一部分是函数体,它是一个以左花括号(curly brace)开始,以右花括号结束的语句块(block of statements)

# 2. 类型

类型是程序设计最基本的概念之一,在本书中我们会反复遇到它。一种类型不仅定义了数据元素的内容,还定义了这类数据上可以进行的运算。
程序所处理的数据都保存在变量中,而每个变量都有自己的类型。如果一个名为 v 的变量的类型为 T,我们通常说 “v 具有类型 T”,或等价的,“v 是一个 T 类型变量”。

# 3. 标准输入输出

首先呢,C++ 并未定义任何输入输出语句,而是包含标准库(standard library)提供 IO 机制,例如 iostream 库。
iostream 库包含两个基础类型 istream 和 ostream,分别表示输入流和输出流。一个流就是一个字符序列,是从 IO 设备读出或写入 IO 设备的。术语 “流”(stream)想要表达的是,随着时间推移,字符是顺序生成或消耗的。
标准输入输出对象

  • cin istream 类型 标准输入
  • cout ostream 类型 标准输出
  • cerr ostream 类型 输出警告和错误信息
  • clog ostream 类型 输出程序运行时的一般性信息
#include <iostream> // 告诉编译器要使用iostream库,尖括号中的名字(iostream)是一个头文件
...
std::cin >> v1 >> v2; // 输入运算符(>>)
std::cout << "Hello World" << std::endl; // 输出运算符(<<) 字符串字面值常量/string literal("Hello World") 操纵符/manipulator(endl)
...

写入 endl 的效果是结束当前行,并将与设备关联的缓冲区(buffer)中的内容刷到设备中。缓冲刷新操作可以保证到目前为止程序所产生的所有输出都真正写入输出流中,而不是仅停留在内存中等待写入流。
而上面代码块中使用 std::cinstd::cout 而不是 cincout ,前缀 std:: 指出 cincout 是定义在名为 std 的命名空间(namespace)中的。命名空间可以帮助我们避免不经意的名字定义冲突。标准库定义的所有名字都在命名空间 std 中。
通过命名空间使用标准库导致我们想使用来自命名空间 std 中的名字必须使用 作用域运算符:: 指出我们想使用定义在命名空间 std 中的名字。当然,之后会给出更简单的方法。

# 4. 注释

C++ 中注释的种类

// 半/单行注释 
/*
* 多行注释
*/

请注意,不要嵌套多层多行注释,那会导致你的程序产生错误,请不要为难你的编译器。

# 5. 控制流

  • while

反复执行一段代码,直到给定条件为假为止。
例如

#include <iostream>
int main() {
int sum = 0, val = 1;
// 当val小于等于10时,运行大括号内部的代码
while (val <= 10) {
sum += val; //将 sum + val 赋给 sum
++val; // 将 val 加 1
}
std:cout << sum << std::endl;
return 0;
}

首先可以先想一想上面的代码块解决了什么问题。
其中,条件 /codition 对应的是 val <= 10
在代码块中我们用到了 复合赋值运算符(+=) ,即
sum += val => sum = sum + val
还用到了 前缀递增运算符(++) ,即
++val => val = val + 1

  • for

每个 for 语句都包含两部分:循环头和循环体。
循环头控制循环体的执行次数,它有三部分组成:一个初始化语句(init-statement)、一个循环条件(condition)以及一个表达式(expression)。

  • 读取数量不定的输入数据
while(std::cin >> value)

循环条件实际上检测的是 std::cin ,当我们使用一个 istream 对象作为条件时,其效果是检测流状态。如果流是有效的,即流未遇到错误,那么监测成功。当遇到文件结束符(end-of-file),或遇到一个无效输入时(例如读入的值不是一个整数),istream 对象的状态会变为无效。处于无效状态的 istream 对象会使条件变为假。

  • 键盘输入文件结束符

    • Windows
      Ctrl + Z
      Enter / Return
    • Mac OS X
      Ctrl + D
  • 再探编译
    编译器无法保证一个程序是否按照其作者的意图工作,但它可以检查形式(form)上的错误。

    • 语法错误(syntax error)
    • 类型错误(type error)
    • 声明错误(declaration error)

    错误信息通常包含一个行号和一条简短描述,描述了编译器认为的我们所犯的错误。按照报告的顺序来逐个修正错误,是一种好习惯。因为一个单个错误常常会具有传递效应,导致编译器在其后报告比实际数量多得多的错误信息。另一个好习惯是在每修正一个错误后就立即重新编译代码,或者最多是修正了一小部分明显的错误后就重新编译。这就是所谓的 “编辑 - 编译 - 调试”(edit-compile-debug)周期。

  • if

当然,if 也能像上面 while 一样将 istream 对象作为条件,不同的是,if 会执行真的但不会循环。
在 if 条件中我们常会用到相等运算符(==)用于检测两个元素的值是否相同。要注意这里不要错用 = ,在 C++ 中 = 是赋值符号,而能单独用来进行判断元素间关系。

# 6. C++ 程序的缩进和格式

对于这个问题最正确的观点就是,不存在唯一的正确风格,但是保持一致性是非常重要的。不只是自己编写代码格式的统一,也是一个团队间代码风格的统一,缩进会使得复杂的程序有更好的可读性和易理解性,而一旦选择了一种风格,就要坚持使用。

# 7. 类

类机制是 C++ 最重要的特性之一。
一个类定义了一个类型以及与其关联的一组操作。
C++ 最初的一个设计焦点就是能定义使用上像内置类型一样自然的类类型。
类定义了行为,作者定义了类对象可以执行的所有动作。一般而言,类的作者决定了类类型对象上可以使用的所有操作。
对于类,我们需要为其定义一个头文件,我们可以通过这个头文件访问自定义的类。而我们引用自定义的类的头文件时,应该用双引号("")包围。
成员函数(member function)是定义为类的一部分的函数,也称之为方法(method)。
我们通常以一个类对象的名义来调用成员函数,以点运算符(.) 来表达我们需要某对象的某成员。点运算符只能用于类类型的对象,其左侧运算对象必须是一个类类型的对象,右侧运算对象必须是该类型的一个成员名,运算结果为右侧运算对象指定的成员。
当用点运算符访问一个成员函数时,我们使用一个调用运算符(())来调用一个函数。调用运算符是一对圆括号,里面放置实参(argument)列表(可能为空)。

# 8. 文件重定向

未避免重复无意义的键盘输入测试,我们可以将标准输入和标准输出与命名文件关联起来,大多数操作系统支持这种文件重定向。

$ addItems <infile >outfile

其中, $ 是操作系统提示符, addItems.exe 是我们以编译好的可执行文件,而上述命令会将我们在 infile 文件中预先编辑好的数据读入,并将输出结果写入到 outfile 文件中。

# 9. 总结

下面会罗列一些本章节我们遇到的术语,你可以回顾一下,如果不理解你可以结合上文以及百度,或者留言我会尽力帮你理解它。如果文章中有任何错误,欢迎留言指正。

  • 参数(实参,argument)
  • 赋值(assignment)
  • 程序块(block)
  • 缓冲区(buffer)
  • 内置类型(built-in type)
  • Cerr
  • 字符串字面值常量(character string literal)
  • cin
  • 类(class)
  • 类类型(class type)
  • clog
  • 注释(comment)
  • 条件(condition)
  • cout
  • 花括号(curly brace)
  • 数据结构(data structure)
  • 编辑 - 编译 - 调试(edit-compile-debug)
  • 文件结束符(end-of-file)
  • 表达式(expression)
  • for 语句(for statement)
  • 函数(function)
  • 函数体(function body)
  • 函数名(function name)
  • 头文件(header)
  • if 语句(if statement)
  • 初始化(initialize)
  • iostream
  • istream
  • 库类型(library type)
  • main
  • 操纵符(manipulator)
  • 成员函数(member function)
  • 方法(method)
  • 命名空间(namespace)
  • ostream
  • 形参列表(parameter list)
  • 返回类型(return type)
  • 源文件(source file)
  • 标准错误(standard error)
  • 标准输入(standard input)
  • 标准库(standard library)
  • 标准输出(standard output)
  • 语句(statement)
  • std
  • 字符串常量(string literal)
  • 未初始化的变量(uninitialized variable)
  • 变量(variable)
  • while 语句(while statement)
  • () 运算符(() operator)
  • ++ 运算符(++operator)
  • += 运算符(+=operator)
  • . 运算符(.operator)
  • :: 运算符(::operator)
  • = 运算符(=operator)
  • -- 运算符(--operator)
  • << 运算符(<< operator)
  • >> 运算符(>>operator)
  • # include
  • == 运算符(==operator)
  • != 运算符(!=operator)
  • <= 运算符(<=operator)
  • < 运算符(< operator)
  • >= 运算符(>=operator)
  • > 运算符(>operator)

上面就是第一章全部内容了,后续可能读第二遍会添加新内容。