文章目录
前言
自学 《C++ Primer 第五版》,它含有 C++11的特性。
以前是C++98标准,一直到2011年,出了 C++11标准,以后每三年出一次标准,现在已有C++11、C++14、C++17…
由于本人,主做安卓开发。开发程序肯定还要考虑兼容性。前两年的程序,至少都要考虑兼容到 安卓 4.x (api level 14~20),甚至更低版本;现在的编译器 Android Studio 在新建项目时,会提示,最小 api 支持,能兼容到多少百分比的设备。
本来想去查下官方文档,安卓哪个版本支持 cpp11, 哪个版本支持 cpp14,结果愣是查不到。安卓 ndk 文档,现在能找到的,也只是说,ndk r18b 开始支持 cpp17。 而 ndk 只能算是编译时,而具体运行时的 android api level,对 cpp 版本的有没有要求,这个暂不清楚。 只能是有机会,以低版本真机 测试下 高版本的 cpp 代码能否正常运行了。
无论如何,现在是2019年,支持 cpp11的设备,只会越来越多了。
什么是基本内置类型
书中说, 基本内置类型,体现了大多数计算机硬件本身就具备的能力。
感觉,就跟 java 的基本数据类型差不多。就是 整形、浮点型、字符型。
基本内置类型,包括如下的算术类型和字面值常量
算术类型
算术类型,就是能被用于计算的类型。整形、浮点型、字符型 都可以用于计算
bool flag = true; //or false. 可用于计算,结果就是 1或0 参与计算
char c = 'c'; //8bit。 占一个字节。
wchar_t w = 'c'; //宽字符型 16bit
char16_t c16 = 'c'; //unicode 字符 16bit
char32_t c32 = 'c'; //unicode 字符 32bit
short s = 77; //16bit
int i = 12222; //16bit
long l = 33333333; //32bit
long long ll = 888888888888; //64bit //cpp11 add
float f = 88.012345678901; //单精度浮点型 6位有效数字
double d = 88.012345678901; //双精度 10位有效数字
long double ld = 88.012345678901; //扩展精度 10位有效数字
c++规定,类型所占字节 longlong >= long >= int >= short
无符号和有符号类型
除 bool 和 unicode 的字符型外,其它非浮点类型都可以是无符号 unsigned 类型。
eg. unsigned int a = 10;
有三种声明方式:
int a = 10;
signed int a = 10;
unsigned int a = 10;
int a = 10;
默认看成是有符号的。 但和signed int a = 10;
又不是同一种类型。
通常也不会特意加上signed
关键字来表示有符号,太麻烦
无符号类型,是 >= 0的值。即使赋值一个负数,也会自动转换成一个 >=0的值。
算术类型的数据范围
假定每种类型在目标设备上的所占字节数,就是上面代码注释中所描述的。
以 short 、unsigned short 为例:
short 本身是16bit;
short的范围:
unsigned short的范围:
算术类型,有符号与无符号的值的范围,就是和其所占字节有关的,设bit数为N,
- 有符号时,负数范围占一半的bit,即 ;0及正数占一半的bit,即 。
- 无符号时,从0开始,最大占满所有的bit范围:
内置函数 sizeof(type)
,可以获取参数类型的所占字节数。eg. sizeof(unsigned int)
对无符号类型,赋值一个超范围的值
unsigned char c0 = 256; //=0
unsigned char c1 = -514; //=254= 2^8-2
unsigned char c2 = 514; //=2
转换规则简单来看:
char 范围 => [0, 255] , 值为负数时,取0的左边值,由于左边没有了,那么从255向前移。所以值-1就对应255。
反之,为正数时,取255的右边值,由于右边没有了,那么从0向后移。所以值256对应0。
-
当字面值(或者说 绝对值) 太大时,就用取模运算。
unsigned char c1 = -514;
=>256-514%256
=>254
; -
反之,为负数时:
unsigned char c1 = -514;
=>514%256
=>2
;
与更大范围的类型进行计算时,或类型转换时,上规则适用的。
字面值常量
就是一看就知道的值。 如 30 、'a'
这样的值。
每个字面值常量都对应一种数据类型。
整形字面值
十进制: 100
八进制:076 以数字零开头
十六进制; 0xabc 以0x 或0X 开头
浮点型字面值
eg. 3.14
科学计数法
科学计数法:一个浮点数x的10的 n 次方,记作: xen
,或xEn
;
eg.
3.14e5; => 3.14*10^5
3.14e-5; => 3.14*10^-5
字符和字符串字面值
eg.
`a` 字符
"abc" 字符串
字符串实际是多个字符构成的数组;编译器在数组末尾自动添加一个空字符。
eg.
"abc" => ['a', 'b', 'c', '\0'];
转义序列
使用反斜杠。常用的
\r 回车符
\n 换行
\\ 反斜杠
\t 横向制表。 类似横向留空白
\v 纵向制表
\? 问号
\" 双引号
\' 单引号
\0 空字符
\u unicode字符 eg. const char32_t ccxx = U'\u4e2d'; cout << (U'中' == ccxx') << endl;
添加前缀或后缀,指定字面值的类型
对字符或字符串面值的前缀: u U L u8
cout << "1: " << sizeof('a') << endl; //char
cout << "2: " << sizeof(L'a') << endl; //L:wchar_t; u:char16_t; U:char32_t;
cout << "3: " << sizeof(u"中国") << endl; //与 char16_t[]
cout << "4: " << sizeof(u8"中国") << endl; //utf8, 与 sizeof("中国")一样,是char[]
对整型或浮点型的后缀: u/U l/L ll/LL f/F
cout << "5: " << sizeof(100) << endl; //int
cout << "6: " << sizeof(100ULL) << endl; // ll/LL: unsigned long long; u/U: unsigned; l/L: long
cout << "7: " << sizeof(1E-3) << endl; //double
cout << "8: " << sizeof(1E-3F) << endl; // f/F: float
cout << "9: " << sizeof(3.14) << endl; //double
cout << "10: " << sizeof(3.14L) << endl; // l/L: long double
布尔字面值和指针字面值
- true 或 false 就是布尔字面值
- nullptr 是指针字面值。表示指针为空