3. 数据类型
3.1. 常用内置数据类型的大小
以下结果若非特别指出,均在 Visual Studio 中测试得到。
类型 |
size/32位编译器 |
size/64位编译器 |
---|---|---|
char |
1 |
1 |
char* |
4 |
8 |
int |
4 |
4 |
int* |
4 |
8 |
short |
2 |
2 |
long |
4 |
4 (8/linux) |
long* |
4 |
8 |
long long |
8 |
8 |
float |
4 |
4 |
double |
8 |
8 |
size_t |
4 |
8 |
size_type |
4 |
8 |
bool |
1 |
1 |
string |
28 |
40 |
3.2. sizeof与strlen
sizeof
sizeof()
是 运算符 ,计算的是分配的内存空间大小(单位为字节),编译时就会计算,不受里面存储内容的影响。sizeof()
可以用数据类型、数组、字符串等做参数。strlen
strlen()
是 函数 ,计算的是字符串的实际长度(字符的个数),以'\0'
结束但长度 不包括'\0'
,程序执行时才计算结果。strlen()
只能用char*
类型做参数。实例
定义以下变量:
1char *strA = "abcdef"; 2char strB[] = "abcdef"; 3char strC[5] = {'a'}; 4char strD[3] = {'a', 'b', 'c'}; 5char strE[] = {'a', 'b', 'c'}; 6char strF[] = {'a', 'b', 'c', '\0'}; 7int y[] = {1,2,3};
结果如下:
sizeof(strA) = 4 : 指针的大小 sizeof(strB) = 7 : 该字符数组用字符串初始化,因此strB就是一个字符串,字符串以'\0'结尾,则大小为6+1=7 sizeof(strC) = 5 : 字符数组所占内存为5字节 sizeof(strD) = 3 : 字符数组所占内存为3字节 sizeof(strE) = 3 : 字符数组中有3个字符 sizeof(strF) = 4 : 字符数组中有4个字符,包括'\0' sizeof(y) = 12 : 4 * 3 = 12 字节 strlen(strA) = 6 : 字符串长度为6,不包括'\0' strlen(strB) = 6 : 字符串长度为6,不包括'\0' strlen(strC) = 1 : 字符数组中只有1个字符 strlen(strD)不定,因为数组strD末尾没有人为补'\0',因此strD是一个普通的字符数组,而不是字符串 strlen(strE)不定,因为数组strE末尾没有人为补'\0',因此strD是一个普通的字符数组,而不是字符串 strlen(strF) = 3 : 字符串长度为3,不包括'\0'
Warning
如果字符数组以字符常量进行初始化且字符个数大于 1,如上例中的
strD
和strE
, 如果不在末尾人为添加'\0'
,则该字符数组不是字符串, 使用函数strlen
求得的大小不定,且该字符数组的内容也是未知的。 虽然strD
只有 3 个字节空间且刚好包含 3 个字符,但是cout << strD
的结果也是不定的。 正确的定义应该是strF
。
3.3. float和double
单精度浮点型 float 的精度为 6 – 7 位有效数字,双精度浮点型 double 的精度为 15 – 16 位有效数字。
1#include <iostream>
2#include <iomanip> // std::setprecision
3using namespace std;
4
5int main(int argc, char ** argv)
6{
7 int i = 200000003 / 100000002; // 1.9999999900000003
8
9 float f_i = 200000003 / (float)100000002; // 浮点型常数默认为 const double,或用 200000003.0f 指定为 float。
10 float f_f = (float)200000003.0 / (float)100000002.0; // 若不进行强制类型转换,会有 warning: truncation from 'double' to 'float'
11 float f_d = (float)200000003.0 / (double)100000002;// warning: truncation from 'double' to 'float'
12 double d_d = 200000003 / (double)100000002;
13
14 cout.setf(ios::fixed); // 浮点数定点输出
15 cout.setf(ios::showpoint); // 显示小数位
16 cout.precision(10); // 固定为10位精度(四舍五入)
17 cout << i << endl; // 1
18 cout << f_i << ends << static_cast<int>(f_i) << endl; // 2.0000000000 2
19 cout << f_f << ends << static_cast<int>(f_f) << endl; // 2.0000000000 2
20 cout << f_d << ends << static_cast<int>(f_d) << endl; // 2.0000000000 2
21 cout << d_d << ends << static_cast<int>(d_d) << endl; // 1.9999999900 1
22 cout.precision(2);
23 cout << d_d << ends << static_cast<int>(d_d) << endl; // 2.00 1
24
25 cout << boolalpha; // 设置布尔型输出格式
26 cout << (i == static_cast<int>(f_f)) << endl; // false
27 cout << (i == static_cast<int>(f_d)) << endl; // false
28 cout << (i == static_cast<int>(d_d)) << endl; // true (只有double转换到int的结果与 i 一致)
29
30 float f_a = 0.1000001;
31 float f_a2 = f_a * f_a; // 0.1000001^2 = 0.01000002000001
32 cout << setprecision(7) << f_a2 << endl; // 0.01000002
33 cout << setprecision(15) << f_a2 << endl; // 0.0100000193342566
34
35 double d_a = 0.1000001;
36 double d_a2 = d_a * d_a; // 0.1000001^2 = 0.01000002000001
37 cout << setprecision(7) << d_a2 << endl; // 0.01000002
38 cout << setprecision(15) << d_a2 << endl; // 0.01000002000001
39
40 return 0;
41}
3.4. 参考资料
数据类型的数值范围
关于strlen与sizeof的区别
C++ 中的 cout.setf() 函数