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

TYPEがcharに定義されていても、「int」を出力します。

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

次に、TYPEがintなどに定義されている場合でも、「char」を出力します。

アイデア?

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

はるかに簡単で、機能します。

TYPEのみを指定したい場合は、次のようにすることができます

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

PPCAT は、C/C++ マクロ文字列連結に対する私の回答で定義されています

于 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++ を使用している場合は、マクロ ハックの代わりにテンプレートを使用しstd::coutprintf().

于 2013-03-28T10:14:19.503 に答える
1

プリプロセッサの評価は、多かれ少なかれ C++ の評価に似ています。これは数値です (プリプロセッサがテキストを処理するという事実にもかかわらず)。マクロ展開後に残るプリプロセッサ シンボルは に置き換えられ0、C++ キーワードはプリプロセッサ内のシンボルのままです。(プリプロセッサ シンボル には特別な例外がありtrue、これは に展開され1ます。)したがって、最終的に、すべての比較は になり0 == 0ます。これは常に true です。

于 2013-03-28T10:14:16.610 に答える
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 に答える
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");
}
于 2013-03-28T10:22:06.517 に答える