C预处理程序可以执行算术吗?如果可以,怎么做? [英] Can the C preprocessor perform arithmetic and if so, how?
问题描述
我目前正在为微控制器编写代码;由于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屋!