繁体   English   中英

预处理程序#if不起作用

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

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