[英]Pre-processor #if doesn't work
I'm trying to write a somehow-generic printArray function in C , which I will able to run with several programs, each with a different type of array. 我正在尝试用C编写某种通用的printArray函数,该函数可以与多个程序一起运行,每个程序具有不同的数组类型。 I did this: 我这样做:
#define TYPE int /* or char or double*/
void printArray(TYPE *a, int size){
for (int i=0; i<size; i++){
#if TYPE == int
printf("%d ", a[i]);
#elif TYPE == char
printf("%c ", a[i]);
#elif TYPE == double
printf("%f ", a[i]);
#endif
}
printf("\n");
}
I have tried running it, but no matter what TYPE is defined to be, the first #if
always checks in, meaning - if the if's are written: 我试过运行它,但是无论定义为什么TYPE,第一个#if
总是会签入,这意味着-如果编写了if:
#if TYPE == int
printf("int");
#elif TYPE == char
printf("char");
#elif TYPE == double
printf("double");
#endif
then it will print "int", even if TYPE is defined to be char, and if 那么即使TYPE定义为char,它也会打印“ int”,并且
#if TYPE == char
printf("char");
#elif TYPE == int
printf("int");
#elif TYPE == double
printf("double");
#endif
then it will print "char", even if TYPE is defined to be int, etc. 那么即使定义TYPE为int等,它也会打印“ char”。
ideas? 想法?
Preprocessor #if evaluates integer expressions. 预处理程序#if计算整数表达式。 You're trying to treat == as if it were comparing tokens. 您试图将==视为正在比较令牌。 Since int, char, double, etc. are not defined as preprocessor variables, they all evaluate as 0. 由于int,char,double等未定义为预处理器变量,因此它们的求值均为0。
You could do 你可以做
#define TYPE int
#define FMT "%d"
void printArray(TYPE *a, int size){
for (int i=0; i<size; i++)
printf(FMT " ", a[i]);
printf("\n");
}
Much simpler, and it works. 简单得多,而且有效。
If you want to only have to specify the TYPE, you could do something like 如果您只需要指定TYPE,则可以执行以下操作
#define FMT_int "%d"
#define FMT_char "%c"
#define FMT_double "%f"
#define FMT PPCAT(FMT_, TYPE)
where PPCAT is defined in my answer to C/C++ Macro string concatenation 在我对C / C ++宏字符串连接的答案中定义了PPCAT
The C and C++ preprocessor can only work with numbers (numeric literals, to be exact). C和C ++预处理器只能使用数字(准确地说是数字文字)。 In expressions, any words it doesn't recognize (after all macro expansion) are treated as a 0
. 在表达式中,所有无法识别的单词(在所有宏扩展之后)都被视为0
。
You'd need to do something like this: 您需要执行以下操作:
#define TYPE_int 0
#define TYPE_char 1
#define TYPE_double 2
#define TYPE_USED TYPE_int
#if TYPE_USED == TYPE_int
typedef int TYPE;
#elif TYPE_USED == TYPE_char
typedef char TYPE;
#elif TYPE_USED == TYPE_double
typedef double TYPE;
#endif
void printArray(TYPE *a, int size){
for (int i=0; i<size; i++){
#if TYPE_USED == TYPE_int
printf("%d ", a[i]);
#elif TYPE_USED == TYPE_char
printf("%c ", a[i]);
#elif TYPE_USED == TYPE_double
printf("%f ", a[i]);
#endif
}
printf("\n");
}
You could use boost.preprocessor to do some metaprogramming magic with preprocessor loops instead of listing all the values manually. 您可以使用boost.preprocessor通过预处理程序循环执行一些元编程魔术,而不是手动列出所有值。
Of course, the above code applies to C. If you're using C++, use a template instead of macro hacks and std::cout
instead of printf()
. 当然,以上代码适用于C。如果您使用的是C ++,请使用模板而不是宏技巧,并使用std::cout
而不是printf()
。
You should avoid the pre-processor wherever possible, and this is a classic example of when to avoid it! 您应该尽可能避免使用预处理器,这是何时避免使用预处理器的经典示例! If you need to write code that depends on type then you can use either template, inheritance or polymorphism for this. 如果您需要编写取决于类型的代码,则可以使用模板,继承或多态。
In this case you can rewrite printArray
as a template function: 在这种情况下,您可以将printArray
重写为模板函数:
template<class T>
void printArray(T *data, int count)
{
for(int i=0; i<count; i++)
{
cout << data[i] << " ";
}
cout << endl;
}
Preprocessor evaluation is more or less like C++ evaluation. 预处理程序评估或多或少类似于C ++评估。 It is numeric (despite the fact that the preprocessor works with text). 它是数字的(尽管预处理器可以处理文本)。 Any preprocessor symbol which remains after macro expansion is replaced by 0
, and C++ keywords are still symbols in the preprocessor. 宏扩展后剩余的任何预处理器符号都将替换为0
,并且C ++关键字仍然是预处理器中的符号。 (There is a special exception for the preprocessor symbol true
, which expands to 1
.) So in the end, all of your comparisons come out to 0 == 0
, which is always true. (预处理器符号true
有一个特殊的例外,该符号扩展为1
)因此最后,所有比较都得出0 == 0
,这始终是正确的。
http://msdn.microsoft.com/en-us/library/ew2hz0yd(v=VS.80).aspx http://msdn.microsoft.com/zh-CN/library/ew2hz0yd(v=VS.80).aspx
The constant-expression is an integer constant expression with some additional restrictions. constant-expression是具有一些附加限制的整数常量表达式。
It seems u can't compare strings. 看来您无法比较字符串。 Try the following: 请尝试以下操作:
#define TYPE_int /* put this too */
#define TYPE int /* or char or double*/
void printArray(TYPE *a, int size){
for (int i=0; i<size; i++){
#ifdef TYPE_int
printf("%d ", a[i]);
#elif defined TYPE_char
printf("%c ", a[i]);
#elif defined TYPE_double
printf("%f ", a[i]);
#endif
}
printf("\n");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.