3

二分探索木データ構造を使用して、一連の構造体を型定義で並べ替えています。

typedef struct {
    char c;
    int index;
} data_t;

typedef struct node node_t;

typedef node {
    void *data;
    node_t *left;
    node_t *right;
}

node_t typedef は、この目的のために私に提供されたライブラリからのもので、おそらくポリモーフィズムを確保するための void* ポインターを使用しています。 node関数に渡されます:

static void *recursive_search_tree(node_t *root, void *key, int cmp(void*,void*))

recursive_search_tree 関数内で、コードを変更して、index 要素を条件として使用して、文字の配列に対する線形パスのインデックスに最も近い一致を見つけられるようにしたいと考えています。これには、最終的に data_t が渡され*keykey->index関数内でアクセスされています。

質問

key->indexキーが構造体をvoid*指している場所にアクセスすることは可能ですか、それともキーの型として宣言されているdata_t場合にのみ可能でしょうか? data_t私は後者をやろうとしましたが、ポインターを int にキャストしてもコンパイラーを通過しないようです。

4

2 に答える 2

3

確かに可能です。 keytype としてキャストします*data_t。(それが本当にkey指している限り!)

key                     /* argument of type void* */
(data_t*)key            /* cast as type data_t*   */
((data_t*)key)->index   /* dereferenced */

簡単な例を次に示します。

#include <stdlib.h>
#include <stdio.h>

typedef struct {
    char    c;
    int     index;
} data_t;

typedef struct node {
    void    *data;
    struct node *left;
    struct node *right;
} node_t;

static int cmp(void *lhs, void *rhs)
{
    return ((data_t *)lhs)->index - ((data_t *)rhs)->index;
}

int main(void)
{
    data_t d0;
    data_t d1;

    d0.c     = 'A';
    d0.index = 1;
    d1.c     = 'B';
    d1.index = 2;

    printf("d0 < d1? %s\n", (cmp((void *)&d0, (void *)&d1) < 0 ? "yes" : "no"));
    printf("d1 < d0? %s\n", (cmp((void *)&d1, (void *)&d0) < 0 ? "yes" : "no"));

    return EXIT_SUCCESS;
}
于 2012-10-21T05:39:26.043 に答える
0

void の使用と同様に、これはタイプセーフではありません。void の使用は、通常、中間体が他の誰かの便宜のために使用しないものを保持しているためです。これは、ツリーに必要なものを何でも保持できるようにする C 関数です。与えられたポインタを返すだけです。

検索機能で

int cmp(void* dt1, void* dt2)
{
data_t*  data1 = (data_t*)dt1;
data_t*  data2 = (data_t*)dt2;
/* Do what you need with data1 and data2 here */
}

必要なことは何でもさせてくれるはずです。問題は、関数内で値をキャストする必要があることです。cmp へのパラメータは、使用しているライブラリの API と正確に一致する必要があります。これは、パラメータが void* であることを示しています。

于 2012-10-21T05:47:37.253 に答える