变量和数据类型
内置类型的机器表示
8个 bit 为一个 byte,32位系统下4个 byte 叫一个 word
基本内置类型
unsigned int 也可以简称为 unsigned
unsigned 类型在赋值超出范围的时候会取该值对该类型取值数目求模后的值。例如 unsigned char 类型在给超出255的值(如336)进行赋值时会将其对256进行求模操作,这样下来它的值就是80(336 % 255 = 80)
字符(串)字面值前面加上 L 就可以变成宽字符(串)字面值,如
1 | L'我'; |
详细的字面值类型见下表
前缀 | 含义 | 类型 |
---|---|---|
u | Unicode16字符 | char16_t |
U | Unicode32字符 | char_32t |
L | 宽字符 | wchar_t |
u8 | utf-8(仅用于字符串字面常量) | char |
定义对象
初始化:创建变量并为它赋初值。
赋值:擦除对象的当前值并用新值代替
声明和定义
如果声明有初始化式,即使前面有 extern 也可以当作是定义,如
1 | extern double pi = 3.1416; //虽然有extern,但是可以当成是定义而非声明 |
注:只有当 extern 声明位于函数外部时,才可以含有初始化式。也就是说函数体内部不能使用上述办法。
名字的作用域
全局作用域中的 const 是单个文件的局部变量,只有在定义时加上 extern 才能被别的文件访问。
const 引用
非 const 引用只能绑定到与该引用同类型的对象,而 const 引用可以绑定到不同但相关的类型的对象或绑定到右值。
1 | int i = 7; |
类的数据成员
一般不能把类的初始化作为其定义的一部分,定义数据成员时,只指定该数据成员的名字和类型。类不是在类定义里面定义数据成员的时候初始化成员,而是在构造函数里面。
C++11新标准规定:可以为数据成员提供一个类内初值。创建对象时类内初值将用于初始化数据成员。
使用 struct 关键字
struct 和 class 不同之处在于默认访问标号,struct 默认是 public 访问,而 class 则是默认 private 访问。
列表初始化
列表初始化允许用一对大括号来初始化对象了,其特点是:当使用列表初始化初始化对象时存在丢失信息的风险,编译器会报错(窄化转换)。现在初始化有四种形式,如下。列表初始化不会损失精度!
1 | long double ld = 3.1415926536; |
如果不用等号,那么就是直接初始化,如果用等号,就是拷贝初始化。拷贝初始化就是新建一个临时变量,再把其值复制过去。
常量表达式
指值不会改变且在编译过程中就能得到计算结果的表达式。
C++11中允许将变量声明为 constexpr 类型以便由编译器来验证变量的值是否是一个常量表达式。声明为 constexpr 的变量一定是一个常量。如下
1 | constexpr int mf = 20; //是一个常量表达式 |
如果 constexpr 定义的是一个指针,那么限定符仅对指针有效,与指针所指的对象无关。
1 | const int *p = nullptr; //这个是底层const |
类型别名
就是类型的小名,有两种方法定义,如下是老办法typedef
1 | typedef double wages; //wages 是 double 的小名 |
C++11定义了新的办法 别名声明,如下
1 | using SI = Seals_item; //SI是Seals_item的小名 |
auto类型说明符
auto 一般会忽略掉 顶层const ,保留 底层const。如
1 | const int ci = i; |
如果想要auto推断出一个顶层const的话需要显式说明,如
1 | const auto f = ci; //因为auto推断的时候忽略了顶层const,手动加上了一个顶层const后,f的数据类型又变成了const int |
也可以将引用类型设置为auto,此时引用的初始化规则仍然有效。如
1 | auto &g = ci; //行,auto推断出来g是一个整型常量引用,可以绑定 |
注:在一个语句中定义多个变量时切记,符号 & 和 * 只从属于某个声明符,而非基本数据类型的一部分!!如下
1 | //其中ci是const int类型,i是int类型 |
decltype类型指示符
这个类型指示符只用来返回表达式的数据类型,不返回表达式的值。用法如下
1 | decltype(f()) sum = x; //sum的类型就是f()返回的类型 |
使用decltype时,编译器并不实际调用 f()
decltype 处理顶层const和引用的方式与auto不同。如果decltype使用的表达式是一个变量,则decltype返回该变量的类型(包括const和引用),如下
1 | const int ci = 0, &cj = ci; |
又如
1 | int i = 42, *p = &i, &r = i; |
切记:decltype((variable)) 的结果永远是引用,而 decltype(variable) 的结果只有当 variable 本身是引用时才是引用,如
1 | int i = 0; |
类内初始值(C++11)
创建对象时,类内初始值将用于初始化数据成员,没有初始值的成员将会被默认初始化。
string::size_type 类型
string::size_type是一个无符号类型的值而且足够存下任何string类型值。所有用于存放string类的size函数返回值的变量都应该是string::size_type类型
C++11中允许使用 auto 和 decltype 来推断变量类型,如
1 | auto len = line.size() |
注:如果一条表达式中已经有了 size() 函数就不要再使用 int 了!原因如下
1 | int n = -1; |