3

このように定義された2つの列挙型があります

enum foo {
    foo_a = 0x1,
    foo_b = 0x2,
    foo_c = 0x4,
    foo_d = 0x8,
    foo_e = 0x10,
    ..etc..
}

enum bar {
    bar_a = 0x1,
    bar_b = 0x2,
    bar_c = 0x4,
    bar_d = 0x8,
    bar_e = 0x10,
    ..etc..
}

現在、foo_[az] と bar_[az] の間に 1 対 1 のマッピングがあり、すぐに調べたいと思います。これを行う明白な方法は、次のような宣言を行うことです

int table[][] = {
    [foo_a] = bar_c,
    [foo_b] = bar_a,
    [foo_c] = bar_b,
    ..etc..
}

を使用して調べるだけですresult = table[(enum foo)temp]。しかし、これらの列挙型はビットごとに宣言されているため、のサイズはtable指数関数的に大きくなります。

コンパイル時に設定する簡単な方法はありますか?

私が何かをすることを考えた1つのこと

int table[][] = {
    [LOG(foo_a)] = bar_c,
    [LOG(foo_b)] = bar_a,
    [LOG(foo_c)] = bar_b,
    ..etc..
}

これによりメモリのフットプリントが削減されますが、とにかくコンパイル時に LOG を計算することを知りません。

他の提案はありますか?

私の唯一の制限は次のとおりです。列挙型を変更するとバイナリの非互換性が発生するため、列挙型を変更することはできません。

編集:コンパイル時のソリューションが望ましい

4

3 に答える 3

3

はい、引数が 2 の累乗である限り、「コンパイル時にログを計算」できます。

#define LOG2P2(m) (((m)-1)/(((m)-1)%255+1) / 255%255*8 + 7-86/(((m)-1)%255+12))

これはm、約 2**2040 (実際の C 実装のどの型よりもはるかに大きい) までの値で機能し、次の質問への回答で、これを取得したさらに大きな値で機能するバージョンがあります。 :

https://stackoverflow.com/a/4589384/379897

于 2013-03-12T04:07:03.037 に答える
1

Just make a table of pairs:

int table[2][] = {
  { foo_a, bar_c },
  { foo_b, bar_a },
  /* ... */
};

Now sort it, and if you want, copy it to a second table which is sorted by the second value to do the reverse lookup. Then do linear search if the table is only a dozen elements, or use bsearch() if it's large.

于 2013-03-12T03:37:55.277 に答える
0

すべての列挙型の値がわかっている場合は、すべての列挙型のログを計算し、それらをバッファーに格納できます。または、すべてのログを書き込むことができます。ファイル内の値 (使用する予定) を読み取り、そのファイルを読み取ってテーブルを生成します。そのようにして、ログを計算します。値は初回のみです。

于 2013-03-12T03:47:59.830 に答える