1

我正在尝试在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

那么它将打印“int”,即使 TYPE 被定义为 char,并且如果

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

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

想法?

4

5 回答 5

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");
}

简单得多,并且有效。

如果您只想指定类型,您可以执行类似的操作

#define FMT_int "%d"
#define FMT_char "%c"
#define FMT_double "%f"
#define FMT PPCAT(FMT_, TYPE)

在我对C/C++ 宏字符串连接的回答中定义了 PPCAT

于 2013-03-28T10:13:16.560 回答
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++,请使用模板而不是宏 hacks,std::cout而不是printf().

于 2013-03-28T10:14:19.503 回答
1

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

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

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

  cout << endl;
}
于 2013-03-28T10:11:59.477 回答
1

预处理器评估或多或少类似于 C++ 评估。它是数字的(尽管预处理器处理文本)。宏扩展后保留的任何预处理器符号都将替换为0,并且 C++ 关键字仍然是预处理器中的符号。(预处理器符号 有一个特殊的例外true,它扩展为1。)所以最后,你所有的比较结果都是0 == 0,这总是正确的。

于 2013-03-28T10:14:16.610 回答
0

http://msdn.microsoft.com/en-us/library/ew2hz0yd(v=VS.80).aspx

常量表达式是一个带有一些附加限制的整数常量表达式。

看来你无法比较字符串。尝试以下操作:

#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");
}
于 2013-03-28T10:22:06.517 回答