[英]Pre-processor #if doesn't work
我正在尝试用C编写某种通用的printArray函数,该函数可以与多个程序一起运行,每个程序具有不同的数组类型。 我这样做:
#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");
}
我试过运行它,但是无论定义为什么TYPE,第一个#if
总是会签入,这意味着-如果编写了if:
#if TYPE == int
printf("int");
#elif TYPE == char
printf("char");
#elif TYPE == double
printf("double");
#endif
那么即使TYPE定义为char,它也会打印“ int”,并且
#if TYPE == char
printf("char");
#elif TYPE == int
printf("int");
#elif TYPE == double
printf("double");
#endif
那么即使定义TYPE为int等,它也会打印“ char”。
想法?
预处理程序#if计算整数表达式。 您试图将==视为正在比较令牌。 由于int,char,double等未定义为预处理器变量,因此它们的求值均为0。
你可以做
#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");
}
简单得多,而且有效。
如果您只需要指定TYPE,则可以执行以下操作
#define FMT_int "%d"
#define FMT_char "%c"
#define FMT_double "%f"
#define FMT PPCAT(FMT_, TYPE)
在我对C / C ++宏字符串连接的答案中定义了PPCAT
C和C ++预处理器只能使用数字(准确地说是数字文字)。 在表达式中,所有无法识别的单词(在所有宏扩展之后)都被视为0
。
您需要执行以下操作:
#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");
}
您可以使用boost.preprocessor通过预处理程序循环执行一些元编程魔术,而不是手动列出所有值。
当然,以上代码适用于C。如果您使用的是C ++,请使用模板而不是宏技巧,并使用std::cout
而不是printf()
。
您应该尽可能避免使用预处理器,这是何时避免使用预处理器的经典示例! 如果您需要编写取决于类型的代码,则可以使用模板,继承或多态。
在这种情况下,您可以将printArray
重写为模板函数:
template<class T>
void printArray(T *data, int count)
{
for(int i=0; i<count; i++)
{
cout << data[i] << " ";
}
cout << endl;
}
预处理程序评估或多或少类似于C ++评估。 它是数字的(尽管预处理器可以处理文本)。 宏扩展后剩余的任何预处理器符号都将替换为0
,并且C ++关键字仍然是预处理器中的符号。 (预处理器符号true
有一个特殊的例外,该符号扩展为1
)因此最后,所有比较都得出0 == 0
,这始终是正确的。
http://msdn.microsoft.com/zh-CN/library/ew2hz0yd(v=VS.80).aspx
constant-expression是具有一些附加限制的整数常量表达式。
看来您无法比较字符串。 请尝试以下操作:
#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.