2.1节中介绍了int类型数据,又介绍了位数短的shot和位数长的long类型,本节主要介绍更多的整数类型

char

  • char: type for character, 8-bit integer indeed!
    • char是character的缩写,是个字符,本质上来讲,其是一个八位的整数
  • signed char: signed 8-bit integer,取值范围[-128, 127]
  • unsinged char: unsigned 8-bit integer,取值范围[0, 255] :::info char: either signed char or unsinged char ::: 由于char是整数,其也有有符号char和无符号char。 :::warning 在int类型中,编码时只写一个int,代表有符号整数 signed int;
    但是在char类型中,char 可不代表 signed char;不同平台不同,可能会导致bug,请谨慎选择 :::

char如何表示字符的呢?字符本身就是整数,它有编码。比如ASCII码

  1. // Use an 8-bit integer
  2. char c1 = 'P';
  3. char c2 = 80;
  4. char c3 = 0x50;

上述代码中的c1c2c3 变量的值是一样的。

如果是中文字符有很多个,用8位整数无法表示完全,所以我们需要更多的字节(2个字节16位,4个字节32位)表达,所以就有了char16char32 类型。

  1. char16_t c = u'于'; //c++11
  2. char32_t c = U'于'; //c++11
  1. // char.cpp
  2. // g++ 2.4_char.cpp --std=c++11 && ./a.out
  3. #include <iostream>
  4. using namespace std;
  5. int main()
  6. {
  7. char c1 = 'P';
  8. char c2 = 80;
  9. char c3 = 0x50;
  10. char16_t c4 = u'于';
  11. char32_t c5 = U'于';
  12. cout << c1 << ":" << c2 << ":" << c3 << endl; // 默认当作字符打印
  13. cout << +c1 << ":" << +c2 << ":" << +c3 << endl; // 在char变量前加上+,可以将其转成整数打印
  14. cout << c4 << endl;
  15. cout << c5 << endl;
  16. return 0;
  17. }

我们可以用八位或者十六位或者三十二位的整数表达一个字符,本质来讲char还是整数类型

bool

  • A C++ keyword, but not a C keyword
    • 在JAVA中,bool和整数类型是完全两种不同的类型,不可相互转换;
    • 但是在C/C++中,可以将其看作整数类型
    • C语言中,没有规定bool是一种数据类型。
  • bool width: 1 byte (8 bits), NOT 1 bit!
    • 虽然理论上bool可以使用1bit就可以表示,但是由于计算机存储以字节为最小单位,所以不可能使用1bit给一个变量用,还是给8个位(一个字节)。
  • Value: true (1) or false (0)

What is the output?

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. bool b1 = true;
  6. int i = b1;
  7. bool b2 = -256; // unrecommended conversion. the value of b is true
  8. bool b2 = (-256 != 0); // better choice
  9. cout << "i=" << i << endl;
  10. cout << "b1=" << b1 << endl;
  11. cout << "b2=" << b2 << endl;
  12. cout << true << endl;
  13. return 0;
  14. }

bool类型的b1初始化为True,如果把b1赋值给int类型的i,编译器会自动隐式转换,不会有报错或者警告。
bool类型的b2初始化为-256,在类型转化的时候,只要不为0,总会转化成1。

前面提到在C中并没有定义bool数据类型,那么如何使用?

  1. // 1. Use typedef to create a type
  2. typedef char bool;
  3. #define true 1
  4. #define false 0
  5. //2. Defined in `stdbool.h` since C99
  6. #include <stdbool.h>

size_t

size_t 是整型,一般表达内存大小,或者元素的个数等等,是数数的。为什么要有一个专门的类型,而不使用int类型呢,因为:

  • Computer memory keeps increasing
  • 32-bit int was enough in the past to for data length, But now it is not.

过去,我们经常使用32位整数表示内存大小,即使使用无符号的int,32位全部用来表达长度,最大能表示2.2 More Integer Types - 图1大小的内存,也就是4GB。

size_t:

  • Unsigned integer:无符号整数
  • Type of the result of sizeof operator:同sizeof操作符返回的类型相同
  • Can store the maximum size of a theoretically possible object of any type。32-bit, or 64-bit
    • 当前系统支持多少位,它就会用多少位;如果系统32位,申请4GB以上的内存会出问题。

整数类型的位数表示混乱,C++11之后,引入了cstdint 头文件,定义了整数数据类型

  1. int8_t // 8位有符号整数
  2. int16_t
  3. int32_t
  4. int64_t
  5. uint8_t // 8位无符号整数
  6. uint16_t
  7. uint32_t
  8. uint64_t
  9. ...

前面提到,我们要特别谨慎overflow的情况,为了解决这个问题,提供了一些有用的宏

  1. INT8_MIN // int8的最小值
  2. INT16_MIN
  3. INT32_MIN
  4. INT64_MIN
  5. INT8_MAX // INT8的最大值
  6. INT16_MAX
  7. INT32_MAX
  8. INT64_MAX
  9. ...

如果想把输入的值转成8位整数,可以通过以上的宏来判断其是否在8位整数所能表达的范围内(最大、最小值)。

  1. // intmax.cpp
  2. #include <iostream>
  3. #include <cstdint>
  4. using namespace std;
  5. int main()
  6. {
  7. cout << "INT8_MAX=" << INT8_MAX << endl;
  8. }

Choose appropriate integer types

  • Wider integers consume more memory, and slower sometimes
    • 位数过宽,会耗费大量内存存储数据,

char(byte) is widely used for image pixels
Choose a data type carefully, and consider all possibilities (short for wide dynamic range images)
image.png
图像一般使用char或者byte来存储,如果用int类型存储,其所需要的存储空间更大,还需要乘4倍,如果采用long,就会乘8。

选择合适的数据类型,特别对于数据存储时。