C预处理程序可以执行算术吗?如果可以,怎么做? [英] Can the C preprocessor perform arithmetic and if so, how?

查看:130
本文介绍了C预处理程序可以执行算术吗?如果可以,怎么做?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在为微控制器编写代码;由于ATMega128没有硬件乘法器或除法器,因此这些操作必须在软件中完成,并且占用大量的周期。但是,出于代码的可移植性和易用性,我宁愿不要将预先计算的值硬编码到我的代码中。因此,例如,我有许多任务取决于系统时钟频率。目前,我的运行频率为16MHz,但是我应该选择降低它,例如为了减少电池应用的功耗,我想更改一行代码,而不是多行代码。

I'm currently writing code for a microcontroller; since the ATMega128 does not have a hardware multiplier or divider, these operations must be done in software and they take up a decent amount of cycles. However, for code portability and ease of use, I'd prefer not to hard-code precomputed values into my code So for instance, I have a number of tasks which are dependent on the system clock frequency. Currently I' running at 16MHz, but should I choose to lower that, say to reduce power consumption for battery applications, I'd like to change one line of code rather than many.

这样说,C预处理程序可以计算算术表达式,然后将结果粘贴到我的代码中,而不是将原始表达式粘贴到代码中吗?如果是这样,我将如何去做?他们的编译器选项是我需要考虑的吗?

So with that said, can the C preprocessor compute arithmetic expressions and then "paste" the result into my code rather than "pasting" the original expression into the code? If so, how would I go about doing this? Are their compiler options and whatnot that I need to consider?

注意:我要计算的值是常量,所以我看不出为什么这不是常数

NOTE: The values I want to compute are constant values, so I see no reason why this would not be a feature.

推荐答案

这是一个问题:


  • 第一季度。 C预处理程序可以执行算术吗?

这是另一个:


  • 第二季度。 C预处理程序可以计算算术表达式,然后将结果
    粘贴到我的代码中,而不是将原始表达式粘贴到代码中吗?

对第一季度的答案是肯定的。问题2的答案是否定的。这两个事实都可以用以下文件来说明

The answer to Q1 is Yes. The answer to Q2 is No. Both facts can be illustrated with the following file:

foo.c

#define EXPR ((1 + 2) * 3)
#if EXPR == 9
int nine = EXPR;
#else
int not_nine = EXPR;
#endif

如果我们将其传递给C预处理器,则用 cpp foo.c 或等价的
gcc -E foo.c ,我们看到的输出如下:

If we pass this to the C preprocessor, either by cpp foo.c or equivalently gcc -E foo.c, we see output like:

# 1 "foo.c"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 30 "/usr/include/stdc-predef.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/predefs.h" 1 3 4
# 31 "/usr/include/stdc-predef.h" 2 3 4
# 1 "<command-line>" 2
# 1 "foo.c"


int nine = ((1 + 2) * 3);

预处理器保留定义 int的行的事实和
删除了定义 not_nine 的行,这表明我们已经正确执行了
求值#的算法。如果EXPR == 9

The fact that the preprocessor retains the line defining int nine and has dropped the line defining not_nine shows us that it has correctly performed the arithmetic required to evaluate #if EXPR == 9.

定义的预处理文本为 int的事实int九=((1 + 2)* 3);
向我们显示 #define 指令使预处理器替换
<$ c定义为((1 + 2)* 3)的$ c> EXPR
,以及具有算术值的 not
的定义为 9

The fact that the preprocessed text of the definition is int nine = ((1 + 2) * 3); shows us that the #define directive causes the preprocessor to replace EXPR with its definition ((1 + 2) * 3), and not with the arithmetic value of its definition, 9.

C预处理程序除<$ c $以外是否还有其他指令c> #define 具有第二个
效果?

Does the C preprocessor have any directive besides #define which has the second effect? No.

但这当然并不意味着 int 9 的定义必须包含
运行时计算,因为编译器几乎可以肯定会计算
算术表达式((1 + 2)* 3)在编译时将其替换为常量 9

But this does not of course imply that the definition of int nine must entail a runtime calculation, because the compiler will almost certainly evaluate the arithmetic expression ((1 + 2) * 3) at compiletime and replace it with the constant 9.

我们可以看到编译器通过检查
编译后的目标文件来翻译源文件。大多数工具链都会提供类似GNU binutils
objdump 之类的帮助。如果我使用gcc编译 foo.c

We can see how the compiler has translated the source file by examining the compiled object file. Most toolchains will provide something like GNU binutils objdump to assist with this. If I compile foo.c with gcc:

gcc -c -o foo.o foo.c

然后调用:

objdump -s foo.o

到看到 foo.o 的全部内容,我得到:

to see the full contents of foo.o, I get:

foo.o:     file format elf64-x86-64

Contents of section .data:
 0000 09000000                             ....            
Contents of section .comment:
 0000 00474343 3a202855 62756e74 752f4c69  .GCC: (Ubuntu/Li
 0010 6e61726f 20342e38 2e312d31 30756275  naro 4.8.1-10ubu
 0020 6e747539 2920342e 382e3100           ntu9) 4.8.1.

还有希望的 9 .data 部分中进行硬编码。

And there is the hoped-for 9 hard-coded in the .data section.

注意:预处理器的算术功能仅限整数算术

Note that the preprocessor's arithmetic capabilities are restricted to integer arithmetic

这篇关于C预处理程序可以执行算术吗?如果可以,怎么做?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆