第一章
1.1 :编写一个简单的c++程序
- main函数的返回类型必须为int, 即整数类型。
- 大多数系统中,main的返回值被用来指示状态。返回值0表示成功,非0的返回值的含义由系统定义,通常用来指出错误类型。
- 编译器通常都包含一些选项,能对有问题的程序结构发出警告。打开这些选项通常是一个好的习惯。我们习惯在GNU编译器中使用-wall选项, 在微软编译器中使用/w4
1.2: 初始输入输出
- iostream包括istream和ostream, 输入流和输出流
- 标准库定义了4个IO对象,cin, cout, cerr, clog
- 写入std::endl的效果是结束当前行,并将与设备关联的缓冲区中的内容刷到设备中
1.3: 注释简介
- 错误的注释比完全没有更糟糕
- 注释界定符不能嵌套
1.4: 控制流
1.5: 类定义
大部分操作系统都支持文件重定向
第二章
2.1: 基本内置类型
- long long 数据类型为c++11中新定义的
- 字符类型分为:char、unsigned char、signed char三种类型,char类型实际上会表现为signed char或unsigned char两种类型中的一种,具体是那一种由编译器决定
- 当明确知晓数值不可能为负时,选用无符号类型
- 在算术表达式(arithmetic expression)中不要使用char或bool, 只有在存放字符或布尔值时才使用它们,因为类型char在一些机器上是有符号的,而在另一些机器上是无符号的,所以使用char进行运算特别容易出问题。如果你需要使用一个不大的整数,那么明确指定它的类型是signed char或者unsigned char
- 执行浮点运算选用dobule, 这是因为float通常精度不够而且双精度浮点数和单精度浮点数的计算代价相差无几。事实上,对于某些机器来说,双精度运算甚至比单精度还快
- 赋值(assignment)给无符号类型(unsigned type)一个超出范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数。例如unsigned char表示的范围是0~255,就应该对256取余。
- 赋值(assignment)给带符号类型(signed type)一个超出范围的数值时,结果是未定义的(undefined)
- 不要将有符号类型(signed type)和无符号类型(unsigned type)放在同一表达式中混用,有符号类型(signed type)会自动转成无符号类型(unsigned type),可能会出现意想不到的结果
- 默认情况下,十进制字面值是带符号数,八进制和十六进制字面值可能是带符号的也可能是无符号的。
- 十进制字面值的类型是int、long、long long中尺寸最小的那个,前提是这种类型要能容纳下当前值。
- 八进制和十六进制字面值的类型是能容纳其数值的int、unsigned int、long、unsigned long、long long和unsigned long long中尺寸最小者
- 如果一个字面值连与之关联的最大数据类型都放不下,将产生错误。short没有对应的字面值
- 整型字面值不会是负数。如果使用了 -42的十进制字面值,那个负号并不在字面值之内,它的作用仅仅是对字面值取负而已。
- 默认的浮点型字面值是一个double
- 泛化的转义序列,其形式是x后紧跟1个或多个十六进制数字,或者后紧跟1个、2个或3个八进制数字,其中数字部分表示的是字符对应的数值
- 如果反斜线后面跟着的八进制数字超过3个,只有前3个数字与构成转义序列,例如1234表示 123和字符4
- 如果x后面跟了多个十六进制数字,所有十六进制数据都将一起构成转义字符,如果超出了范围则可能会报错
- 可以通过加前缀或后缀来改变字面值的类型
- 指针的字面值是nullptr
2.2: 变量(variable)
- 初始化(initialized)不是赋值(assignment),初始化(initialized)的含义是创建变量(variable)时赋予其一个初始值,而赋值(assignment)的含义是把对象(object)的当前值擦除,而以一个新值来替代
- C++11中新增了用花括号(curly brace)来初始化(initialized)变量得到了全面应用,这种初始化(initialized)的形式被称为列表初始化(list initialization)
- 定义(definition)于任何函数体之外的内置变量默认初始化(default initialized)为0
- 定义(definition)于函数体内的内置类型的对象(object)如果没有初始化(uninitialized),则其值是未定义(undefinition)。类的对象如果没有显式地初始化,则其值(value)由类(class)确定
- 建议初始化(initialized)每一个内置类型(built-in type)的变量(variable)。虽然并非必须这么做,但如果我们不能确保未初始化(undefinition)后程序的安全,那么这么做不失为一种简单可靠的方法
- 变量(variable)可以多次声明(declaration),但只能定义(definition)一次
- 在函数体内部,如果试图初始化(initialized)一个由extern关键字标记的变量(variable),将引发错误
2.3: 复合类型(compound type)
- 因为引用(reference)是依靠绑定(bind)实际对象(object)而存在的,所以引用(reference)必须初始化(initialized)。
- 因为引用(reference)本身不是一个对象(object),所以不能定义(definition)引用(reference)的引用(reference)。
- 引用(reference)只能绑定(bind)在对象(object)上,而不能与字面值(literal)或某个表达式(expression)的计算结果绑定(bind)在一起. 但是请注意,常引用却可以绑定字面值和表达式。事实上是绑定到了临时量上面,常引用不会引起临时量改变,而普通引用却可以引起临时量改变导致引用与实际对像值不同,所以是非法的。
- 因为引用(reference)不是对象(object),没有实际地址(address),所以不能定义(definition)指向(point to)引用(reference)的指针(pointer)
- 指向指针的引用,引用本身不是一个对象,因此不能定义指向引用的指针。但指针是对象,所以存在对指针的引用:int *p, *&r = p; 其中r就是一个指向指针的引用;面对这种复杂类型时,最简单的办法是从右向左阅读r的定义,离变量名最近的符号(此例中是&r的符号&)对变量的类型有最直接的影响,因此r是一个引用。
2.4:const限定符
- const对象一旦创建后其值就不能再改变,所以const对象必须初始化
- 编译器在编译过程中把所有用到const变量的地方,都用const初始值进行替换,如果程序包含多个文件,则每个用了const对象的文件都必须得能访问到它的初始值才行,要做到这一点,就必须在每一个用到变量的文件中都有对它的定义,为了支持这一用法,同时避免对同一变量的重复定义,默认情况下,const对象被设定为仅在文件内有交。当多个文件中出现了同名的const变量时,其实等同于在不同文件中分别定义了独立的变量。
- 某些时候有这样一种const变量,它的初始值不是一个常量表达式,但又确实有必要在文件间共享。这种情况下,我们不希望编译器为每个文件分别生成独立的变量。相反,我们想让这类const对象像其它对象一样工作,也就是说,只在一个文件中定义const,而在其他多个文件中声明并使用它,解决的办法是,对于const变量不管是声明还是定义都添加extern关键字,这样只需定义一次就可以了
- const与引用,看2.3引用