C 预处理器可以执行整数运算吗?

问题描述 投票:0回答:6

C预处理器能够执行整数运算吗?

例如:

#define PI 3.1416
#define OP PI/100
#define OP2 PI%100

有没有办法在预处理阶段计算

OP
和/或
OP2

c-preprocessor
6个回答
44
投票

整数算术?运行以下程序来找出答案:

#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 的预处理器就会失败。我还没有检查标准是否允许在预处理器中进行浮点运算。

常规宏扩展不会计算整数表达式,而是将其留给编译器,通过预处理(gcc 中的 -E)可以看出:

#define ONEPLUSONE (1 + 1)
#if ONEPLUSONE == 2
    int i = ONEPLUSONE;
#endif

结果是

int i = (1 + 1);
(可能还加上一些指示源文件名和行号等的东西)。


21
投票

您编写的代码实际上并不使预处理器进行任何计算。 #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

8
投票

,我的意思是:它可以做算术:)

99瓶啤酒所示。


8
投票

是的,可以使用 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;

感谢这个帖子。


5
投票

是的。

我不敢相信还没有人与某个混淆的 C 竞赛获胜者建立联系。这个人通过递归包含在预处理器中实现了 ALU。 这里是实现,这里是一些解释。

现在,也就是说,你不想做那个人所做的事情。这很有趣,但是看看他的提示文件中的编译时间(更不用说生成的代码是不可维护的)。更常见的是,人们严格使用预处理器进行文本替换,并且常整数算术的评估发生在编译时或运行时。

正如其他人指出的,您可以在 #if 语句中进行一些算术运算。


5
投票

做算术时要小心:加括号

#define SIZE4 4
#define SIZE8 8
#define TOTALSIZE SIZE4 + SIZE8

如果您曾经使用过类似的东西:

unsigned int i = TOTALSIZE/4;

并且期望 i 为 3,您将得到 4 + 2 = 6。 添加括号:

#define TOTALSIZE (SIZE4 + SIZE8)
© www.soinside.com 2019 - 2024. All rights reserved.