~运算符只能对整型单个元素按位取反,不能作用于整个数组;必须遍历每个元素单独使用,否则报错;对有符号数取反可能得负值,建议用unsigned类型避免陷阱。

用 ~ 运算符对数组元素逐个取反
按位取反在 C++ 中只能作用于整型(int、unsigned int、char 等),不能直接对整个数组操作。必须遍历每个元素,对每个值单独使用 ~ 运算符。
常见错误是误以为 ~arr 能反转整个数组,实际会触发类型不匹配错误或对指针取反(如 error: invalid operand of type 'int *' to binary 'operator~')。
-
~是单目运算符,作用于单个整数,结果是该数所有二进制位翻转(0→1,1→0) - 对有符号整数(如
int)取反后可能得到负值,例如~1在 32 位系统上是-2(补码表示) - 若需保持无符号语义,建议显式使用
unsigned类型,比如unsigned char或uint8_t - 示例:
int arr[] = {1, 2, 3};<br>for (int& x : arr) x = ~x;执行后arr变为{-2, -3, -4}(取决于平台整型宽度和符号规则)
注意 char 类型的符号性陷阱
在多数编译器中,char 默认是有符号的,~ 对其取反后可能产生负值,再赋回 char 时发生截断或符号扩展,行为易出错。
- 比如
char c = 0xFF;(即 -1),~c先提升为int再取反:先变成0xFFFFFFFF(-1 的补码),再取反得0x00000000→0;但若c = 1,~c是-2,赋给char后仍是-2(即0xFE) - 更安全的做法是统一用
unsigned char:unsigned char bytes[] = {0x0F, 0xF0};<br>for (auto& b : bytes) b = ~b; // 得到 {0xF0, 0x0F} - 避免隐式类型提升干扰:不要写
char x = ~y;,而应写char x = static_cast<char>(~static_cast<unsigned char>(y));</unsigned></char>(仅当必须用char时)
对 std::array 或 std::vector 的处理方式一致
std::array 和 std::vector 不改变底层按位取反的逻辑——仍需遍历 + ~。区别只在语法糖和边界检查。
-
std::array<int> a = {1,2,3,4}; for (auto& x : a) x = ~x;</int>完全合法且高效 -
std::vector<uint8_t> v = {0xAA, 0x55}; for (auto& x : v) x = ~x;</uint8_t>同样适用,注意uint8_t是unsigned,结果可预测 - 别用
std::transform加std::bit_not:它要求函数对象返回同类型,而std::bit_not<int>()(x)</int>返回int,对uint8_t容器会引发隐式转换风险,不如手写循环清晰
性能与对齐无关,但要注意常量表达式限制
按位取反本身是极快的 CPU 指令(NOT),不存在性能瓶颈。真正容易被忽略的是:如果想在编译期完成取反(比如用于 constexpr 数组初始化),必须确保操作数是字面量且类型支持常量求值。
-
constexpr unsigned x = ~0x0F;合法,结果是0xFFFFFFF0(取决于unsigned宽度) - 但
constexpr std::array<int> a = {{1, 2}};</int>之后无法再constexpr地对其取反——C++20 前不支持对容器元素做运行期外的修改 - 若需编译期反转,得手动展开或用模板递归生成,例如:
template<size_t... i> constexpr auto flip_arr(std::index_sequence<i...>) {<br> return std::array{~vals[I]...};<br>}</i...></size_t...>
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











