参见英文答案 >
Can I use a binary literal in C or C++?19
当我们对十六进制数使用0x前缀,而对于八进制数使用o时,有没有什么可以用于二进制数?
当我们对十六进制数使用0x前缀,而对于八进制数使用o时,有没有什么可以用于二进制数?
我尝试b后缀,但GCC不允许.
Error: invalid suffix “b” on integer constant
可能吗?
解决方法
标准C不定义二进制常数.有一个GNU(我相信)扩展(在流行的编译器中,cl声也适应它):0b前缀:
int foo = 0b1010;
如果你想坚持标准的C,那么有一个选择:你可以组合一个宏和一个函数来创建一个几乎可读的“二进制常量”功能:
#define B(x) S_to_binary_(#x) static inline unsigned long long S_to_binary_(const char *s) { unsigned long long i = 0; while (*s) { i <<= 1; i += *s++ - '0'; } return i; }
然后你可以这样使用它:
int foo = B(1010);
如果打开重型编译器优化,编译器将很可能完全消除函数调用(常量折叠),或至少内联它,因此这甚至不会是性能问题.
证明:
以下代码:
#include <stdio.h> #include <stdlib.h> #include <limits.h> #include <string.h> #define B(x) S_to_binary_(#x) static inline unsigned long long S_to_binary_(const char *s) { unsigned long long i = 0; while (*s) { i <<= 1; i += *s++ - '0'; } return i; } int main() { int foo = B(001100101); printf("%d\n",foo); return 0; }
已经使用clang -o baz.S baz.c -Wall -O3 -S编译,并且它生成了以下程序集:
.section __TEXT,__text,regular,pure_instructions .globl _main .align 4,0x90 _main: ## @main .cfi_startproc ## BB#0: pushq %rbp Ltmp2: .cfi_def_cfa_offset 16 Ltmp3: .cfi_offset %rbp,-16 movq %rsp,%rbp Ltmp4: .cfi_def_cfa_register %rbp leaq L_.str1(%rip),%rdi movl $101,%esi ## <= This line! xorb %al,%al callq _printf xorl %eax,%eax popq %rbp ret .cfi_endproc .section __TEXT,__cstring,cstring_literals L_.str1: ## @.str1 .asciz "%d\n" .subsections_via_symbols