4.5
//默认double类型
4.5f
//float类型
基本内置类型
基本内置类型包含算术类型和空类型,算术类型包含字符、整数型、布尔值和浮点数,空类型不对应具体的值,仅用于一些特殊的场合。
算术类型
分为两类,整型(包括字符和布尔类型)和浮点型。
浮点数有效位数的最小值,然而大多数编译器都实现了更高的精度。float以1个字(32比特)来表示,double以2个字(64比特)来表示,long double以3或4个字(96或128比特)来表示。一般来说,类型float和double分别有7和16个有效位;类型long double则常常被用于有特殊浮点需求的硬件,它的具体实现不同,精度也各不相同。
带符号类型和无符号类型
除去布尔型和扩展的字符型之外,其他整型可以划分为带符号的和无符号的两种。带符号类型可以表示正数、负数或0。,无符号类型则仅能表示大于等于0的值。
类型int、short、long和long long都是带符号的,通过在这些类型名前添加unsigned就可以得到无符号类型。类型unsigned int可以缩写为unsigned。
字符型被分为了三种:char、signed char和unsigned char。类型char和类型signed char并不一样。字符的表现形式只有两种,带符号和无符号的。类型char只会变现为其中一种,具体由编译器据决定。
类型转换
- 非布尔类型的算术值赋给布尔类型时,0—>false,其他—>true
- 布尔值赋给非布尔类型时,false—>0,true—>1
- 浮点数赋给整数类型时,进行近似处理。结果值保留浮点数中小数点之前的部分。
- 整数值赋给浮点类型时,小数部分记为0。如果该整数所占的空间超过了浮点类型的容量,精确度可能由损失。
- 当赋给无符号数一个超过它的表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数。【涉及数的存储】
- 当赋给带符号数一个超过它的表示范围的值时,结果是未定义的。
自动转换
窄—>宽
整型<浮点型
布尔<int
char<int
有符号<无符号
空间小<空间大
类型别名
是一个名字,是某种类型的同义词。类型别名和类型的名字等价,只要是类型的名字出现的地方,就能使用类型别名。
定义类型别名
typedef
typedef 类型 类型别名;
声明符可以包含类型修饰,由基本类型构造出复合类型。
特别声明
using 别名 = 类型;
把等号左侧的名字规定成等号右侧类型的别名
指针、常量和类型别名
首先,遇到使用类型别名的声明语句时,不能把类型别名替换成其本来的样子【可通过添加小括号帮助理解】。其次,如果使用 const 修饰类型别名,它修饰的是一个整体,可以为其加一个小括号方便理解。
typedef char* pstring;
const pstring cstr = 0; //可理解为 const ( char * ) cstr = 0;
const 修饰 pstring 即 char * ,说明 cstr 是一个指针常量,其指向不能改变,但是指向的内容可以改变。
auto
auto 可以让编译器通过初始值推算变量的类型。
使用 auto 可以在一条语句中声明多个变量。因为一条语句只能有一个基本数据类型,所以该语句中所有变量的基本类型都一样。
常量
会忽略顶层的 const ,保留底层的 const 。
对常量对象取地址是一种底层 const 。
明确指出可使推断出的 auto 类型是一个顶层 const。
引用
使用引用是使用引用的对象【尤其是引用被用作初始值时】,真正参与初始化的是引用对象的值,此时编译器以引用对象的类型作为 auto 的类型。
可将引用的类型设为 auto 。
设置一个类型为 auto 的引用时,保留初始值中的顶层常量属性,若给初始值绑定一个引用,此时的常量将不再是顶层常量。
decltype
作用:选择并返回操作数的数据类型,在此过程中,编译器分析表达式并得到它的类型,却不实际计算表达式的值。
decltype 处理顶层 const 和引用的方式与 auto 不太相同。如果 decltype 使用的表达式是一个变量,则 decltype 返回该变量的类型(包括顶层 const 和引用)。
引用作为其所指对象的同义词出现,只有用在 decltype 处例外。
引用
decltype 使用的表达式不是一个变量时,decltype 返回表达式结果对应的类型。有些表达式向 decltype 返回一个引用类型,这种情况发生时,意味着该表达式的结果对象能作为一条赋值语句的左值。
//decltype 的结果可以是引用类型
int i = 42, *p = &i, &r = i;
decltype(r + 0) b; // 正确:加法的结果是 int ,因此 b 是一个未初始化的 int 类型的变量
decltype(*p) c; // 错误:c 是 int& ,必须初始化【*p 意为对p解引用,p 指针指向一个int类型的对象】
decltype 结果是引用类型的情况
引用
表达式的内容是引用时,decltype 的结果是引用类型。
因为 r 是一个引用,所以 decltype(r) 的结果是引用类型,若让结果类型是 r 所指的类型,可把 r 作为表达式的一部分,如 r + 0 ,该表达式的结果是一个具体值而非一个引用。
解引用
表达式的内容是解引用操作时,decltype 的结果是引用类型。解引用指针可以得到指针所指的对象,而且可以给该对象赋值。
decltype 和 auto 的区别
- 处理顶层 const 和引用的方式与 auto 不同。
auto 忽略顶层的 const,保留底层的 const。使用引用使用的是引用的对象,编译器以引用对象的类型作为 auto 的类型,可显示的使用 & 来声明一个 auto 类型的引用。
decltype 使用的表达式是一个变量,则 decltype 返回该变量的类型(包括顶层 const 和引用)。表达式的内容是引用时返回引用类型。
- decltype 的结果类型与表达式形式密切相关。
对于 decltype 所用的表达式,如果变量名加上一对括号,则得到的类型与不加括号时不同 。如果 decltype 使用的是一个不加括号的变量,得到的结果是该变量的类型;如果给变量加上一层或多层括号,得到的结果是该变量类型的引用。
decltype((variable))
(注意是双层括号)的结果永远是引用,而decltype(variable)
结果只有当 variable 本身就是一个引用时才是引用。
// decltype 的表达式如果是加上括号的变量,结果是引用
decltype((i)) d; //错误:d 是 int&,必须初始化
decltype(i) e; //正确:e 是一个(未初始化的)int
自定义数据结构
数据结构:把一组相关的数据元素组织起来然后使用其策略和方法。以类的形式自定义数据结构。