Как к stringify выражение в C

Если они - созданные сервисы.NET, можно использовать installutil.exe с переключателя/u в папке платформы .NET как C:\Windows\Microsoft.NET\Framework64\v2.0.50727

8
задан Andrew 13 August 2009 в 22:34
поделиться

7 ответов

Препроцессор C не может этого сделать, поэтому используйте вместо него snprintf :

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

Использование

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

NB

Для простоты я пропустил контроль ошибок и бесплатно .

10
ответ дан 5 December 2019 в 10:04
поделиться

Вам, вероятно, не понравится формат, в котором будет представлено выражение, да , это возможно , но в очень эклектичный способ - вам нужно будет создать отдельный функциональный язык, который «запускается» препроцессором. Доказательство:

$ 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;
}

В этом примере у нас есть новый чисто функциональный язык, запускаемый препроцессором, который используется для вычисления 500-го числа Фибоначчи, а затем преобразования его в строку для передачи компилятору C.

Конечно, я очень сомневаюсь, что это что-то который вы когда-либо использовали бы на практике, и это очень далеко идущее злоупотребление препроцессором, но я считаю его очень заставляющим задуматься. (и да, без таких экзотических теоретических поворотов, как этот, это невозможно).

5
ответ дан 5 December 2019 в 10:04
поделиться

Могу предположить, что у вас больше опыта работы с языками сценариев, чем с C.

При использовании чисто компилируемого языка, такого как C, вам нужно знать несколько этапов: Предварительная обработка, компиляция, компоновка и запуск

Сначала запускается препроцессор . Вот где расширяется ваш макрос. На данный момент его содержимое составляет «10 * 50». С этим ничего не поделаешь.

После завершения макропрепроцессора компилятор преобразует программу в объектный файл

После того, как компилятор завершит работу с каждым исходным файлом, ] компоновщик вмешивается и соединяет их всех вместе.

Наконец, когда ваш пользователь готов, он выполняет вашу программу. Семантически это когда вычисляется 10 * 50. (На самом деле,

4
ответ дан 5 December 2019 в 10:04
поделиться

Макросы препроцессора запускаются перед компилятором. По определению невозможно сделать именно то, что вы пытаетесь сделать.

Чтобы преобразовать число в строку во время выполнения, вызовите функцию itoa , например:

char thestring[8];

itoa(10 * 50, thestring, 10);

Обратите внимание, что этот код объявляет строку как массив, а не указатель. Для получения дополнительной информации прочтите об управлении памятью в C.

1
ответ дан 5 December 2019 в 10:04
поделиться

Вам нужно интерпретировать строку. C сам по себе этого не делает, поищите библиотеку, которая сделает это за вас.

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

Есть и другие, просто выполните поиск в Google.

0
ответ дан 5 December 2019 в 10:04
поделиться

Как и другие В ответах говорилось, что это невозможно сделать с помощью препроцессора C. Это один из многих недостатков C, которые решает C ++. Это то, что может быть выполнено очень элегантно с помощью метапрограммирования шаблонов.

Чтобы вычислить арифметическое выражение во время компиляции:

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

Вот метафункция форматирования строк , которую я нашел в архивах списков рассылки boost. Эта версия преобразует int (подобный вычисленному выше) в строку в базе по вашему выбору:

#include <boost/mpl/string.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/push_back.hpp>
namespace mpl = boost::mpl;
struct itoa_ct
{
  // radix for _itoa() goes up to 36, but only bother with 16 here
  typedef mpl::vector_c<char
    ,'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'
    > radix_t;
  template <int Radix, unsigned int Quotient>
    struct radix_convert
    {
      typedef typename mpl::push_back<
        typename radix_convert<Radix, Quotient / Radix>::type
        , mpl::char_<mpl::at_c<radix_t, Quotient % Radix>::type::value>
        >::type type;
    };
  template <int Radix>
    struct radix_convert<Radix, 0>
    {
      typedef mpl::string<> type;
    };
  template <int I, int Radix = 10>
    struct apply
    {
      // All bases != 10 consider I as unsigned
      typedef typename radix_convert<
        Radix, static_cast<unsigned int>((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<converted_t, mpl::char_<'-'> >
        , mpl::identity<converted_t>
        >::type::type type;
    };
};

Соединение двух вместе, ваше выражение становится:

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

... и все это превращается в не более чем постоянная строка "500" во время компиляции: -)

-2
ответ дан 5 December 2019 в 10:04
поделиться

Вы могли бы написать сценарий (perl?) Для использования в качестве препроцессора, который распознает строки для оценки, оценивает их, а затем вызывает истинный cpp для "оцененного" файла.

Возможно это могло сработать.

-1
ответ дан 5 December 2019 в 10:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: