¿Qué significa #x dentro de una macro C?

3 minutos de lectura

avatar de usuario
anders lind

Por ejemplo tengo una macro:

#define PRINT(int) printf(#int "%d\n",int)

Sé cuál es el resultado. Pero, ¿cómo es que #int representa todo el asunto?

Se me olvida un poco este detalle. ¿Puede alguien amablemente darme una pista?

¡Gracias!

  • Posible duplicado de este stackoverflow.com/questions/10676999/stringizing-operator

    – Omkant

    16 de enero de 2013 a las 5:40

En este contexto (aplicado a una referencia de parámetro en una definición de macro), el signo de libra significa expandir este parámetro al texto literal del argumento que se pasó a la macro.

En este caso, si llama PRINT(5) la expansión macro será printf("5" "%d\n", 5); que imprimirá 5 5; no muy útil; sin embargo si llamas PRINT(5+5) la expansión macro será printf("5+5" "%d\n", 5+5); que imprimirá 5+5 10un poco menos trivial.

Este mismo ejemplo se explica en este tutorial sobre el preprocesador C (que, por cierto, es el primer éxito de Google para c macro signo de libra).

  • ¿Es esta función gcc o estándar ANSI C?

    –Anders Lind

    16 de enero de 2013 a las 5:48

  • @AndersLind: Este es un comportamiento estándar. Ver §6.10.3.2/2 que detalla la semántica de la # operador.

    – sueño relajado

    16 de enero de 2013 a las 5:51


  • @dreamlax guau, gracias. Nunca lo uso en mis 10 años de vida como programador… ¡maldita sea!… aunque programo C++ la mayor parte del tiempo

    –Anders Lind

    16 de enero de 2013 a las 5:52

  • Realmente 5+510. Los espacios entre tokens de cadena se ignoran (no se convierten en carácter de espacio “).

    – Fredrick Gauss

    02/08/2014 a las 18:11

  • Ahora bien, esta pregunta es el primer éxito de Google para el “signo de libra macro c” 🙂

    – loco

    20 de abril de 2017 a las 5:56

avatar de usuario
Jack Pekín

“#” puede mostrar el nombre de una variable, es mejor definir la macro así:

#define PRINT(i) printf(#i " = %d\n", i)

y usarlo así:

int i = 5;
PRINT(i);

Resultado mostrado:

i = 5

avatar de usuario
Karthik T

Esa es una mala elección de nombre para el parámetro macro, pero inofensivo (gracias dreamlax).

Básicamente si escribo así

PRINT(5);

Será reemplazado como

printf("5" "%d\n",5);

o

printf("5 %d\n",5);

Es un proceso llamado Stringificación#int se reemplaza con una cadena que consta de su contenido, 5 -> “5”

  • La macro es expandida por el preprocesador que no tiene conocimiento del sistema de tipo C. Hasta donde tengo entendido int no rompe ninguna regla en §6.10 (Directivas de preprocesamiento), pero estoy de acuerdo en que es una mala elección.

    – sueño relajado

    16 de enero de 2013 a las 5:46

  • Su enlace a la documentación de Stringification está inactivo, por favor actualícelo.

    – Muerte por tensores

    16 mayo 2017 a las 18:45

  • @DrewBuckley arreglado!

    – Karthik T.

    17 de mayo de 2017 a las 9:36

  • "5 %d\n" incorrecto "5%d\n" Correcto

    – usuario16217248

    14 de enero a las 4:53

avatar de usuario
Aagam Shet

‘#’ se llama operador de cadena. El operador Stringize pone comillas alrededor del parámetro pasado y devuelve una cadena. Solo se usa en sentencias marco que toman los argumentos.

#include<stdio.h> 

#define stringLiteral(sl) #sl

int main()
{
   char StringizeOpreator="a"; 
   printf(stringLiteral(StringizeOpreator));
   return 0;
}

Aquí el stringLiteral marco toma el argumento formal sl y regresa #sl. El argumento real pasado es StringizeOpreator variable. La declaración de devolución #sl posee # operador, que pone comillas alrededor del argumento como "StringizeOpreator" y devuelve una cadena.

Entonces, la salida del programa anterior es el nombre del parámetro real ‘StringizeOpreator’ en lugar del valor almacenado en el parámetro real pasado.

output :
StringizeOperator
...
exitcode 0

Para saber más visita este enlace:
Operador de cadena

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad