一、内置类型
1、wchar_t 用于扩展字符集,如汉字、日文等;
char16_t、char32_t用于Unicode字符集;
long long 长整型 64位。
2、无符号数减去一个值时,无论这个值是不是无符号数,结果都不会是负值(若为负,则取取模后的值);
最好不要混用有符号数和无符号数。
3、反斜线\后面跟着的八进制数超过3个,只有前3个数字与\构成转义序列。
二、变量
1、初始化不是赋值,初始化时创建一个变量时赋予其一个初始值,赋值是把变量的当前值擦掉,以一个新值代替;
//初始化的几种形式
int a = 0;
int a = { 0 };
int a{ 0 };
int a(0);
定义变量时没有赋初值,则被默认初始化;对于内置类型变量,定义于任何函数体之外会被初始化为0,定义在函数体内部的内置类型变量将不被 初始化。
最好初始化每一个内置类型变量。
2、声明一个变量而非定义它,可在变量名前添加关键字extern;
在函数体内部,初始化一个由extern关键字标记的变量,将引发错误。
三、复合类型
1、引用
(1)引用必须被初始化;
(2)引用不是对象,不能定义引用的引用。
2、指针
(1)指针存放对象的地址,使用取地址符“&”获取该地址;
(2)指针的值(即地址)应属下列4种状态之一:
1. 指向一个对象;
2. 指向紧邻对象所占空间的下一个位置;
3. 空指针,即没有指向任何对象;
4. 无效指针,也就是上述情况之外的其他值。
(3)指针指向了一个对象,可以使用解引用符“ * ”来访问该对象(仅适合确实指向某个对象的有效指针);
int i = 42;
//&紧随类型名出现,是声明的一部分,r是一个引用
int &r = i;
//*紧随类型名出现,是声明的一部分,p是一个指针
int *p;
//&出现在表达式中,是一个取地址符
p = &i;
//*出现在表达式,是一个解引用符
*p = i;
//&是声明的一部分,*是一个解引用符
int &c = *p;
(4)空指针最好使用nullptr初始化;
(5)赋值永远改变的是等号左侧的对象;
(6)void* 指针是一种特殊的指针类型,可放任意对象的地址。void*指针,不能直接操作指针所指的对象,因为不知道对象的类型。可那其与 别的指针比较、作为函数的输入或输出、赋给另一个void*指针;
(7)最好将*(或是&)与变量名连在一起。
//面对一条比较复杂的指针或是引用的声明语句,从右往左读有助理解,离变量名最近的符号对变量的类型有最直接的影响
int i = 42;
int *p;
//r是对指针p的一个引用
int *&r = p;
四、const限定符
1、const对象创建时就必须初始化;
2、多文件共享const对象,需在变量的定义前添加extern关键字;
3、const 的引用
对常量的引用不能被用作修改它所捆绑的对象;
//正确:引用及其对应的对象都是常量
const int ci = 1024;
const int &r1 = ci;
//错误:试图让一个非常量引用指向一个常量对象
int &r2 = ci;
4、指针与const
(1)指向常量的指针不能用于改变其所指对象的值;
(2)顶层const表示指针本身是个常量,底层const表示指针所指对象是一个常量;
5、一个对象是不是常量表达式由它的数据类型和初始值决定;
声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化:
//20是常量表达式
constexpr int mf = 20;
//mf+1是常量表达式
constexpr int limit = mf + 1;
指针和引用都能定义成constexpr,但它们的初始值受到严格限制。一个constexpr的指针的初始值必须是nullptr或是0,或是存储于某个固定地址中的对象。
五、处理类型
1、类型别名
//传统方法,wages是double的同义词
typedef double wages;
//新标准方法,SI是double的同义词
using SI = double;
2、auto类型说明符,能让编译器去分析表达式所属的类型,auto定义的变量必须有初始值。
3、decltype类型指示符
(1)decltype类型说明符,选择并返回操作数的数据类型;
decltype(f()) sum = x; //sum的类型就是函数f的返回类型
(2)decltype((variable)) (双层括号)的结果永远是引用,必须初始化;
decltype((variable)) 结果只有当variable本身是引用时才是引用。
六、自定义数据结构
1、类定义的最后不要忘记加分号;
2、头文件通常包含那些只能被定义一次的实体,如类、const和constexpr变量等;
3、预处理变量。
预处理变量有两种状态:已定义和未定义。#define指令把一个名字设定为预处理变量;#ifdef和#ifndef分别检查某个指定的预处理变量是否已经定义:#ifdef 当且仅当变量已定义时为真,#ifndef 当且仅当变量未定义时为真。一旦检查结果为真,则执行后续操作直至遇到#endif指令为止。
#include <iostream>
#ifndef SALES_DATA_H //第一次包含Sales_data.h时,#ifndef检查结果为真,执行后面语句直至遇到#endif为止。此时,SALES_DATA_H已定义,再次包含时将忽略#ifndef到#endif之间的部分
#define SALES_DATA_H //一般把预处理变量的名字全部大写
#include <string>
using namespace std;
struct Sales_data{
string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
#endif