📄 c++primer
字号:
\40 空格 \0 空字符(null character) \062 '2' \115 'M' \0xA 回车符,相当于 \r 2.3. 变量2.3.1. 什么是变量 变量是程序可以操作的有名字的存储区域,变量 亦称 对象(object)。 C++ 中的每一个变量都有特定的类型,该类型决定了变量的内存大小和布局、取值范围、可应用在该变量上的操作集。 // 计算 2 的 10 次方 #include <iostream> int main() { int value = 2; // 类型为int的局部对象,即变量 int pow = 10; int result = 1; // repeat calculation of result until cnt is equal to pow for (int cnt = 0; cnt != pow; ++cnt) result *= value; // result = result * value; std::cout << value << " raised to the power of " << pow << ": \t" << result << std::endl; return 0; }2.3.2. 变量名 C++ 的关键字、保留字不能用作程序的标识符(变量名、函数名等)。 变量命名习惯 (1) 变量名一般用小写字母。例如,通常会写成 index,而不写成 Index 或 INDEX。 (2) 变量名的应该是能帮助记忆、有用途意思的名字。如 on_loan(贷款) 或 salary(薪水)。 (3) 变量名的词之间加下划线,或者词的首字母都大写。例如 student_loan 或 studentLoan,而不写成 studentloan。 (4) 命名习惯要是保持一致! C++ 关键字 asm do if return try auto double inline short typedef bool dynamic_cast int signed typeid break else long sizeof typename case enum mutable static union catch explicit namespace static_cast unsigned char export new struct using class extern operator switch virtual const false private template void const_cast float protected this volatile continue for public throw wchar_t default friend register true while delete goto reinterpret_cast C++ 操作符替代名 and bitand compl not_eq or_eq xor_eq and_eq bitor not or xor 2.3.3. 定义对象(变量) 类型决定了分配给变量的存储空间的大小和可以在其上执行的操作。 下列语句定义了 5 个变量: int units_sold; double sales_price, avg_price; std::string title; Sales_item curr_book; 多个变量可以定义在同一条语句中: double salary, wage; // 定义两个double类型的变量 int month, day, year; // 定义三个int类型的变量 std::string address; // 定义一个std::string类型的变量 已初始化变量和未初始化变量可以在同一个定义中定义: #include <string> double salary = 9999.99, wage(salary + 0.01); int interval, month = 8, day = 7, year = 1955; std::string title("C++ Primer, 4th Ed."), publisher = "A-W"; 对象可以用任意复杂的表达式(包括函数的返回值)来初始化: double price = 109.99, discount = 0.16; double sale_price = apply_discount(price, discount); C++ 支持两种初始化变量的形式:复制初始化、直接初始化 int ival(1024); // 直接初始化 int ival = 1024; // 复制初始化 对内置类型来说,复制初始化和直接初始化几乎没有差别,实际上就是直接将值复制到新定义的对象中。 对类类型的对象来说,复制初始化和直接初始化有差别,有些初始化仅能用直接初始化完成。 定义如何进行初始化的成员函数称为构造函数。和其他函数一样,构造函数能接受多个参数。 #include <string> std::string titleA = "C++ Primer, 4th Ed."; // 复制初始化 std::string titleB("C++ Primer, 4th Ed."); // 调用构造函数进行初始化 std::string all_nines(10, '9'); // 调用构造函数进行初始化,all_nines= "9999999999"2.3.4. 变量初始化规则 内置类型变量是否自动初始化取决于变量定义的位置。 在函数体外定义的变量(即全局变量)都初始化成 0,在函数体里定义的内置类型变量不进行自动初始化。 未初始化变量引起的错误难于发现。永远不要依赖未定义行为。 建议每个内置类型的对象都要初始化,除非你确定忽略初始化式不会带来风险。 如果定义类类型变量时,没有显式初始化式,就会自动调用默认构造函数。 std::string empty; // empty 变量被初始化为空字符串,相当于 empty = "" 大多数类都提供了默认构造函数。 有些类类型没有默认构造函数,没有初始值是根本不可能定义这种类型的变量的。2.3.5. 声明和定义 在 C++ 语言中,变量必须且只能定义一次,而且在使用变量之前必须定义或声明变量。 extern int i; // 引用声明,不为i分配内存;变量i应该定义在程序的其他地方(或其他文件) int j; // 定义声明,为j分配内存 extern double pi = 3.1416; // 如果声明中有初始化,就当作定义声明,而理睬 extern // 只有当 extern 声明位于函数外部时,才可以含有初始化式2.3.6. 名字的作用域 作用域是程序的一段区域。C++ 语言中,大多数作用域是用花括号来界定的。 一般来说,名字从其声明点开始直到其声明所在的作用域结束处都是可见的。 定义在所有函数外部的名字具有全局作用域,可以在程序中的任何地方访问。 C++ 中作用域可嵌套。 #include <iostream> #include <string> std::string s1 = "hello"; // s1 具有全局作用域,可用于整个程序 int main() { std::string s2 = "world"; // s2 具有局部作用域,可用于整个main()中 std::cout << s1 << " " << s2 << std::endl; // 打印出:hello world int s1 = 42; // s1 是局部变量,并隐藏了全局的s1,不建议这么用! std::cout << s1 << " " << s2 << std::endl; // 打印出:42 world return 0; } 第7章将详细讨论局部作用域和全局作用域;第6章将讨论语句作用域; 第12章将介绍类作用域,第17.2节将介绍命名空间作用域)。2.3.7. 在变量使用处定义变量 一般来说,变量的定义或声明可以放在程序中能摆放语句的任何位置。 变量在使用前必须先声明或定义。 在对象第一次被使用的地方定义对象可以提高程序的可读性。 读者不需要返回到代码段的开始位置去寻找某一特殊变量的定义,而且,更容易给它赋以有意义的初始值。2.4. const 限定语(1) 定义常量: const int bufSize = 512; // bufSize 是常量,不能修改 bufSize = 0; // 错误,因为 bufSize 是常量 const int i; // 错误,const 必须初始化常量(2) 非 const 对象默认为 extern 全局 // file_1.cc int counter; // 定义声明变量,分配内存 // file_2.cc extern int counter; // 引用声明 file_1 中的 counter 变量 ++counter; // 对 file_1 中定义的 counter 变量自增1(3) const 对象默认是文件局部的,加修饰词 extern 才表示全局 C++ 中,const 对象默认为文件局部的,其他文件不可以访问。 C 中,const 对象默认为全局的,程序的所有文件都可访问。 // file_1.cc extern const int bufSize = fcn(); // 对 const 对象加修饰词 extern,就可以在其他文件访问它了 // file_2.cc extern const int bufSize; // 引用声明 file_1 中的 bufSize 常量 //... for (int index = 0; index != bufSize; ++index) // 使用 file_1 中的 bufSize 常量 // ...2.5. 引用(Reference) 引用就是为对象(变量)的另起一个名字,主要用作函数的形式参数(第 7.2.2 中介绍)。 下面用独立的对象来介绍并举例说明引用的用法。(1) 引用必须初始化成一个对象 int ival = 1024; int &refVal = ival; // refVal 绑定 ival,refVal 与 ival 一样使用 int &refVal2; // 错误:引用必须初始化 int &refVal3 = 10; // 错误:引用必须初始化成一个对象 (2) 引用不能再绑定到别的对象 int jval = 10; &refVal = jval; // 引用不能再绑定到别的对象(3) 引用是别名 refVal = 5; // 即 ival = 5; refVal += 2; // 即 ival += 2; int ii = refVal; // 将 ival 的值赋给赋值为对象 ii(4) 定义多个引用 int i = 1024, i2 = 2048; int &r = i, r2 = i2; // r 是一个引用, r2 是一个 int 对象 int i3 = 1024, &ri = i3; // 定义一个对象, 再定义一个引用 int &r3 = i3, &r4 = i2; // 定义两个引用(5) 非 const 引用不能绑定 const 对象 const int ival = 1024; const int &refVal = ival; // 引用和对象都是 const,都不能修改值 int &ref2 = ival; // 错误,非 const 引用不能绑定 const 对象(6) 非 const 引用只能绑定到与该引用同类型的对象 double dval = 3.14 int &ri2 = dval; // 错误,非 const 引用不能绑定到不同类型的对象!(7) const 引用则可以绑定到不同但相关的类型的对象或绑定到右值(字面常量) int i = 42; const int &r = 42; // const 引用绑定到一个右值(字面常量) const int &r2 = r + i; // const 引用绑定到一个右值 double dval = 3.14; const int &ri = dval; // const 引用绑定到不同类型的对象 // 上一句被编译器转换成下面两句 int temp = dval; // 根据 double 对象创建一个临时 int 对象 const int &ri = temp; // 绑定到这个临时 int 对象2.6. typedef 名字 typedef 可以用来定义类型的同义词。 typedef double wages; // wages 是 double 的同义词 typedef int exam_score; // exam_score 是 int 的同义词 typedef wages salary; // salary 是 double 的间接的同义词 wages hourly, weekly; // 相当于 double hourly, weekly; exam_score test_result; // 相当于 int test_result; 标识符或类型名并没有引入新的类型,而只是现有数据类型的同义词。 typedef 名字可出现在程序中类型名可出现的任何位置。2.7. 枚举 经常用到一些常数值,例如 const int input = 0; const int output = 1; const int append = 2; 虽然这种方法也能奏效,但没有指出这些值是相关联的。 枚举不但定义了整数常量集,而且还把它们聚集成组。 枚举成员是常量。 // input is 0, output is 1, and append is 2 enum open_modes {input, output, append}; // shape is 1, sphere is 2, cylinder is 3, polygon is 4 enum Forms {shape = 1, sphere, cylinder, polygon}; // point2d is 2, point2w is 3, point3d is 3, point3w is 4 enum Points { point2d = 2, point2w, point3d = 3, point3w }; Points pt3d = point3d; // 正确,point3d 是 Points 枚举成员 Points pt2w = 3; // 错误,pt2w 不能初始化为 int 字面常量 pt2w = polygon; // 错误,polygon 不是 Points 枚举成员 pt2w = pt3d; // 正确,两个对象都是 Points 枚举类型 对于C,定义枚举变量时前面必须加 enum ;在C++中可以省去。2.8. 类类型 C++ 中,通过定义类来自定义数据类型。类定义了数据和对数据进行的操作。 标准库类型string、istream和ostream都定义成类。 // 用 class 定义类 class Sales_item { public: // 在这声明一些供外部使用的变量或函数,即接口 private: std::string isbn; unsigned units_sold; double revenue; }; // C++ 也可以用 struct 来定义类类型。(struct C 语言中继承过来的) struct Sales_item { // struct 默认是 public,所以不必使用 public 标记 private: std::string isbn; unsigned units_sold; double revenue; }; 访问标号 public、private 可以多次出现在类定义中。 默认情况下,struct 的成员为 public,而 class 的成员为 private。 类是 C++ 最重要特性之一,后面的章节将做更详细的解说。2.9. 编写自己的头文件2.9.1. 设计自己的头文件(1) 将程序分成独立的逻辑块,分别存放到不同文件,编译后将组成一个程序
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -