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