我在cpp中写了一段代码。我的代码中有一个循环,必须以指定的频率执行。 我希望每当选择的频率等于或大于70hz时,"如果"声明工作,如果不是if的内容没有"如果",但我不知道如何在预处理器中写它。我写了这样的东西,但它总是执行"否则"部分内容:
#define Freq70Hz 70
int frequency = Freq70Hz;
int main
{
while(true)
{
#if frequency == Freq70Hz
if(condition ){
// do the firstthing
}
#else
// do the firstthing
#endif
}
}
答案 0 :(得分:3)
在这里,您将静态编译时编程与动态运行时编程混合在一起。在这种情况下,预编译器如何在编译时知道frequency
的值?它可能在程序执行期间发生变化。您要么拥有这样的静态解决方案:
#define FREQUENCY 70 //this can be changed by passing in compiler options
int main()
{
while(true)
{
#if FREQUENCY > 70
if(condition ){
// do the firstthing
}
#else
// do the firstthing
#endif
}
}
或者你想要一个像这样的动态解决方案:
int frequency = 70;
int main()
{
while(true)
{
if(frequency == 70 && condition)
{
// do the firstthing
}
else
{
// do the firstthing
}
}
}
答案 1 :(得分:1)
您误解了预处理器的功能。
预处理器在程序运行之前进行文本处理。
特别是,它只将普通变量视为文本,并且不知道它们的类型是什么,或者运行时的值是什么。即使它们是像程序启动时初始化的frequency
这样的全局变量,也是如此。 我们看到了;预处理器没有。
#define Freq70Hz 70
中的别名定义看起来只是文件其余部分的文本替换规则。每当文本出现在程序的其余部分时,文本(" Freq70Hz")将被替换(通过" 70"),但在编译器看到代码之前。
然后你成为预处理器规范怪癖的牺牲品。
您认为对#if frequency == Freq70Hz
行进行了有意义的评估。您希望将考虑变量frequency
的值,其中我们(但不是预处理器!)知道为70。但事实并非如此。
预处理器会看到预处理程序令牌 frequency
。它没有频率为int变量的概念,因为它无法理解C编程语言。它看到此标记是条件预处理器表达式的一部分。虽然没有告诉它用一个值替换它。
现在捕获:在预处理器条件表达式中执行了所有替换之后仍然存在的标识符被替换为0(!),参见最新的C草案n1570,6.10.1。/ 4。 预处理器不会抱怨"未定义的标识符"。这使得指令#if frequency == Freq70Hz
#if 0 == 70
显然始终为假。
由于默认使用未定义的预处理程序标识符是一个危险的特性 - 普通的编程语言在Basic之后停止这样做 - 它很有必要知道很久以前有人向我展示过的技巧:使用宏函数< / em>的。 #define Freq70Hz() 70
在功能上是等同的,但是当你稍后拼错它时会抱怨。
答案 2 :(得分:0)
使用模板消除死代码
template<bool isGE70Hz>
void DoWhile() {
while(true) {
if (isGE70Hz) { // dead code elimination as isGE70Hz is compiletime constant.
if(condition ){
// do the firstthing
}
} else {
// do the firstthing
}
}
}
int main() {
if (frequency >= Freq70Hz) // chose specialization
DoWhile<true>()
else
DoWhile<false>()
// if frequency and Freq70Hz both are compiletime constants you could do
// DoWhile<frequency >= Freq70Hz>
}
答案 3 :(得分:0)
假设// do the firstthing
是两者中的相同,假设frequency
在执行中不会改变,我将不会使用预处理器......如果你使用{ {1}}然后再做:
static const int frequency = Freq70Hz
编译器将根据 while(true)
{
if(condition || frequency == Freq70Hz){
// do the firstthing
}
}
不会改变的知识编译出适当的东西。也就是说,如果频率= = Freq70Hz,则整个if部分不会在发布可执行文件中。如果频率!= Freq70Hz那么if部分就是条件。