簡體   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