预处理器#if不起作用

时间:2013-03-28 10:07:32

标签: c c-preprocessor

我正在尝试在 C 中编写一个somehow-generic 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

然后它将打印“int”,即使TYPE被定义为char,如果

#if TYPE == char
        printf("char");
#elif TYPE == int 
        printf("int");
#elif TYPE == double
        printf("double");
#endif

然后它会打印“char”,即使TYPE被定义为int等等。

想法?

5 个答案:

答案 0 :(得分:6)

预处理器#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)

其中PPCAT在我对C/C++ Macro string concatenation

的回答中定义

答案 1 :(得分:4)

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 ++,请使用模板而不是宏ha并使用std::cout代替printf()

答案 2 :(得分:1)

您应尽可能避免使用预处理器,这是何时避免使用预处理器的典型示例!如果您需要编写依赖于类型的代码,那么您可以使用模板,继承或多态。

在这种情况下,您可以将printArray重写为模板函数:

template<class T>
void printArray(T *data, int count)
{
  for(int i=0; i<count; i++)
  {
    cout << data[i] << " ";
  }

  cout << endl;
}

答案 3 :(得分:1)

预处理器评估或多或少像C ++评估。它 是数字的(尽管预处理器可以使用 文本)。宏之后仍然存在的任何预处理器符号 扩展由0替换,C ++关键字仍然是符号 在预处理器中。 (有一个特殊例外 预处理器符号true,扩展为1。)所以在 最后,你的所有比较都来自0 == 0,这是 总是如此。

答案 4 :(得分:0)

http://msdn.microsoft.com/en-us/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");
}