我正在尝试在 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等等。
想法?
答案 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");
}