2011-01-21 8 views
5
unsigned char *adata = (unsigned char*)malloc(500*sizeof(unsigned char)); 
unsigned char *single_char = adata+100; 

¿Cómo cambio los primeros cuatro bits en single_char para representar valores entre 1..10 (int)?Cómo cambiar 4 bits en char sin signo?

La pregunta vino de estructura de la cabecera TCP:

Data Offset: 4 bits 

The number of 32 bit words in the TCP Header. This indicates where 
the data begins. The TCP header (even one including options) is an 
integral number of 32 bits long. 

Por lo general, tiene un valor de 4..5, el valor char es como 0xA0.

Respuesta

7

Suponen que ha inicializado * single_char a algún valor. De lo contrario, la solución café publicada hace lo que necesita.

(*single_char) = ((*single_char) & 0xF0) | val;

  1. (*single_char) & 11110000 - Restablece los bajos 4 bits a 0
  2. | val - Establece los últimos 4 bits a valor (suponiendo val es < 16)

Si desea para acceder a los últimos 4 bits, puede usar unsigned char v = (*single_char) & 0x0F;

If y Si desea acceder a los 4 bits superiores, puede cambiar la máscara 4, es decir.

unsigned char v = (*single_char) & 0xF0;

y para establecer ellos:

(*single_char) = ((*single_char) & 0x0F) | (val << 4);

+1

En el caso específico de la cabecera TCP, los 4 bits más bajos de este octeto están reservados y deben ser cero. – caf

+1

Ah bien, entonces su solución es mejor :) – GWW

+0

@GWW, al final, fue su solución la que funcionó para mí. Pero ocasionalmente establece valores extraños ... (por ejemplo, single_char se convierte en hexadecimal 0x86 en lugar de 0x80). –

3

Puede usar bitwise operators para acceder a bits individuales y modificar de acuerdo con sus requisitos.

6

Esto establecerá el alto 4 bits de *single_char a los datos de corrección, y borrar los 4 bits inferiores:

unsigned data_offset = 5; /* Or whatever */ 

if (data_offset < 0x10) 
    *single_char = data_offset << 4; 
else 
    /* ERROR! */ 
+0

¿Cambiará los primeros 4 bits y no afectará a los bits más bajos de todos modos? ¡Gracias! –

+0

@mhambra: "primero" es una cuestión de notación: cambiará los * 4 bits más significativos, que es lo que quiere para ese campo del encabezado TCP. Como escribí, borrará (cero) los 4 bits más bajos, y esto es lo que quiere para el encabezado TCP, donde esos 4 bits más bajos están reservados y deben ser cero. – caf

2

Sé que esta es una publicación anterior, pero no quiero que otros lean artículos largos sobre operadores bit a bit para obtener una función. ción similar a éstos -

//sets b as the first 4 bits of a(this is the one you asked for 
void set_h_c(unsigned char *a, unsigned char b) 
{ 
    (*a) = ((*a)&15) | (b<<4); 
} 

//sets b as the last 4 bits of a(extra) 
void set_l_c(unsigned char *a, unsigned char b) 
{ 
    (*a) = ((*a)&240) | b; 
} 

espero que ayude a alguien en el futuro

Cuestiones relacionadas