简体   繁体   English

预处理程序#if不起作用

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM