【问题标题】:Don't understand how tsearch return pointers work不明白 tsearch 返回指针是如何工作的
【发布时间】:2014-02-17 22:00:17
【问题描述】:

我一直在试图弄清楚 tsearch 库是如何工作的,但我已经到了完全被难住的地步。这是我的代码:

#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <stdlib.h>
#include <dirent.h>
#include <utime.h>
#include <sys/wait.h>
#include <sys/msg.h>
#include <signal.h>
#include <ctype.h>
#include <search.h>

int compare (const void *a, const void *b);
void action(const void *nodep, VISIT value, int level);

struct word {
    char word[100];
    int occur;          
};

int main (void) {
    void *root = NULL;
    char *words[] = {"a","b","c","a"};
    struct word *entry = malloc(10 * sizeof(struct word));  
    struct word *ptr;
    struct word *ptr2;
    int i;  

    for (i=0;i<4;i++) {
        memcpy(entry[i].word,words[i],100);
        entry[i].occur = 1;                 
        ptr = tfind(&entry[i],&root,compare);
        if (ptr == NULL) {          
            tsearch(&entry[i],&root,compare);
        }
        else {              
            printf("%i\n",ptr->occur);
            printf("%i\n",entry[0].occur);          
            entry[0].occur++;           
        }
    }
    twalk (root, action);   
    //tdestroy (&rootp,freefct);
    return 0;
}

int compare (const void *a, const void *b) {
    const struct word *w1, *w2;

    w1 = (const struct word *) a;
    w2 = (const struct word *) b;

    return strcmp(w1->word, w2->word);
}

void action(const void *nodep, VISIT value, int level) {
    struct word *w = *((struct word **) nodep);
    switch (value) {
    case leaf:
    case postorder:
        printf("%s: %i\n",w->word, w->occur);
        break;
    default:
        break;
    }
    return;
}

现在,我认为 ptr 应该指向 entry[0] (因为那是它找到的值所在的位置)并且 ptr->occur 应该给我“a”的发生值。但事实并非如此。它给了我 0,结果如下所示:

0 1 a2 乙:1 c: 1

更改 entry[0] 的值确实会更改它在步行期间打印的内容。

我已经尝试了所有我能想到的取消引用或强制转换 ptr 的组合,将其声明为 void* 或 struct word*...

所以我的问题基本上是:

给定 tfind 的返回值(以及应该声明为什么),我如何访问结构中的值?

【问题讨论】:

    标签: c binary-search-tree


    【解决方案1】:

    tfind 的返回值不是入口,它是指向树内部节点结构的指针,其第一个元素是指向入口的指针。由于节点结构是不透明的,你可以把ptr想象成一个结构词**。

    如果您将 else 部分重写为

        else {
            printf("i=%d ptr=%p *ptr=%p entry=%p,%p,%p,%p\n", i, ptr, *(struct word **)ptr, entry, entry+1, entry+2, entry+3);
            printf("wrong: %i\n",ptr->occur);
            printf("right: %i\n",(*(struct word **)ptr)->occur);
            printf("right: %i\n",entry[0].occur);
            entry[0].occur++;
        }
    

    你会得到(至少在我的机器上)

    i=3 ptr=0x8f32430 *ptr=0x8f32010 entry=0x8f32010,0x8f32078,0x8f320e0,0x8f32148
    wrong: 0
    right: 1
    right: 1
    a: 2
    b: 1
    c: 1
    

    如您所见,指向 elem[0] 的不是 ptr,而是 *ptr。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-19
      • 1970-01-01
      • 2021-03-30
      • 1970-01-01
      • 1970-01-01
      • 2018-11-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多