C++初学者指南第一步—4.基本类型
文章目录
- C++初学者指南第一步---4.基本类型
基本类型是所有复杂类型(如列表、哈希映射、树、图等)的基本构建块。
1.变量声明
变量声明的基本语法
type variable = value;
type variable {value}; C++11
// 声明 & 初始化 'i':
int i = 1;
// 打印‘i’的值:
cout << i << '\n';  
int j {5};
cout << j << '\n';

 注意:基本类型的变量默认不会被初始化!
int k;  // k不会被初始化!
cout << k << '\n';  // k可能是任何值
因为在c++中,你只需要为你使用的内存付出代价(大内存块的初始化可能相当昂贵)。
 注意:但是: 在声明变量时,你几乎总是需要对其进行初始化,以防止出现bug!
2.快速概览
Booleans 布尔型
bool b1 = true;
bool b2 = false;
Characters 字符型
- 最小整数;通常为1字节
- 在x86/x86_64平台上,signed(有符合) 类型值的范围为[-128,127]。
Signed Integers 有符号整数
n bits ⇒ values ∈ [ 
     
      
       
       
         − 
        
        
        
          2 
         
         
         
           n 
          
         
           − 
          
         
           1 
          
         
        
       
      
        -2^{n-1} 
       
      
    −2n−1,  
     
      
       
        
        
          2 
         
         
         
           n 
          
         
           − 
          
         
           1 
          
         
        
       
      
        2^{n-1} 
       
      
    2n−1-1]
 n位数 ⇒ 值属于 [ 
     
      
       
       
         − 
        
        
        
          2 
         
         
         
           n 
          
         
           − 
          
         
           1 
          
         
        
       
      
        -2^{n-1} 
       
      
    −2n−1, 
     
      
       
        
        
          2 
         
         
         
           n 
          
         
           − 
          
         
           1 
          
         
        
       
      
        2^{n-1} 
       
      
    2n−1-1] 的范围
short s = 7;        
int   i = 12347;
long  l1 = -7856974990L;
long long  l2 = 89565656974990LL;
// ' C++14增加的数字分隔符,
long l3 = 512'232'697'499;
Unsigned Integers 无符号整数
n bits ⇒ values ∈ [0,  
     
      
       
        
        
          2 
         
         
         
           n 
          
         
           − 
          
         
           1 
          
         
        
       
      
        2^{n-1} 
       
      
    2n−1]
 n位数 ⇒ 值属于 [0,  
     
      
       
        
        
          2 
         
         
         
           n 
          
         
           − 
          
         
           1 
          
         
        
       
      
        2^{n-1} 
       
      
    2n−1] 的范围
unsigned u1 = 12347U; 
unsigned long u2 = 123478912345UL;  
unsigned long long u3 = 123478912345ULL;  
// 非10进制
unsigned x = 0x4A;        // 16进制
unsigned b = 0b10110101;  // 二进制 C++14
Floating Point Types 浮点数类型
- float 通常为IEEE 754格式32位。
- double 通常为IEEE 754格式64位。
- long double 在x86/x86-64上通常为80位。
float       f  = 1.88f;
double      d1 = 3.5e38;
long double d2 = 3.5e38L; C++11
// ' digit separator C++14
double d3 = 512'232'697'499.052;
3.Common Number Representations 常用的数字表示常用数字的表示方法

 浮点数工具:值映射的交互式可视化工具
4.Arithmetic Operations 算术运算
- 表达式 a ⊕ b 返回操作⊕应用于 a 和 b值的结果
- 表达式 a ⊕= b 存储 a中操作⊕的结果
| 代码 | 注释 | 
|---|---|
| int a = 4; int b = 3; | 变量a设置为值4 变量b设置为值3 | 
| a = a + b; a += b; | a: 7 加法运算 a: 10 | 
| a = a - b; a -= b; | a: 7 减法运算 a: 4 | 
| a = a * b; a *= b; | a: 12 乘法运算 a: 36 | 
| a = a / b; a /= b; | a: 12 除法运算 a: 4 | 
| a = a % b; | a: 1 除法余数运算(取模) | 
Increment/Decrement 递增/递减
- 将值更改为递增1/递减 1
- 前缀表达式 ++x / --x 返回新的(递增/递减)值
- 后缀表达式 x++ / x-- 增加/减少值,但返回旧值
| 代码 | 注释 | 
|---|---|
| int a = 4; int b = 3; | a: 4 b: 3 | 
| b = a++; b = ++a; | a: 5 b: 4 a: 6 b: 6 | 
5.Comparisons 比较运算
2-way Comparisons 二元比较
比较结果为 true 或 false
| 代码 | 注释 | 
|---|---|
| int x = 10; int y = 5; | |
| bool b1 = (x == 5); bool b2 = (x != 6); | false 相等比较 true 不相等比较 | 
| bool b3 = x > y; bool b4 = x < y; bool b5 = y >= 5; bool b6 = x <= 30; | true 大于比较 false 小于比较 true 大于等于比较 true 小于等于比较 | 
3-Way Comparisons With <=> 三元比较用<=> C++20
确定 2 个对象的相对顺序:
 (a <=> b) < 0 如果 a < b
 (a <=> b) > 0 如果 a > b
 (a <=> b) == 0 如果 a 和 b 相等
- 三元比较返回一个可与字面量 0 比较的比较类别值
- 返回的值来自三种可能的类别之一:std::strong_ordering、std::weak_ordering 或 std::partial_ordering
4 <=> 6 → std::strong_ordering::less
 5 <=> 5 → std::strong_ordering::equal
 8 <=> 1 → std::strong_ordering::greater
6.布尔型逻辑运算
操作符
bool a = true;
bool b = false;
bool c = a && b;   // false    逻辑与 AND
bool d = a || b;   // true     逻辑或 OR
bool e = !a;       // false    逻辑非 NOT
// 备选的拼写:
bool x = a and b;  // false
bool y = a or b;   // true
bool z = not a;    // false
转换为布尔型
- 0 始终为 false;
- 其他一切都是true;
bool f = 12;   // true   (int → bool)
bool g = 0;    // false  (int → bool)
bool h = 1.2;  // true   (double → bool)
短路求值
如果出现以下情况,则不计算布尔比较的第二个操作数 在计算第一个操作数后,结果已经知道了。
int i = 2;  
int k = 8;
bool b1 = (i > 0) || (k < 3);
i > 0 已经是true ,k < 3不计算,因为逻辑或的结果已经是true。
7.基础类型的内存大小
所有类型大小都是 sizeof(char) 的倍数
cout << sizeof(char);   // 1
cout << sizeof(bool);   // 1
cout << sizeof(short);  // 2
cout << sizeof(int);    // 4
cout << sizeof(long);   // 8
// number of bits in a char
cout << CHAR_BIT;   // 8
char   c = 'A';
bool   b = true;
int    i = 1234;
long   l = 12;
short  s = 8;

 大小取决于平台
 C++仅提供基本保证
- sizeof(short) ≥ sizeof(char)
- sizeof(short) ≥ sizeof(char)
- sizeof(int) ≥ sizeof(short)
- sizeof(int) ≥ sizeof(short)
- sizeof(long) ≥ sizeof(int)
- sizeof(long) ≥ sizeof(int)
例如,在某些 32 位平台上: int = long
整数大小保证 C++11
#include <cstdint>
- 精确尺寸(在某些平台上不可用)
 int8_t, int16_t, int32_t, int64_t, uint8_t, …
- 保证最小尺寸
 int_least8_t, uint_least8_t, …
- 速度最快且保证最小尺寸
 int_fast8_t, uint_fast8_t, …
固定宽度浮点类型保证 C++23
#include <stdfloat>
// storage bits: sign + exponent + mantissa(存储位: 符号 + 指数 + 尾数)
std::float16_t  a = 12.3f16;   // 1 +  5  +  10 =  16 bits =  2 B
std::float32_t  b = 12.3f32;   // 1 +  8  +  23 =  32 bits =  4 B
std::float64_t  c = 12.3f64;   // 1 + 11  +  52 =  64 bits =  8 B
std::float128_t d = 12.3f128;  // 1 + 15  + 112 = 128 bits = 16 B
std::bfloat16_t e = 12.3b16;   // 1 +  8  +   7 =  16 bits =  2 B
8.std::numeric_limits (数值范围模板类)
#include <limits>
// smallest negative value:(double类型的最小负值)
cout << std::numeric_limits<double>::lowest();
// float/double: smallest value > 0 (float/double类型的最小正值)
// integers: smallest value
cout << std::numeric_limits<double>::min();
// largest positive value:(可以表示的最大正值)
cout << std::numeric_limits<double>::max();
// smallest difference btw. 1 and next value:(1和下一个值之间最小差值,用于浮点数比较)
cout << std::numeric_limits<double>::epsilon();
…

 cppreference:数值限制
9.Type Narrowing类型缩小(类型窄化)
- 从可以表示更多值的类型转换为可以表示更少值的类型
- 可能会导致信息丢失
- 一般来说,没有编译器警告——默默地发生
- 隐藏的潜在运行时错误来源
double   d = 1.23456;
float    f = 2.53f;
unsigned u = 120u;
double e = f;  // OK  float → double
int i = 2.5;   // 缩小 double → int
int j = u;     // 缩小 unsigned int → int
int k = f;     // 缩小 float → int
10.花括号初始化(统一初始化)C++11
type variable { value };
- 适用于所有基本类型
- 缩小转换 ⇒ 编译器警告
double   d {1.23456};  // OK
float    f {2.53f};    // OK
unsigned u {120u};     // OK
double e {f};  // OK float → double
int i {2.5};   //  COMPILER WARNING: double       → int
int j {u};     //  COMPILER WARNING: unsigned int → int
int k {f};     //  COMPILER WARNING: float        → int
注意:确保防止静默类型转换,特别是将无符号整数转换缩小为有符号整数转换——它们会导致难以发现的运行时错误!
11.位运算
Bitwise Logic 按位逻辑运算
| 表达式 | 说明 | 
|---|---|
| a & b | AND按位与 | 
| a | b | OR按位或 | 
| a ^ b | XOR按位异或 | 
| ~a | NOT按位反(反码) | 
#include <cstdint>
std::uint8_t a = 6;  
std::uint8_t b = 0b00001011;
std::uint8_t c1 = (a & b);  // 2
std::uint8_t c2 = (a | b);  // 15
std::uint8_t c3 = (a ^ b);  // 13
std::uint8_t c4 = ~a;       // 249
std::uint8_t c5 = ~b;       // 244
// test if int is even/odd:
bool a_odd  = a & 1;
bool a_even = !(a & 1);
memory bits:
0000 0110
0000 1011
0000 0010
0000 1111
0000 1101
1111 1001
1111 0100
result:
0 ⇒ false
1 ⇒ true
Bitwise Shifts 按位移位
| 表达式 | 说明 | 
|---|---|
| x << n | 返回 x 的值,其位向左移动 n 位 | 
| x >> n | 返回 x 的值,其位向右移动 n 位 | 
| x <<= n | 通过向左移动 n 位来修改 x | 
| x >>= n | 通过向右移动 n 位来修改 x | 
#include <cstdint>
std::uint8_t a = 1;
a <<= 6;  // 64
a >>= 4;  // 4
std::uint8_t b1 = (1 << 1);  // 2
std::uint8_t b2 = (1 << 2);  // 4
std::uint8_t b3 = (1 << 4);  // 16
memory bits:
0000 0001
0100 0000
0000 0100
0000 0010
0000 0100
0001 0000
注意:把一个数据类型为N位的对象移动N位或更多位是未定义行为!
std::uint32_t i = 1;  // 32 bit type
i <<= 32;   未定义行为!
std::uint64_t j = 1;  // 64 bit type
j <<= 70;   未定义行为!
12.算术转换和提升
很遗憾,这里有一大堆规则(可以追溯到C语言)的目的是确定二元运算的两个操作数和结果的共同类型
 Operand A ⊕ Operand B → Result
简单总结
涉及至少一种浮点类型的运算
- long double ⊕ any other type → long double
- double ⊕ float → double
- double ⊕ any integer → double
- float ⊕ any integer → float
两种整数类型的运算
- 先对两个操作数执行整数提升:基本上任何小于int的值都会被提升为int或unsigned int(取决于哪一种类型可以表示未提升类型的所有值)
- 如果两个操作数类型不同,则应用整数转换:
- 两个有符号:较小类型转换为较大类型
- 两个无符号:较小类型转换为较大类型
- 有符号 ⊕ 无符号: 
  - 如果两者位宽相同,有符号转换为无符号
- 否则,如果无符号类型可以表示有符号类型的所有值,无符号转换为有符号
- 否则,两者都转换为无符号
 
附上原文链接
 翻译和整理文章不易,如果文章对您有用请随手点个赞,谢谢!










