2011-11-01 14 views
6

Ha pasado un tiempo desde que programé en C/C++. Por mi vida, no puedo recordar (o encontrar en Google) cómo hacer que esto funcione. Me pareció que había una forma abreviada de escribir una cadena de repetición de bytes, así:notación abreviada de bytes en C/C++?

0x00 => 0x00000000 
0xFF => 0xFFFFFFFF 
0xCD => 0xCDCDCDCD 

Así por ejemplo, si declaro

int x = 0xCD; 
printf("%d", x) // prints "3452816845", not "205". 

Sin utilizar bitshifts (es decir, el preprocesador lo maneja). ¿Me estoy volviendo loco? PD Estoy usando Microsoft Visual C++ 2010

+9

Nada de esto existe. –

+1

@Justin: ¡Uno de nosotros se está volviendo loco, y no creo que sea yo! :-) ¿Qué tipo de taquigrafía crees que podría ser? Una conversión de formato?¿Un factor de repetición en una declaración? ¿Un bucle implícito? – wallyk

+2

Es difícil imaginar esa característica en C o C++ si solo porque no hay muchos lugares en los que sería útil. –

Respuesta

2

A menos que escriba su propia macro, esto es imposible. ¿Cómo sabría cuánto tiempo repetir? 0xAB podría significar 0xABABABABABABABABABABAB por todo lo que sabe (utilizando la idea propuesta).

+0

Lo repetiría dependiendo del tipo. – Jay

+1

Si es necesario, use una macro como lo sugerí yo y duskwuff. – jli

+1

@Justin: No, no sería así. C y C++ no se inicializan de esa manera. Existe el tipo de inicializador, el tipo de variable y las formas de conversión de uno a otro. El tipo y el valor del inicializador no se ven afectados por el tipo de variable. ¿Estás seguro de que estás pensando en C o C++? –

2

No existe una taquigrafía. 0x00 es lo mismo que 0. 0xFF es lo mismo que 0x000000FF.

+2

... aunque '0x00' es hexadecimal y' 0' es octal. :-) –

8

No hay nada como eso por defecto en C. Hay algo similar en CSS (el color #123 se expande a #112233), pero eso es completamente diferente. :)

Se puede escribir una macro para que lo haga por usted, sin embargo, como:

#define REPEAT_BYTE(x) ((x) | ((x) << 8) | ((x) << 16) | ((x) << 24)) 
... 
int x = REPEAT_BYTE(0xcd); 
1

Usted podría utilizar alguna plantilla engaño:

#include <iostream> 
#include <climits> 

using namespace std; 

template<typename T, unsigned char Pattern, unsigned int N=sizeof(T)> 
struct FillInt 
{ 
    static const T Value=((T)Pattern)<<((N-1)*CHAR_BIT) | FillInt<T, Pattern, N-1>::Value; 
}; 

template<typename T, unsigned char Pattern> 
struct FillInt<T, Pattern, 0> 
{ 
    static const T Value=0; 
}; 

int main() 
{ 
    cout<<hex<<FillInt<unsigned int, 0xdc>::Value<<endl; // outputs dcdcdcdc on 32 bit machines 
} 

que se adapta automáticamente al tipo integral pasado como primer argumento y está completamente resuelto en tiempo de compilación, pero esto es solo por diversión, no creo que usaría tal cosa en código real.

13

La forma más sencilla es:

0x1010101u * x 

No puedo pensar en ninguna sintaxis que posiblemente podría ser más simple o más explica por sí mismo ...

Editar: Te veo lo quieren para trabajar para tipos arbitrarios. Como solo tiene sentido para los tipos sin firmar, supongo que estás usando un tipo sin firmar. A continuación, intente

#define REPB(t, x) ((t)-1/255 * (x)) 
+3

¡Eso es brillante! –

2

Nope. Pero se puede usar memset:

int x; 
memset(&x, 0xCD, sizeof(x)); 

Y se podría hacer una macro de que:

#define INITVAR(var, value) memset(&(var), (int)(value), sizeof(var)) 
int x; 
INITVAR(x, 0xCD); 
1

Usted puede utilizar el preprocesador concatenación token:

#include <stdio.h> 
#define multi4(a) (0x##a##a##a##a) 

int main() 
{ 
    int a = multi4(cd); 
    printf("0x%x\n", a); 
    return 0; 
} 

Resultado:

0xcdcdcdcd 

Por supuesto, y Debe crear una nueva macro cada vez que desee crear un "generador" con un número diferente de repeticiones.