Если они - созданные сервисы.NET, можно использовать installutil.exe с переключателя/u в папке платформы .NET как C:\Windows\Microsoft.NET\Framework64\v2.0.50727
Препроцессор C не может этого сделать, поэтому используйте вместо него snprintf
:
char *stringify(int n) {
char *res = malloc(12);
snprintf(res, 12, "%d", n);
return res;
}
const char *thestring = stringify(10 * 50);
Для простоты я пропустил контроль ошибок и бесплатно
.
Вам, вероятно, не понравится формат, в котором будет представлено выражение, да , это возможно , но в очень эклектичный способ - вам нужно будет создать отдельный функциональный язык, который «запускается» препроцессором. Доказательство:
$ 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.
Конечно, я очень сомневаюсь, что это что-то который вы когда-либо использовали бы на практике, и это очень далеко идущее злоупотребление препроцессором, но я считаю его очень заставляющим задуматься. (и да, без таких экзотических теоретических поворотов, как этот, это невозможно).
Могу предположить, что у вас больше опыта работы с языками сценариев, чем с C.
При использовании чисто компилируемого языка, такого как C, вам нужно знать несколько этапов: Предварительная обработка, компиляция, компоновка и запуск
Сначала запускается препроцессор . Вот где расширяется ваш макрос. На данный момент его содержимое составляет «10 * 50». С этим ничего не поделаешь.
После завершения макропрепроцессора компилятор преобразует программу в объектный файл
После того, как компилятор завершит работу с каждым исходным файлом, ] компоновщик вмешивается и соединяет их всех вместе.
Наконец, когда ваш пользователь готов, он выполняет вашу программу. Семантически это когда вычисляется 10 * 50. (На самом деле,
Макросы препроцессора запускаются перед компилятором. По определению невозможно сделать именно то, что вы пытаетесь сделать.
Чтобы преобразовать число в строку во время выполнения, вызовите функцию itoa
, например:
char thestring[8];
itoa(10 * 50, thestring, 10);
Обратите внимание, что этот код объявляет строку
как массив, а не указатель. Для получения дополнительной информации прочтите об управлении памятью в C.
Вам нужно интерпретировать строку. C сам по себе этого не делает, поищите библиотеку, которая сделает это за вас.
http://expreval.sourceforge.net/ http://www.codeproject.com/KB/library /expreval.aspx
Есть и другие, просто выполните поиск в Google.
Как и другие В ответах говорилось, что это невозможно сделать с помощью препроцессора 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" во время компиляции: -)
Вы могли бы написать сценарий (perl?) Для использования в качестве препроцессора, который распознает строки для оценки, оценивает их, а затем вызывает истинный cpp для "оцененного" файла.
Возможно это могло сработать.