Как говорится в этом вопросе, препроцессор C способен сделать это?
например:.
#define PI 3.1416
#define OP PI/100
#define OP2 PI%100
Можно ли рассчитывать OP и/или OP2 на этапе предварительной обработки?
Как говорится в этом вопросе, препроцессор C способен сделать это?
например:.
#define PI 3.1416
#define OP PI/100
#define OP2 PI%100
Можно ли рассчитывать OP и/или OP2 на этапе предварительной обработки?
Целочисленная арифметика? Выполните следующую программу, чтобы узнать:
#include "stdio.h"
int main() {
#if 1 + 1 == 2
printf("1+1==2\n");
#endif
#if 1 + 1 == 3
printf("1+1==3\n");
#endif
}
Ответ "да", есть способ заставить препроцессор выполнить целочисленную арифметику, которая должна использовать ее в условии препроцессора.
Обратите внимание, что ваши примеры не являются целыми арифметическими. Я просто проверил, и препроцессор gcc терпит неудачу, если вы попытаетесь сделать это с помощью сравнения с плавающей точкой. Я не проверял, позволяет ли стандарт когда-либо разрешать арифметику с плавающей запятой в препроцессоре.
Регулярное расширение макросов не оценивает целочисленные выражения, оно оставляет его компилятору, как видно из предварительной обработки (-E в gcc):
#define ONEPLUSONE (1 + 1)
#if ONEPLUSONE == 2
int i = ONEPLUSONE;
#endif
Результат int i = (1 + 1);
(плюс, вероятно, некоторые вещи, указывающие имена файлов и номера строк и т.д.).
Код, который вы написали, фактически не делает препроцессор выполненным. #define выполняет простую замену текста, поэтому с этим определяется:
#define PI 3.1416
#define OP PI/100
Этот код:
if (OP == x) { ... }
становится
if (3.1416/100 == x) { ... }
а затем он скомпилируется. Компилятор, в свою очередь, может принять такое выражение и вычислить его во время компиляции и создать эквивалентный ему код:
if (0.031416 == x) { ... }
Но это компилятор, а не препроцессор.
Чтобы ответить на ваш вопрос, да, препроцессор МОЖЕТ выполнить некоторую арифметику. Это можно увидеть, когда вы пишете что-то вроде этого:
#if (3.141/100 == 20)
printf("yo");
#elif (3+3 == 6)
printf("hey");
#endif
ДА, я имею в виду: он может выполнять арифметику:)
Как показано в 99 бутылок пива.
Да, это можно сделать с помощью препроцессора Boost. И он совместим с чистым C, поэтому вы можете использовать его в программах на C только с компиляциями C. Ваш код включает числа с плавающей запятой, поэтому я думаю, что это нужно сделать косвенно.
#include <boost/preprocessor/arithmetic/div.hpp>
BOOST_PP_DIV(11, 5) // expands to 2
#define KB 1024
#define HKB BOOST_PP_DIV(A,2)
#define REM(A,B) BOOST_PP_SUB(A, BOOST_PP_MUL(B, BOOST_PP_DIV(A,B)))
#define RKB REM(KB,2)
int div = HKB;
int rem = RKB;
Это предварительная обработка (проверка с помощью gcc -S)
int div = 512;
int rem = 0;
Благодаря этой теме.
Да.
Я не могу поверить, что никто еще не связан с каким-то запутанным победителем конкурса C. Парень реализовал ALU в препроцессоре с помощью рекурсивных включений. Здесь - реализация, а здесь - это что-то вроде объяснение.
Теперь, когда вы сказали, вы не хотите делать то, что сделал этот парень. Это весело и все, но посмотрите на время компиляции в его файле подсказок (не говоря уже о том, что полученный код не поддается). Чаще всего люди используют предварительный процессор строго для замены текста, а оценка постоянной целочисленной арифметики происходит либо во время компиляции, либо во время выполнения.
Как отмечали другие, вы можете сделать некоторую арифметику в операторах #if.
Будьте осторожны при выполнении арифметики: добавьте скобки.
#define SIZE4 4
#define SIZE8 8
#define TOTALSIZE SIZE4 + SIZE8
Если вы когда-нибудь используете что-то вроде:
unsigned int i = TOTALSIZE/4;
и ожидайте, что я буду 3, вы получите 4 + 2 = 6 вместо этого. Добавить скобку:
#define TOTALSIZE (SIZE4 + SIZE8)