2009-11-06 14 views
6

¿Qué es a##b & #a?¿Cómo funciona este código C?

#define f(a,b) a##b 
    #define g(a) #a 
    #define h(a) g(a) 

    main() 
    { 
      printf("%s\n",h(f(1,2))); //how should I interpret this?? [line 1] 
      printf("%s\n",g(f(1,2))); //and this? [line 2] 
    } 

¿Cómo funciona este programa?


La salida es

12 
f(1, 2) 

Ahora entiendo cómo a##b & #a trabajo. Pero, ¿por qué el resultado es diferente en los dos casos (línea 1 y línea 2)?

+3

¿Qué sucede cuando ejecutas ese programa? Hacer eso debería ayudarte a entender lo que está sucediendo. –

+1

Realmente, jugar un rato con ese código arrojará luz. Y si tienes preguntas específicas, no dudes en preguntarlas aquí. – sharptooth

Respuesta

19

El ## concatena dos tokens juntos. Solo se puede usar en el preprocesador.

f(1,2) se convierte en 1 ## 2 se convierte en 12.

El operador # por sí mismo stringifies símbolos: #a se convierte en "a". Por lo tanto, g(f(1,2)) se convierte en "f(1,2)" cuando el preprocesador termina con él.

h(f(1,2)) es efectivamente #(1 ## 2) que se convierte en #12 que se convierte en "12" cuando el preprocesador se ejecuta sobre él.

4

a ## b pegará el código togather.

tan f (1,2) se convertirá en 12

+2

Eso es solo la mitad del problema. –

0

un ## b es el contatenation de cadena de la literales a y b, por lo que f (1,2) es "12"

#A es la cadena literal a, so g (3) es "3"

3

La macro f (a, b) concatena sus argumentos, g (a) convierte sus argumentos en una cadena y h (a) es macro auxiliar para g (a). Creo que seria:

12 
f(1,2) 

La razón es que la h (a) macro hace que su argumento sea completa expandida antes de pasarla a g (a), mientras que g (a) se llevará a sus argumentos, literalmente, sin ampliar ellos primero.

+0

¿por qué el segundo printf termina en '" f (1,2) "' en lugar de '" 12 "'? – Moeb

+0

por qué ocurre esto: '" La razón es que la macro h (a) hace que su argumento se expanda por completo antes de pasarlo a g (a) mientras que g (a) tomará sus argumentos literalmente sin expandirlos primero ". ? – Moeb

0

## es el operador de macro concatenación. Entonces, por ejemplo, f(foo,bar) sería equivalente a foobar.

5

Para preguntas como estas (y también más problemas del "mundo real" que tienen que ver con el preprocesador), me resulta muy útil leer el código, después de que haya sido preprocesado.

cómo hacer esto varía con el compilador, pero con gcc, se utilizaría la siguiente:

$ gcc -E test.c 

(snip) 
main() 
{ 
     printf("%s\n","12"); 
     printf("%s\n","f(1,2)"); 
} 

Por lo tanto, se puede ver que los símbolos han sido a la vez concatenados, y se convirtió en una cadena.

+0

¿por qué el segundo printf termina en '" f (1,2) "' en lugar de '" 12 "'? – Moeb

+0

@hanifr: Porque la macro g() stringifica su argumento, supongo. – unwind

0
 
    #define f(a,b) a##b 
    #define g(a) #a 
    #define h(a) g(a) 

Así, ## combinar 2 partes directamente entre sí, sin importar qué tipo son ... darle un ejemplo .. printf("%d\n",f(1,2)); que presentamos lo 12, que significa aquí f (1,2) es 12 un entero.

 
    int a2 = 100; 
    printf("%d\n",f(a,2)); 

aquí f (a, 2) es la etiqueta. apunta a una etiqueta en el contexto del código, si no hay int a2 = 100, se obtienen errores de compilación. Y #a convierte lo que sea, en una cadena ... Y luego h(a) g(a) Es muy extraño ... Parece que cuando llamas a h (a), se convierte en g (a), y pasa a a g (a), en primer lugar, interpreta lo que es. entonces, antes de que puedas g (a), a se transforma en f (a, b) = a ## b = 12

Cuestiones relacionadas