1

私は現在、ネット上で見つけたいくつかのソース コードを調べています。これは、理解できない方法でプリプロセッサ マクロを利用しています。クワッドエッジデータ構造を実装しています。誰かが私のために物事を明確にしてくれることを願っています!

typedef int edge_ref;

typedef struct {
    edge_ref next[4];
    void *data[4];
    unsigned mark;
} edge_struct;

#define ROT(e) (((e)&0xfffffffcu)+(((e)+1)&3u))
#define SYM(e) (((e)&0xfffffffcu)+(((e)+2)&3u))
#define TOR(e) (((e)&0xfffffffcu)+(((e)+3)&3u))

#define ONEXT(e) ((edge_struct *)((e)&0xfffffffcu))->next[(e)&3]
#define ROTRNEXT(e) ((edge_struct *)((e)&0xfffffffcu))->next[((e)+1)&3]
#define SYMDNEXT(e) ((edge_struct *)((e)&0xfffffffcu))->next[((e)+2)&3]
#define TORLNEXT(e) ((edge_struct *)((e)&0xfffffffcu))->next[((e)+3)&3]

#define MARK(e)  ((edge_struct *)((e)&0xfffffffcu))->mark

そして、これはそれらがどのように使用されるかです:

edge_ref e;
e = (edge_ref) malloc(sizeof(edge_struct));
ONEXT(e) = e;
SYMDNEXT(e) = SYM(e);
ROTRNEXT(e) = TOR(e);
TORLNEXT(e) = ROT(e);
MARK(e) = 0;
return e;

これは、私が問題を抱えていることを概説するための単なる抜粋です。全体はここで見つけることができます

4

5 に答える 5

2

これらのマクロは単純なコード置換です。何をしているのかは別のことです。

ONEXT(e) = e;

((edge_struct *)((e)&0xfffffffcu))->next[(e)&3] = e; になります。

アドレスに関連するデータを含む構造をロードしているように見えます。

マクロに圧倒されないでください。マクロのコードを置き換えて、それが何をするかを理解してください。その後、書き直してコメントを追加し、次の人が今のあなたを経験する必要がないようにします。

于 2010-05-12T15:34:17.110 に答える
1

彼らは、malloc 関数が少なくとも 4 バイトにアラインされたメモリ アドレスを返すと想定しています。彼らは、すべてのメモリ割り当てがゼロに設定された下位 2 ビットの値になると想定しているため、これらの 2 ビットを使用して情報を格納しています。したがって、構造内のデータを取得するには、これらの 2 つのビットをクリアして真のアドレスを取得する必要があります。

((edge_struct *)((e)&0xfffffffcu))

したがって、edge_ref は、edge_struct 型のオブジェクトへのポインターであり、オブジェクトの内部配列 ((e)&3u ビット) へのインデックスです。

以下のファイル: 巧妙ですが、euurrgghh ( XOR リストと並んで)。

于 2010-05-12T15:39:38.423 に答える
1

0xfffffffcuは、0 である最後の 2 ビットを除くすべてのビットが 1 に設定された符号なし定数11111111111111111111111111111100です。の下位 2 ビットを操作するためのマスクとして使用されていますe。これらのマクロの要点は、循環配列として扱う 4 つの構造体の配列 (つまり、モジュロ 4 インデックス) を操作できるようにすることです。

于 2010-05-12T15:32:54.507 に答える
1

少々お待ちください...

typedef int edge_ref;

#define ONEXT(e) ((edge_struct *)((e)&0xfffffffcu))->next[(e)&3]

e = (edge_ref) malloc(sizeof(edge_struct));
ONEXT(e) = e;

malloc の戻り値は signed int にキャストされ、NULL のチェックなしで使用され、unsigned int でマスクされます...

このコードの目的はわかりませんが、いかなる目的にも使用しないことを強くお勧めします。

于 2010-05-12T15:35:12.083 に答える
0

私の推測では、ポインターが整列していると仮定して、ポインターにタグを追加したと思います。(逆参照の前にマスキング操作があるのはそのためです)。

于 2010-05-12T15:38:39.940 に答える