数据类型
Kong Liangqian Lv6

编译

分开编译链接

1
g++ -c main.cpp

-c 表示只编译,生成一个目标文件 main.o

1
g++ -c mul.cpp

-c 表示只编译,生成一个目标文件 mul.o

1
g++ main.o mul.o -o mul

表示链接

一次性编译链接

1
g++ main.cpp mul.cpp -o mul

一次性编译链接完

整数类型

1
2
3
4
5
6
7
8
9
10
11
12
//overflow.cpp
#include <iostream>
using namespace std;

int main()
{
int a = 56789;
int b = 56789;
int c = a * b;
cout << "c = " << c << endl;
return 0;
}

这里c会得到负数。因为a * b的结果已经超过了int的范围,这里改为unsigned int就行了,在做运算的时候需要仔细审视数据类型的数据范围

image-20220322231153234

可以通过如下代码查看是几个字节

1
2
3
4
5
6
7
8
#include <iostream>
int main() {
std::cout << "sizeof(short) = " << sizeof(short) << std::endl;
std::cout << "sizeof(int) = " << sizeof(int) << std::endl;
std::cout << "sizeof(long) = " << sizeof(long) << std::endl;
std::cout << "sizeof(long long) = " << sizeof(long long) << std::endl;
return 0;
}
1
2
3
4
sizeof(short) = 2
sizeof(int) = 4
sizeof(long) = 8
sizeof(long long) = 8

对同一个数据类型有不同的范围会很麻烦,所以自从c++11开始,在 <cstdint>中引入了一些范围固定的类型,他们是 int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, 等等

char

char,一个字节,代表八位的整数类型,他默认不一定是signed char, 不同的平台不一样。

他打印的时候会默认打印出字符,如果想要打印出数字,那就加一个+号

虽然他可以打印出字符,但是本质上来讲,他是一个整数

中文字符?

1
2
char16_t c = u'孔';
char32_t c1 = U'良';

当保存一个变量的时候,用int就行,不必要用char,

当保存大量的数据的时候,比如图片,就需要考虑用char和byte。

Bool

注意,他在C中不是一个数据类型。字节为最小单元,虽然只用一个位,但是系统还是分配了一个字节给Bool

true 就是1,当称整数来看就行了

1
2
bool b = true;
int i = b; // the value of i is 1.

会隐式转换,不会编译报错

size_t

他是一个整数,一般用来表示内存的大小或者表达元素的个数,是一个数数的数据类型。

为什么不用int来数数呢?过去我们经常用32位的整数表示内存的大小,一般情况是下足够的。如果用于表达大小,无符号整数他可以表达的最大大小是4GB,如果要表达8GB大小,就不行了,虽然可以用long,但是后续还是引进了size_t类型

  • 无符号类型
  • 他就是sizeof操作符返回的类型
  • 可以存任何大小,你的系统是多少位就可以申请多少位

c++11 固定类型

为了解决类型不固定的问题,c++11 引入固定的字节数int

1
2
3
4
5
6
7
8
#include <cstdint>

int8_t
int16_t
int32_t
int64_t
uint8_t
...

浮点数

思考一个问题: [0, 1]中的实数有无穷多个,但是32位的电脑能表示的数却只有$2^{32}$个,咋办?

因此,电脑只能通过一些代表性的数字进行采样

计算的过程需要控制住误差,一般用的是float和double,float是一个32位的,double是64位表示的浮点数,精度更高一些,更高的有long double 128位

同时,double也会计算的更慢

注意,两个浮点数不可以使用 == , 因为浮点数本身就是一个近似的值,他不准确,因此需要使用

1
2
if (f1 == f2)  //bad
if (fabs(f1 - f2) < FLT_EPSILON) // Good

inf Nan

1
2
3
4
5
6
7
8
9
10
11
12
//nan.cpp
#include <iostream>
using namespace std;

int main()
{
float f1 = 2.0f / 0.0f;
float f2 = 0.0f / 0.0f;
cout << f1 << endl;
cout << f2 << endl;
return 0;
}
1
2
inf
nan

数据类型转换

1
2
3
4
5
6
7
int num_int1 = 9   // 不需要做类型转换,直接赋值过去
int num_int2 = 'C' // 隐式类型转换!‘C’是一个八位的整数,八位变成32位的整数!
int num_int3 = int('C') // 显式类型转换! function-style
int num_int4 = (int)'C' // 显式类型转换! C-style
int num_int5 = 2.8 // double转int,隐式类型转换。舍弃小数位
float num_float = 2.3 // double 转 float
short num_short = 650000 // 650000超过了 short的范围,会变成-5360

最好需要用类型转换

1
float f = 17 / 5; // 会进行整数除法 = 3.f, 不是3.4f

计算的时候就四种类型: int long float double

1
2
3
unsigned char char1 = 255;
unsigned char char2 = 1;
int num = char1 + char2; // why num = 256?

做计算的时候char 会 转为 int。

那么什么时候来使用char呢?保存数据的时候,比如一张图片,只有要保存大量的数据的时候,才需要考虑用到char

 Comments