正如问题所说, C 预处理器能够做到吗?
E.g:
#define PI 3.1416
#define OP PI/100
#define OP2 PI%100
在预处理阶段是否有任何方式计算OP和/或OP2?
答案 0 :(得分:28)
整数算术?运行以下程序以找出:
#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 in gcc)看到以下内容:
#define ONEPLUSONE (1 + 1)
#if ONEPLUSONE == 2
int i = ONEPLUSONE;
#endif
结果是int i = (1 + 1);
(可能还有一些东西用于表示源文件名和行号等)。
答案 1 :(得分:16)
您编写的代码实际上并没有使预处理器进行任何计算。 #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
答案 2 :(得分:6)
是,我的意思是:它可以做算术:)
如99 bottles of beer中所示。
答案 3 :(得分:6)
是的,可以使用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;
答案 4 :(得分:4)
是
我无法相信没有人与某个混淆的C竞赛获胜者联系过。该人通过递归包含在预处理器中实现了ALU。 Here是实现,here是一种解释。
现在,那就是说,你不想做那个人做的事情。它很有趣,但是看看他的提示文件中的编译时间(更不用说生成的代码不可维护的事实)。更常见的是,人们严格使用预处理器进行文本替换,并且在编译时或运行时都会对常数整数运算进行评估。
然而,正如其他人所指出的,你可以在#if语句中做一些算术。
答案 5 :(得分:0)
进行算术时要小心:添加括号。
#define SIZE4 4
#define SIZE8 8
#define TOTALSIZE SIZE4 + SIZE8
如果您使用过类似的东西:
unsigned int i = TOTALSIZE/4;
并期望我为3,您将得到4 + 2 = 6。 添加括号:
#define TOTALSIZE (SIZE4 + SIZE8)