c - 用C代码编写二进制数字系统

标签 c

<分区>

当我们对十六进制数使用 0x 前缀,对八进制数使用 0 时,对于二进制数有什么可以做的吗?

我尝试了 b 后缀,但是 GCC不允许。

Error: invalid suffix "b" on integer constant

这可能吗?

最佳答案

标准 C 没有定义二进制常量。虽然有一个 GNU C 扩展(在流行的编译器中,clang 也对其进行了调整):0b0B 前缀:

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

所以clang完全消除了对该函数的调用,并将其返回值替换为101。整洁吧?

关于c - 用C代码编写二进制数字系统,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15114140/

相关文章:

c - 为什么像这样使用指针会导致构建崩溃?

c - C 应用程序中未处理的 win32 异常

c - 分配和分配 : different memory size allocated

c - 用于控制firewalld的D-Bus API或C库

c - 如何将结构映射为共享匿名内存?

c - 错误 : invalid value 'precompiled-header' in '-x precompiled-header'

c - 函数原型(prototype)声明

c - 通过 shell 命令获取 C 应用程序的参数

c - 如何为 CreateProcess() 启动的进程设置语言环境

c - 在二进制文件中寻找模式