第二章
2.1一个char的空间应确保可以存放机器基本字符集中任意字符对应的数字值,也就是说一个char的大小和一个机器字节一样
2.2可寻址的最小内存块称为字节,存储的基本单元称为字
2.3一般来说,float和double分别有7和16个有效位
2.4在算术表达式中不要使用char或bool,因为char在一些机器上是有符号的,在另外一些机器上是无符号的
2.5当我们赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数
2.6当我们赋给带符号类型一个超出它表示范围的值时,结果是未定义的(undefined)
2.7当一个算术表达式中既有无符号数又有int值时,那个int值就会转换成无符号数
2.8初始化不是赋值,初始化是创建变量时赋予一个初始值,而赋值的含义是把对象的当前值擦除,用一个新值来替代
2.9当用于内置类型的变量时,如果使用列表初始化且初始值存在丢失信息的风险,编译器将会报错
2.10定义于任何函数体之外的变量被初始化为0,定义在函数体内部的内置类型变量将不被初始化(uninitialized)
2.11建议初始化每一个内置类型的变量
2.12声明使得名字为程序所知,定义则负责创建与名字关联的实体
2.13如果想声明一个变量而非定义它,就在变量名前添加extern,而且不要显式地初始化变量
2.14用户自定义的标识符中不能连续出现两个下划线,也不能以下划线紧连大写字母开头,定义在函数体外的标识符不能以下划线开头
2.15定义于for语句内的变量,块作用域的范围在for语句之内
2.16显式地访问全局变量::xxxx
2.17引用本身不是一个对象,不能定义引用的引用
2.18除了两种以外,其他所有指针的类型都要和它所指向的对象严格匹配,第一种是允许一个指向常量的指针,指向一个非常量对象
2.19空指针不指向任何对象,在试图使用一个指针之前可以首先检查它是否为空,得到空指针最直接的办法就是使用字面值nullptr来初始化指针,也可以使用一个NULL的预处理变量来给指针赋值
2.20赋值永远改变的是等号左侧的对象,所以可以轻松判断改变的是指针还是指针所指向的对象
2.21对于两个类型相同的合法指针,可以用相等操作符来判断,比较结果是bool类型,它们都为空,或者都指向同一个对象,或者都指向同一个对象的下一地址都可以令这两个指针相等
2.22void*是以一种特殊类型的指针类型,可以用于存放任意对象的地址,一个void*指针存放着一个地址,不过我们不知道该地址中到底是个什么类型的对象
2.23变量的定义包括一个基本数据类型,和一组声明符,比如*和&都属于类型修饰符
2.24从右向左阅读变量的定义,离变量名最近的符号对变量的类型有最直接的影响,int *&r,从右往左阅读可知道,r是一个引用,*不过是确定引用的类型的,*说明r引用的是一个指针,基本数据类型可以看出r引用的是一个int指针
2.25const对象一旦创建后,其值就不能再改变
2.26如果想在多个文件间共享const对象,必须在变量的定义前添加extern关键字
2.27对const的引用常常被称为常量引用,这一说法并不严谨,因为引用不是一个对象,所以我们没法让引用本身恒定不变
2.28引用的类型必须与其所引用的对象的类型一致,有两个例外,一个是在初始化常量引用时允许用任意表达式作为初始值,只要该表达式的结果能转换成引用的类型即可
2.29和常量引用一样,指向常量的指针也没有规定其所指的对象必须是一个常量,所谓指向常量的指针仅仅要求不能通过该指针来改变对象的值,而没有规定不能通过其他途径来改变
2.30用顶层const来表示指针本身是个常量,而底层const表示指针所指对象是一个常量
2.31
int i = 0;
int *const p1 = &i; //不能改变p1的值,这是一个顶层const
const int ci = 42; //不能改变ci的值,这是一个顶层const
const int *p2 = &ci; //允许改变p2的值,这是一个底层const
const int *const p3 = p2; //靠右的const是顶层const,靠左的是底层const
2.32允许将变量声明为constexpr类型以便由编译器来验证变量的值是否是一个常量表达式,声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化
2.33可以使用别名声明来定义类型的别名,using作为别名声明的开始,其后紧跟别名和等号,其作用是把等号左侧的名字规定成等号右侧类型的别名
2.34auto让编译器通过初始值来推断变量的类型,显然auto定义的变量必须有初始值
2.35类型说明符decltype的作用是选择并返回操作数的数据类型,编译器分析表达式并得到它的类型,却不实际计算表达式的值
2.36可以为数据成员提供一个类内初始值(in-class initializer),创建对象时,类内初始值将用于初始化数据成员。没有初始值的成员将被默认初始化