1. 基本语法 C++14 引入了二进制字面量,允许开发者直接使用二进制数字表示整数,使代码在涉及位操作时更加直观和可读。
下面是基本语法格式:
1 2 int a = 0b101010 ; int b = 0B11110000 ;
二进制数 0b101010 每一位的权值从右向左依次是 20 ,21 ,22 ,…
二进制数 0B11110000 每一位的权值从右向左依次是 20 ,21 ,22 ,…
我们可以通过代码将指定的二进制数值以十进制的格式进行输出,示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <iostream> #include <bitset> int main () { int binary1 = 0b1010 ; int binary2 = 0b11110000 ; int binary3 = 0b100000000 ; std::cout << "0b1010 = " << binary1 << std::endl; std::cout << "0b11110000 = " << binary2 << std::endl; std::cout << "0b100000000 = " << binary3 << std::endl; return 0 ; }
2. 其它字面量修饰符 2.1 有符号/无符号 在C++14 中二进制字面量还可以配合有符号/无符号修饰符使用:
1 2 3 unsigned int a = 0b1010u ; unsigned long b = 0b1010ul ; long long c = 0b1010ll ;
u:unsigned
ul:unsigned long
ll:long long
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <iostream> #include <type_traits> int main () { auto x = 0b1010u ; auto y = 0b1010ul ; auto z = 0b1010ull ; std::cout << "Type of 0b1010u: " << typeid (x).name () << std::endl; std::cout << "Type of 0b1010ul: " << typeid (y).name () << std::endl; std::cout << "Type of 0b1010ull: " << typeid (z).name () << std::endl; return 0 ; }
2.2 数值分割符 C++14 还引入了数字分隔符 ‘(即单引号) ,可以与二进制字面量结合使用,这样可以提供可读性(不影响数值 ):
1 2 int a = 0b1001'0011'1010'0101 ; int b = 0b1111'0000'1100'0011 ;
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <iostream> int main () { int mask1 = 0b1111'0000 ; int mask2 = 0b1000'0000'0000'0000 ; int flags = 0b0010'0101 ; std::cout << "掩码1: " << std::hex << mask1 << std::endl; std::cout << "掩码2: " << std::hex << mask2 << std::endl; std::cout << "标志位: " << std::hex << flags << std::endl; return 0 ; }
数值分割符除了在二进制数据中使用,也可以在其它进制的数值中使用,比如:
1 2 3 4 5 6 long long bigNumber = 1'000'000'000 ; double pi = 3.14159'26535'89793 ; int hex = 0xFF'FF'FF'FF ; int binary = 0b1000'0001'1000'0000 ; int octal1 = 012'345 ; int octal2 = 07'77'777 ;
语法规则总结:
允许的用法
1 2 3 int a = 012'345 ; int b = 0'123'456 ; int c = 07'654'321 ;
不允许的用法
1 2 3 int d = '12345; // ❌ 错误:不能在第一个数字之前 int e = 12345' ; int f = 12 ''345; // ❌ 错误:不能连续使用分隔符
3. 实际应用场景 3.1 位掩码和标志位 下面的代码中展示了如何使用位标志位(bit flags)来管理文件权限,这是一个非常经典的用法:
使用二进制字面量 :0b001 是 C++14 引入的二进制字面量,清晰易读
枚举定义 :FilePermissions 枚举定义了三个权限标志
位运算 :使用 & 运算符检查是否设置了特定权限位
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <iostream> enum FilePermissions { READ = 0b001 , WRITE = 0b010 , EXECUTE = 0b100 }; int main () { int user_perms = 0b111 ; int group_perms = 0b101 ; int other_perms = 0b001 ; if (user_perms & FilePermissions::WRITE) { std::cout << "用户有写权限" << std::endl; } return 0 ; }
3.2 颜色处理 下面的代码中展示了 位运算 在颜色处理中的经典应用,主要目的是将ARGB(Alpha, Red, Green, Blue)四个8位分量打包成一个32位整数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 #include <iostream> #include <iomanip> struct Color { unsigned int argb; Color (unsigned char a, unsigned char r, unsigned char g, unsigned char b) { argb = (a << 24 ) | (r << 16 ) | (g << 8 ) | b; } unsigned char getAlpha () const { return (argb & ALPHA_MASK) >> 24 ; } unsigned char getRed () const { return (argb & RED_MASK) >> 16 ; } void print () const { std::cout << "ARGB: 0x" << std::hex << std::setfill ('0' ) << std::setw (8 ) << argb << std::endl; } }; int main () { constexpr unsigned int ALPHA_MASK = 0b1111'1111'0000'0000'0000'0000'0000'0000 ; constexpr unsigned int RED_MASK = 0b0000'0000'1111'1111'0000'0000'0000'0000 ; constexpr unsigned int GREEN_MASK = 0b0000'0000'0000'0000'1111'1111'0000'0000 ; constexpr unsigned int BLUE_MASK = 0b0000'0000'0000'0000'0000'0000'1111'1111 ; Color red (255 , 255 , 0 , 0 ) ; red.print (); return 0 ; }
关于Color 结构体的成员:
A (Alpha):透明度(0-255,0完全透明,255完全不透明)
R (Red):红色分量
G (Green):绿色分量
B (Blue):蓝色分量
每个分量都是8位(0-255),总共32位
构造函数 - 位运算打包:
1 argb = (a << 24 ) | (r << 16 ) | (g << 8 ) | b;
内存布局 (32位 = 4字节):
1 2 3 字节3 字节2 字节1 字节0 [Alpha] [Red] [Green] [Blue] 0xFF 0xFF 0x00 0x00
位运算分解 :
a << 24:Alpha值左移24位 → 占据最高8位(位31-24)
r << 16:Red值左移16位 → 占据次高8位(位23-16)
g << 8:Green值左移8位 → 占据中间8位(位15-8)
b:Blue值不移动 → 占据最低8位(位7-0)
|(按位或):将四个部分合并
掩码定义 :二进制字面量
1 constexpr unsigned int ALPHA_MASK = 0b1111'1111'0000'0000'0000'0000'0000'0000 ;
0b前缀:C++14引入的二进制字面量
'分隔符:提高可读性(每8位一组)
常量表达式:constexpr 编译期常量
ALPHA_MASK:0xFF000000(提取Alpha分量)
RED_MASK:0x00FF0000(提取Red分量)
可用于提取颜色分量:alpha = (argb & ALPHA_MASK) >> 24
4. 总结 综上所述,关于C++14 的二进制字面量的特性可以做如下总结:
提高代码可读性 :在位操作场景中更直观
配合分隔符 :' 分隔符使长二进制数更易读
编译时友好 :支持编译时计算和常量表达式
类型灵活 :可与各种整数类型修饰符结合使用
在进行项目开发是时候可以灵活使用,这个特性特别适合如下应用场景:
嵌入式开发(寄存器操作)
网络编程(协议标志位)
图形编程(颜色处理)
加密算法(位操作密集)
系统编程(权限控制)