我定义了一个宏。但我需要在运行时根据条件更改此值。 我该如何实现呢?
答案 0 :(得分:29)
在源文件甚至编译之前,宏会被预处理器替换为它们的值。您无法在运行时更改宏的值。
如果你能解释一下你正在努力实现的目标,毫无疑问还有另一种方法来解决你的问题,不包括宏。
答案 1 :(得分:25)
您无法更改宏本身,即它扩展到的内容,但您可以更改涉及宏的表达式的值。对于一个非常愚蠢的例子:
#include <stdio.h>
#define UNCHANGEABLE_VALUE 5
#define CHANGEABLE_VALUE foo
int foo = 5;
int main() {
printf("%d %d\n", UNCHANGEABLE_VALUE, CHANGEABLE_VALUE);
CHANGEABLE_VALUE = 10;
printf("%d %d\n", UNCHANGEABLE_VALUE, CHANGEABLE_VALUE);
}
因此,您的问题的答案取决于您希望更改对使用宏的代码产生何种影响。
当然5
是编译时常量,而foo
则不是,因此如果您计划将CHANGEABLE_VALUE
用作case
,则无效标签或其他什么。
请记住,C源的翻译有两个(实际上更多)阶段。在第一个(我们关心的两个)中,扩展了宏。完成所有操作后,程序将进行“语法和语义分析”,如5.1.1.2/2所述。这两个步骤通常被称为“预处理”和“编译”(虽然含糊不清,但整个翻译过程通常也称为“编译”)。它们甚至可以由单独的程序实现,“编译器”在执行任何其他操作之前根据需要运行“预处理器”。因此,运行时太晚,无法尝试返回并更改宏扩展到的内容。
答案 2 :(得分:13)
你做不到。宏由Preprocessor扩展,甚至在编译代码之前就会发生。它纯粹是文本的替代品。
如果您需要在运行时更改某些内容,只需使用实际函数调用替换宏。
答案 3 :(得分:7)
你不能。
由于宏在编译本身之前由预处理器解析,因此将其内容直接复制到您使用它的位置。
您仍然可以根据需要使用参数插入条件语句,或使用调用范围可访问变量。
如果要更改单个值,请更好地使用全局范围变量,即使不鼓励这样做。 (作为宏观的密集使用)
答案 4 :(得分:4)
根据您的目的,您可以采取多种方式。
全局变量而不是宏
// someincludefile.h
extern static int foo;
// someincludefile.c
static int foo = 5;
// someotherfile.c
#include "someincludefile.h"
printf("%d\n", foo); // >> 5
foo = -5;
printf("%d\n", foo); // >> -5
您可以切换的条件
// someincludefile.h
extern static int condition;
#define FOO1 (5)
#define FOO2 (-5)
#define FOO (condition ? (FOO1) : (FOO2))
// someincludefile.c
static int condition = 1;
// someotherfile.c
#include "someincludefile.h"
printf("%d\n", FOO); // >> 5
condition = 0;
printf("%d\n", FOO); // >> -5
本地和动态评估的条件
// someincludefile.h
#define CONDITION (bar >= 0)
#define FOO1 (5)
#define FOO2 (-5)
#define FOO ((CONDITION) ? (FOO1) : (FOO2))
// someotherfile.c
#include "someincludefile.h"
int bar = 1;
printf("%d\n", FOO); // >> 5
bar = -1;
printf("%d\n", FOO); // >> -5
在最后一个中,CONDITION将被评估为其代码在本地范围内,因此您可以在其中使用局部变量和/或参数,但如果需要,您也可以使用全局变量。