变量和基本类型
基本内置类型
算数类型: 包括整型和浮点型
C++算术类型
类型 含义 最小尺寸
bool 布尔类型 未定义
char 字符 8位
wchar_t 宽字符 16位
char16_t Unicode字符 16位
char32_t Unicode字符 32位
short 短整型 16位
int 整型 16位
long 长整型 32位
long long 长整型 64位
float 单精度浮点数 6位有效数字
double 双精度浮点数 10位有效数字
long double 扩展精度浮点数 10位有效数字
其他字符类型用于扩展字符集,char在一些机器上是有符号的,在另一些机器上又是无符号的
带符号类型和无符号类型
带符号:signed
无符号:unsigned
类型转换
1、将一个非布尔类型的算术值赋给布尔类型时,初始值为0则结果为false,否则结果为true
2、将一个布尔值赋给非布尔类型时,初始值为false,则结果为0,初始值为true,则结果为1
3、将一个浮点数赋给整数类型时,结果值将仅保留浮点数中小数点之前的部分
4、将一个整数值赋给浮点类型时,小数部分记为0,若该整数所占空间超过浮点类型容量,精度会有损失
5、赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数
6、赋给带符号类型一个超出它表示范围的值时,结果是未定义的
字面值常量
整型和浮点型字面值
整型字面值:
十进制数、八进制数(以0开头的整数)、十六进制数(以0x或0X开头的整数)
浮点型字面值:
以一个小数或以科学计数法表示的指数,其中指数部分用E或e标识
字符和字符串字面值
字符串字面值实际上是由常量字符构成的数组,编译器在每个字符串结尾处添加一个空字符(‘\0’)
转义序列
有两类字符不可直接使用,一类是不可打印字符,没有可视的图符;另一类是具有特殊含义的字符,需要用到转义序列,以'\'作为开始
常见转义序列
换行符 \n 横向制表符 \t 报警(响铃)符 \a
纵向制表符 \v 退格符 \b 双引号 \"
反斜线 \\ 问号 \? 单引号 \'
回车符 \r 进纸符 \f
也可使用泛化的转义序列,形式为:x后紧跟1个或多个十六进制数字,或者后紧跟1个、2个或3个八进制数字,数字部分表示的是字符对应的数值,若后面跟着的八进制数字超过3个,只有前3个数字与构成转义序列
指定字面值的类型
前缀 含义 类型
u Unicode 16 字符 char16_t
U Unicode 32 字符 char32_t
L 宽字符 wchar_t
u8 UTF-8(仅用于字符串字面常量) char
整型字面值 浮点型字面值
后缀 最小匹配类型 后缀 类型
u or U unsigned f或F float
l or L long l或L long double
ll or LL long long
布尔字面值:true 和 false
指针字面值:nullptr
变量
变量定义的基本形式:
类型说明符 一个或多个变量名组成的列表,变量名以逗号分隔,最后以分号结束
初始化:
创建变量时赋予其一个初始值,而赋值的含义是把对象的当前值擦除,而以一个新值来代替
声明:
使名字为程序所知,一个文件如果想使用别处定义的名字则必须包含对那个名字的声明,在变量名前添加关键字extern
定义:
负责创建与名字关联的实体,任何包含了显示初始化的声明即成为定义
标识符
由字母、数字和下划线组成,必须以字母或下划线开头,长度没有限制,对大小写敏感
C++关键字
alignas continue friend register true
alignof decltype goto reinterpret_cast try
asm default if return typedef
auto delete inline short typeid
bool do int signed typename
break double long sizeof union
case dynamic_cast mutable static unsigned
catch else namespace static_assert using
char enum new static_cast virtual
char16_t explicit noexcept struct void
char32_t export nullptr switch volatile
class extern operator template wchar_t
const false private this while
const_cast for public throw
复合类型
基于其他类型定义的类型
引用
为对象起了另一个名字,引用类型引用另外一种类型,通过将声明符写成 &d 的形式来定义引用类型, d 是声明的变量名,引用必须初始化,引用并非对象,所有引用的类型都要和与之绑定的对象严格匹配,引用只能绑定在对象上,而不能与字面值或某个表达式的计算结果绑在一起
指针
1、指针本身就是一个对象,允许对指针赋值和拷贝,在指针的生命周期内可以先后指向几个不同的对象
2、指针无需在定义时赋初始值
3、指针存放某个对象的地址,要想获取该地址,需要使用取地址符(操作符&)
4、指针值:
(1) 指向一个对象
(2) 指向紧邻对象所占空间的下一个位置
(3) 空指针,意味着指针没有指向任何对象
(4) 无效指针,也就是上述情况之外的其他值
5、如果指针指向了一个对象,则允许使用解引用符(操作符*)来访问该对象
6、空指针:不指向任何对象,得到空指针最直接的办法就是用字面值nullptr来初始化指针,nullptr是一种特殊类型的字面值,可以被转换成任意其他的指针类型
7、C++11之前使用NULL的预处理变量来给指针赋值,变量在头文件cstdlib中定义,值就是0,由预处理器负责管理
8、类型相同的合法指针可用==操作符和!=操作符来进行比较
9、void 指针用于存放任意对象的地址,可用来和别的指针比较、作为函数的输入或输出,或者赋值给另一个void 指针,但不能直接操作void* 指针所指向的对象
指向指针的指针
通过*的个数可以区分指针的级别,**表示指向指针的指针,***表示指向指针的指针的指针
指向指针的引用
int i = 42;
int *p = &i;
int *&r = p;
从右向左读r的定义,&r表示r是一个引用,int *表示r所引用的对象的类型是指向int类型的指针
const 限定符
1、const对象一旦创建后其值就无法再改变,因此const对象必须初始化
2、默认状态下,const对象仅在文件内有效
3、如果想在多个文件之间共享const对象,必须在变量的定义之前添加extern关键字
const 引用
对常量的引用
const int ci = 1024;
const int &r1 = ci; //正确:引用及其对应的对象都是常量
r1 = 412; //错误:r1是对常量的引用
int &r2 = ci; //错误:试图让一个非常量引用指向一个常量对象
对const 的引用可能引用一个并非const的对象
指针和 const
const double pi = 3.14; //pi是个常量,他的值不能改变
double *ptr = π //错误:ptr是一个普通指针
const double *cptr = π //正确:cptr可以指向一个双精度常量
*cptr = 42; //错误:不能给*cptr赋值
const 指针
常量指针:将*放在const之前,必须初始化,初始化后不能再指向其他对象
int errNumb = 0;
int *const curErr = &errNumb; //curErr 将一直指向errNumb
const double pi = 3.14159;
const double *const pip = π //pip是一个指向常量对象的常量指针
顶层 const
顶层 const 表明指针本身是个常量,底层 const 表明指针所指的对象是一个常量
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
const int &r = ci; //用于生命引用的const都是底层const
constexpr和常量表达式
常量表达式:不会改变并且在编译过程就能得到计算结果的表达式
一个对象(或表达式)是不是常量表达式由他的数据类型和初始值共同决定
在C++11中,允许将变量声明为constexpr类型以便由编译器来验证变量的值是否是一个常量表达式,声明为constexpr的变量一定是一个常量,而且必须用常量表达式来初始化
指针和 constexpr
constexpr 仅对指针有效,与指针所指的对象无关
类型别名
传统方法使用关键字typedef
typedef double wages; //wages是double的同义词
使用别名声明定义类型的别名:
using SI = Sales_item; //SI是Sales_item的同义词
typedef char *pstring;
const pstring cstr ≠ const char *cstr
声明语句中用到pstring时,基本数据类型是指针,用char*重写了声明语句后,数据类型就变成了char,*成为了声明符的一部分
auto 类型说明符
auto 让编译器通过初始值来推算变量的类型,auto 定义的变量必须有初始值
auto 一般会忽略掉顶层const,同时底层 const 则会保留下来
decltype 类型指示符
选择并返回操作数的数据类型,编译器分析表达式并得到它的类型,却不实际计算表达式的值
decltype(f()) sum = x; // sum 的类型就是函数f的返回类型
如果decltype使用的表达式不是一个变量,则decltype返回表达式结果对应的类型
如果表达式的内容是解引用操作,则decltype将得到引用类型
对于decltype所用的表达式来说,如果变量名加上了一对括号,则得到的结果与不加括号时会有所不同,如果不加,则得到的结果就是该变量的类型,如果添加了一层或多层括号,编译器就会把它当成一个表达式
decltype((variable))的结果永远是引用,而decltype(variable)结果只有当variable本身就是一个引用时才是引用