位操作
位操作函数
<stdbit.h> 是 C23 引入的头文件,提供一组面向无符号整数类型的位操作工具。
注意
- 这些接口要求实现支持 C23;老版本编译器可能不存在该头文件。
- 多数接口要求实参为无符号整数类型;把有符号整数直接传入可能会触发不符合预期的转换。
常用能力包括:
- 统计 1/0 的个数:
stdc_count_ones/stdc_count_zeros - 统计前导/尾随 0/1:
stdc_leading_zeros/stdc_trailing_zeros/stdc_leading_ones/stdc_trailing_ones - 位宽与取整:
stdc_bit_width/stdc_bit_floor/stdc_bit_ceil - 单比特判断:
stdc_has_single_bit - 循环移位:
stdc_rotate_left/stdc_rotate_right
它们通常还提供若干“按类型区分”的版本,例如:
stdc_count_ones_ui:以unsigned int为主要目标类型stdc_count_ones_ul:以unsigned long为主要目标类型stdc_count_ones_ull:以unsigned long long为主要目标类型
示例:统计二进制 1 的个数
c
#include <stdio.h>
#include <stdbit.h>
int main(void) {
unsigned int x = 0xF0u; /* 11110000b */
printf("ones = %u\n", stdc_count_ones_ui(x));
return 0;
}1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
端序
端序是构成多字节对象的字节的顺序。更多相关内容请参考 Wikipedia。
在 <stdbit.h> 中定义了三个宏,用来表示标量类型的端序:
__STDC_ENDIAN_BIG____STDC_ENDIAN_LITTLE____STDC_ENDIAN_NATIVE__
- 如果标量类型为小端序,则
__STDC_ENDIAN_NATIVE__等于__STDC_ENDIAN_LITTLE__; - 如果标量类型为大端序,则
__STDC_ENDIAN_NATIVE__等于__STDC_ENDIAN_BIG__。 - 如果既不使用大端序,也不使用小端序,则
__STDC_ENDIAN_NATIVE__既不等于__STDC_ENDIAN_BIG__,也不等于__STDC_ENDIAN_LITTLE__。
示例:
c
#include <stdio.h>
#include <stdbit.h>
int main(void) {
if (__STDC_ENDIAN_NATIVE__ == __STDC_ENDIAN_BIG__) {
printf("大端序\n");
} else if (__STDC_ENDIAN_NATIVE__ == __STDC_ENDIAN_LITTLE__) {
printf("小端序\n");
} else {
printf("未知的端序\n");
}
return 0;
}1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
习题
#11751
⚡3⏳2
写一个程序:从标准输入读入一个 unsigned int,输出它的二进制 1 的个数。
要求:
- 使用
<stdbit.h>的stdc_count_ones_ui; - 输入失败时退出。
#11752
⚡4⏳2
写一个程序:从标准输入读入一个 unsigned int x 和一个非负整数 k,输出把 x 循环左移 k 位的结果。
要求:使用 stdc_rotate_left_ui。