最近在读《C++ primer》英文版,把笔记写在这了,如果有理解的不对的地方,希望大家给予指正!
Chapter2,Section2.1——Primitive Built-in Types
算术类型
类型决定了程序中的数据和可以进行的操作。
C++定义了算术类型和一个特殊的void(空)类型。
算术类型有整型,字符类型,布尔类型,浮点类型。空类型常用在函数没有返回值时。
下表中列出了标准中能保证的最小大小:
C++ 算术类型
类型————含义————最小大小
bool————布尔类型————NA
char————字符类型————8bits
wchar_t——宽位字符类型——16bits
char16_t——Unicode字符——16bits
char32_t——Unicode字符——32bits
short————短整型————16bits
int————整型——————16bits
long————长整型————32bits
long long——长整型————64bits
float单精度浮点类型——————6位有效数字
double双精度浮点类型——————10位有效数字
long double扩展精度浮点类型——10位有效数字
布尔类型代表的值有true和false。
有许多字符类型,他们中有的是用来支持国际化。最基本的是char类型。一个char和一个单独的机器字节一样大。
其余的字符类型——wchar_t,char16_t,char32_t是用来拓展字符集。
wchar_t能够支持机器上最大的拓展字符集中的任何字符。
char16_t和char32_t是指Unicode字符。(Unicode是一个能用来表示在任何自然语言中使用的字符的标准。)
计算机按位存储数据,每一位存储0或1。大多数计算机处理内存的块的大小是2的幂。可寻址的最小块是一个“字节”。
最基本的存储单元通常是一小部分字节,被称为一个“字”。
在C++里一个字节至少和机器的基本字符集中的一个字符有一样多的位数。在大多数的机器里一个字节是8位,一个字是32或64位,也就是4或8个字节。
大多数的计算机里每一个字节都关联着一个数字——”地址“。一个地址下可以存储任意大小的位。要想知道某一地址的内存的具体含义,就要知道存储在这一地址下的数据的类型。
浮点类型有单精度浮点类型,双精度浮点类型,扩展精度浮点类型。标准中规定了有效数字的最小值。大多数的编译器提供了比最小值更大的精度。float是一个字(32位),double是两个字(64位),long double是3个或4个字(96或128位)。float和double分别能产生7和16位有效数字。long double通常被用来去适应专用浮点硬件,它的精度可能从一个实现变化到另一个。
有符号类型和无符号类型
除了bool类型可扩展类型,整型分为有符号和无符号两类。有符号数包括整数(包含0)、负数。无符号数都是大于等于0的数。
int,short,long,long long都是有符号的。在类型名前面加上unsigned就变成了无符号类型,unsigned int类型可能被缩写为unsigned。
不同于整数类型,基本字符类型有三种:char,signed char,和unsigned char。char和signed char是不一样的。尽管有三种不同的字符类型,但是仅有两种形式:unsigned和signed。char类型具体采用哪种类型取决于用的编译器。
在无符号类型里,所有的位都代表值。例如8-bits能代表0-255之间的所有值。
标准里没有定义有符号数的形式,但是定义了正值和负值之间的范围。一个8位的有符号字符能表示从-127到127之间的所有值,大多数现代的机器能表示-128到127之间的所有值。
C++和C一样能够让程序在必要时更加接近硬件,算术类型能够适应各种类型的硬件的特点。但是C++中的算术类型经常让人感到困惑。大多数的编程者能够通过限制他们使用的类型来忽略这些复杂性。
下面给出使用哪种类型的建议:
(1)当值不可能是负值时使用unsigned类型。
(2)在证书运算时使用int类型。short通常都太小,long通常和int有着一样的大小。如果数据的值比int的最小大小大,那么就使用long long。
(3)在算术运算中不要使用char和bool类型。当存储字符或判断真值时使用它们。使用char的计算表达式通常会出问题因为char在一些机器上是有符号的但是在另一些机器上是无符号的。如果要使用小整数,则定义char是signed或是unsigned的。
(4)在计算中使用双精度数double;float通常精度不够。双精度计算的花费与单精度比起来可以忽略不计。事实上,在一些机器上,双精度操作比单精度快。long double的精度通常是不必要的并且经常要考虑运行时间花费。
类型转换
(1)把一个非布尔算术类型赋给布尔类型对象,则当该非布尔类型值为0时为false,其余情况为true。
(2)把一个布尔类型数据赋给其它算术类型,当布尔类型为true时值为1,否则为0。
(3)当把整型赋值给浮点型,小数的部分是0。如果整型的位数比超过了浮点类型能容纳的,则会发生精度丢失。
(4)如果把一个超过无符号数范围的数赋值给该无符号数,则结果是这个数模上该类型能表示的数的个数。
例如一个8位的unsigned char能表示的数的范围是0到255,如果把该范围以外的某个数赋值给这个类型的变 量,则编译器把这个数模上256的余数赋值给这个类型的变量。
unsigned char c = -1;则c的值是255。(-1模256)
(5)如果我们把超过有符号数范围外的数赋给一个有符号数,则结果是undefined。这个程序可能会运行,它可能会 崩溃,或者可能产生无效值。
编译器不能发现错误中不明确的行为的结果。即使代码编译了,程序执行一个未定义的表达式也会出错。不幸的是程序在含有未定义的行为时在某些情况下或在某些编译器里也会执行正确。并不能保证同一个程序在同一编译器或是同一编译器的后续版本中运行正确。程序通常应该避免定义时实现的行为。避免不可移植程序。
如果在一个表达式里同时含有int类型和unsigned类型,则int类型自动转为unsigned类型。
如果是32位int,unsigned -1是4294967295。
当无符号数有有符号负数相乘时,结果是令人惊奇的,结果取决于机器上int是多少位的。
Literals
整型和浮点类型literals
整型literals:十进制,八进制0,十六进制0x。
默认情况下十进制是有符号的,八进制和十六进制可以是有符号的或无符号的。
十进制literals有适应literals值的最小的int,long,long long类型。
八进制literals和十六进制literals有适应literals值的int,unsigned int,long,unsigned long,long long,unsigned long long类型。
short类型没有literals。
通常说的十进制literals都是正的,如果一个十进制literals前面有负号,则负号不是literals的一部分。
浮点literals包括一个十进制小数点或使用科学计数法的指数形式。当使用科学计数法时,指数被缩写为E或e。
默认情况下,浮点literals有double类型。
字符和字符串类型literals
在单引号里面的一个字符是一个字符literals,在双引号里面的一个或多个字符是字符串literals。
编译器在每一个字符串literals后面加一个空字符'\0'。
两个仅仅被空格,tab,或者换行分隔开的临近的字符串literals可以联结成一个字符串literals。
转义序列
转义序列以反斜杠\开始。用来转义一些看不见的字符(比如回退符或控制字符)和一些在程序中有特殊意义的字符(双引号,单引号,问号,和反斜杠)。这个语言定义了多个转义序列:
换行 \n,水平制表符 \t,alert(bell) \a,垂直制表符 \v,回退符 \b,
双引号 \",反斜杠 \\,问号 \?,单引号 \',回车符 \r,跳页符 \f。
也可以写\x加上十六进制数字或\加一个、两个或三个八进制数字。
例如(Latin-1字符集):\7 (bell),\12 换行,\40 空格,\0 空,\115 'M',\x4d 'M'。
如果\跟随了超过3个八进制字符,则只处理\后的前三个。
定义literals类型
我们能用下表中的前缀或后缀重写默认类型中的整型、浮点或字符literals。
(当写一个long literals是,最好写大写‘L’,以免把小写'l'与数字1弄混。)
下面为定义literals类型表:
字符和字符串literals
前缀——含义——————————类型
u——Unicode 16位字符—————char16_t
U——Unicode 32位字符—————char32_t
L——宽字符——————————wchar_t
u8——utf-8(仅是String literals)——char
整数literals浮点literals
后缀——最小类型
u或U——unsigned
l或L——long
ll或LL——long long
后缀——类型
f或F——float
l或L——long double
布尔和指针literals
true和false是bool类型的literals。
nullptr是一个指针literals。