Cómo encadenar una expresión en C

¿Hay una manera de evaluar una expresión antes de la estratificación en c?

ejemplo:

#define stringify(x) #x ... const char * thestring = stringify( 10 * 50 ); 

El problema es que quiero conseguirlo.

 const char * thestring = "500"; 

Y no

 const char * thestring = "10 * 50"; 

Se puede hacer esto?

El preprocesador de C no puede hacer eso, así que usa snprintf lugar:

 char *stringify(int n) { char *res = malloc(12); snprintf(res, 12, "%d", n); return res; } 

Uso

 const char *thestring = stringify(10 * 50); 

nótese bien

Por simplicidad he omitido el control de errores y free .

Probablemente no le va a gustar el formato en el que se va a presentar la expresión, , es posible, pero de una manera muy ecléctica: tendrá que crear un lenguaje funcional independiente que esté siendo “ejecutado” por el preprocesador. . La prueba:

 $ cvs -d:pserver:anonymous@chaos-pp.cvs.sourceforge.net:/cvsroot/chaos-pp login $ cvs -z3 -d:pserver:anonymous@chaos-pp.cvs.sourceforge.net:/cvsroot/chaos-pp co -P chaos-pp $ cvs -z3 -d:pserver:anonymous@chaos-pp.cvs.sourceforge.net:/cvsroot/chaos-pp co -P order-pp $ cd order-pp/example $ grep -A 6 'int main' fibonacci.c int main(void) { printf ("The 500th Fibonacci number is " ORDER_PP(8stringize(8to_lit(8fib(8nat(5,0,0))))) ".\n"); return 0; } $ cpp -I../inc fibonacci.c 2>/dev/null | grep -A 6 'int main' int main(void) { printf ("The 500th Fibonacci number is " "139423224561697880139724382870407283950070256587697307264108962948325571622863290691557658876222521294125" ".\n"); return 0; } 

En este ejemplo, hemos utilizado un lenguaje puramente funcional de preprocesador recién creado para calcular el número de Fibonacci número 500 y luego crear una cadena de caracteres para dar al comstackdor de C.

Por supuesto, dudo mucho que esto sea algo que usarías en la práctica, y es un abuso muy extenso del preprocesador, pero considero que es un truco muy estimulante. (y sí, sin los giros teóricos exóticos como éste, no es posible).

Supongo que usted tiene más experiencia en lenguajes de scripting que en C.

Hay varias fases que debes conocer con un lenguaje puramente comstackdo como C: Preproceso, Comstackción, Enlace y Ejecución

Primero se ejecuta el preprocesador . Ahí es donde tu macro se expande. En este punto, su contenido es “10 * 50”. No hay mucho que hacer al respecto.

Una vez que se completa el preprocesador de macros, el comstackdor convierte el progtwig en un archivo de objeto

Una vez que el comstackdor termina en cada archivo de origen, el enlazador interviene y los pega a todos juntos.

Finalmente, cuando su usuario está listo, ejecutan su progtwig. Semánticamente, esto es cuando se calcula el 10 * 50. (En realidad, la mayoría de los comstackdores reconocerán que siempre tendrá el mismo valor y lo reemplazarán por 500, pero eso es un detalle de implementación).

A los lenguajes de script les gusta desenfocar todas estas líneas, para que pueda ver dónde alguien podría estar confundido.

Las macros del preprocesador se ejecutan antes del comstackdor. Es, por definición, no es posible hacer exactamente lo que usted está tratando de hacer.

Para convertir un número en una cadena en tiempo de ejecución, llame a la función itoa , como esto:

 char thestring[8]; itoa(10 * 50, thestring, 10); 

Tenga en cuenta que este código declara que la thestring es una matriz, no un puntero. Para más información, lea acerca de la administración de memoria en C.

Necesitas interpretar la cadena. C no hace eso solo, busca una biblioteca que lo haga por ti.

http://expreval.sourceforge.net/ http://www.codeproject.com/KB/library/expreval.aspx

Hay otros, solo busca en google.

Podría escribir un script (perl?) Para usarlo como preprocesador que reconozca las cadenas a evaluar, las evalúe y luego llame al verdadero cpp en el archivo “evaluado”.

Tal vez podría funcionar.

Como han dicho las otras respuestas, esto no se puede hacer con el preprocesador de C. Esta es una de las muchas deficiencias de C que se resuelven con C ++. Este es el tipo de cosa que se puede lograr de una manera muy elegante utilizando la metaprogtwigción de plantillas.

Para calcular una expresión aritmética en tiempo de comstackción:

 #include  namespace mpl = boost::mpl; int main(int argc, char *argv[]) { const int n = mpl::multiplies, mpl::int_<50> >::value; return 0; } 

Aquí hay una metafunción de formato de cadena que encontré en los archivos de listas de correo de boost. Esta versión convertirá un int (como el calculado anteriormente) en una cadena en la base de su elección:

 #include  #include  #include  #include  #include  #include  #include  #include  namespace mpl = boost::mpl; struct itoa_ct { // radix for _itoa() goes up to 36, but only bother with 16 here typedef mpl::vector_c radix_t; template  struct radix_convert { typedef typename mpl::push_back< typename radix_convert::type , mpl::char_::type::value> >::type type; }; template  struct radix_convert { typedef mpl::string<> type; }; template  struct apply { // All bases != 10 consider I as unsigned typedef typename radix_convert< Radix, static_cast((Radix == 10 && I < 0) ? -I : I) >::type converted_t; // Prefix with '-' if negative and base 10 typedef typename mpl::if_< mpl::bool_<(Radix == 10 && I < 0)> , mpl::push_front > , mpl::identity >::type::type type; }; }; 

Poniendo los dos juntos tu expresión se convierte en:

 const char *thestring = mpl::c_str, mpl::int_<50> >::value>::type>::value; 

… y todo esto se convierte en nada más que una cadena constante “500” en tiempo de comstackción 🙂