Standard C nie definiuje stałych binarnych. Jest GNU (wierzę) rozszerzenie chociaż (wśród popularnych kompilatorów, dzyń dostosowuje je również): the 0b
prefix:
int foo = 0b1010;
Jeśli chcesz trzymać się standardowej C, to nie ma opcji: można połączyć makro i funkcją stworzyć prawie czytelny „binarny” stałą cechę:
#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;
}
i wtedy można go używać tak:
int foo = B(1010);
Jeśli włączysz optymalizację kompilatorów, najprawdopodobniej kompilator najprawdopodobniej całkowicie wyeliminuje wywołanie funkcji (stałe składanie) lub przynajmniej je podkreśli, więc nie będzie to nawet problem z wydajnością.
Dowód:
Poniższy kod:
#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;
}
został skompilowany przy użyciu clang -o baz.S baz.c -Wall -O3 -S
i wyprodukowany następujący montaż:
.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
Więc clang
całkowicie wyeliminowane wywołanie funkcja i zastąpił jej wartość zwracaną przez 101
. Schludnie, co?
Literały binarne nie istnieją w C. Najbliższe są szesnastkowe, ponieważ ściśle podążają za binarnym wzorem bitowym. –
Hex na binarny jest bardzo łatwy do konwersji. –
Oktal jest również dostępny, napisany 0666 i tak (/ moje kaczki i działa) – vonbrand