第二章 变量和基本类型
2.1 基本内置类型
- 赋给无符号类型一个超出其表示范围的值时,其值为初始值对该无符号类型示数总数值取模后的余数。而赋给带符号类型一个超出其表示范围的值时,其结果为未定义的。
- 无符号数永远不会小于0。
2.2 变量
- 定义于函数体内的内置类型的对象如果没有初始化,则其值未定义,若定义于函数体外,怎会被默认初始化为 0 。类的对象如果没有显式地初始化,则其值由类确定。
- 声明只是规定了变量的类型和名字。定义除此以外还申请存储空间,同时同事有可能为变量赋初值。变量能且只能被定义一次,但可以被多次声明。
- 在一个函数内,可以定义与某一全局变量同名的局部变量,并在其作用域范围内覆盖原全局变量。这时可以使用::(作用域操作符)来应用原来的全局变量,因为当作用域操作符的左侧为空时,向全局作用域请求对应的变量。
2.3 复合类型
- 引用即别名。必须初始化,且无法使引用重绑。
- 引用本身不是一个对象,无法定义引用的引用。
- 不能直接操作 void* 指针所指的对象。
2.4 const限定符
- 若想在多个文件之间共享 const 对象,必须在变量的定义之前加上 extern 关键字。
- 常量引用可以指向一个常量对象,而非常量引用不能指向常量对象。
- 非 const 的对象可以被 常量对象引用,只不过不允许通过该常量引用来改变对象的值。
- const 对象必须初始化。
- 顶层 const ,形如
typename * const val = & pointer;
使 val 只读,即 val 与 pointer 绑定,并可以通过改变 val 指向的数据来改变 pointer 指向的数据,即 * val 可写。 - 底层 const ,形如
const typename * val = &p;
相对的,使 * val 只读, val 引用的对象可以改变,但始终不能通过 val 来改变其引用对象所指向的数据。 - 用于声明引用的 const 都是 底层const。
- 所以在初始化时,两边的对象必须拥有相同的底层 const 资格(状态),且两者的数据类型可以互相转化。
- 将变量声明为 constexpr 时,会由编译器来验证变量的值是否为一个常量表达式。一般来讲,如果你认定变量是一个常量表达式,那就把它声明成 constexpr 类型。
- 对于一个被定义了的指针来说, constexpr 限定符只对指针有效,与指针所对应的对象无关。
2.5 处理类型
- pstring 是char*的别名,但在声明语句中不可简单的替换为 const char * cstr=0;这样会将cstr曲解为指向const char 的指针,而实际意义更类似于char * const cstr = 0; 即指向char的常量指针。
typedef char *pstring;
const pstring cstr = 0; //cstr是指向char的常量指针
- auto 语句中所有的变量的初始基本数据类型必须一样。
- auto 一般会忽略掉顶层 const 。(对常量对象取地址是一种底层的 const )
- 赋值表达式会返回引用。
- 若 decltype 使用的表达式是一个变量,则返回该变量的类型(包括顶层 const 和引用)。若表达式不是一个变量,则返回表达式结果对应的类型。