C 如果元素不是',则在链接列表的开头添加元素;不在名单上

C 如果元素不是',则在链接列表的开头添加元素;不在名单上,c,singly-linked-list,C,Singly Linked List,我有以下数据结构: typedef struct Word { char *word; int occur; struct Word *next_word; } * WordList; 我正在尝试实现一个函数,将字符串(单词)添加到WordList。如果它已经存在于列表中,则增加其出现次数,否则,将其添加到头部。此函数还返回所述单词在列表中的出现次数 以下是我的实施: #include <stdlib.h> #include <string.h>

我有以下数据结构:

typedef struct Word {
    char *word;
    int occur;
    struct Word *next_word;
} * WordList;
我正在尝试实现一个函数,将字符串(单词)添加到
WordList
。如果它已经存在于列表中,则增加其出现次数,否则,将其添加到头部。此函数还返回所述单词在列表中的出现次数

以下是我的实施:

#include <stdlib.h>
#include <string.h>

int addAtHead(WordList *w, char *word) {
    WordList head = *w;

    while (*w && strcmp((*w)->word, word) != 0)
        w = &(*w)->next_word;

    if (!*w) {
        WordList new = malloc(sizeof(struct Word));

        size_t length = strlen(word) + 1;
        new->word = malloc(length);
        memcpy(new->word, word, length);

        new->occur = 0;

        new->next_word = head;
        *w = new;
    }

    return ++(*w)->occur;
}
不停地,不停地

我假设在我的代码中的某个地方,我将最后一个元素链接到第一个元素,所以我绘制了下面的图表来找出这种情况发生的地方

然后我假设问题在于行
*w=new
如何将
*w
设置为再次开始列表,而不创建循环列表?

我稍微简化了您的代码。。。也许你会想到:

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

typedef struct Word {
  char *word;
  int occur;
  struct Word *next_word;
}WordList;

int addAtHead(WordList **w_ptr, char *word) {
  WordList *head, *w;
  w = *w_ptr;
  head = w;

  while (w != NULL && strcmp(w->word, word) != 0)
     w = w->next_word;

  if (w == NULL) {
     WordList *newstruct;
     newstruct = malloc(sizeof *newstruct);
     if(newstruct == NULL) /* out of memory etc. */
       return -1;
     size_t length = strlen(word) + 1;
     newstruct->word = malloc(length);
     if(newstruct->word == NULL){
       free(newstruct);
       return -2;
     }
     memcpy(newstruct->word, word, length);

     newstruct->occur = 0;
     newstruct->next_word = head;
     w = newstruct;
     printf("address: %p, head: %p\n", w, head);
     *w_ptr = newstruct;
  }
  return ++(w->occur);
}

void printWordList(WordList *w) {
  for ( ; w; w = w->next_word)
     printf("Word: %s\nOccurrences: %d\n\n",
        w->word, w->occur);
}

int main(void) {
  int rv = 0;    
  WordList *w = NULL;

  rv = addAtHead(&w, "world");
  printf("addAtHead = %d\n",rv);
  rv = addAtHead(&w, "hello");
  printf("addAtHead = %d\n",rv);
  if(w == NULL){
    printf("w == NULL\n");
  } else { 
    printf("pointer address: %p\n",w);  
  }
  printWordList(w);
  return 0;
}
#包括
#包括
#包括
typedef结构字{
字符*字;
int发生;
结构单词*下一个单词;
}词表;
int addAtHead(单词列表**w_ptr,字符*单词){
词表*头,*w;
w=*w_ptr;
水头=w;
while(w!=NULL&&strcmp(w->word,word)!=0)
w=w->下一个单词;
如果(w==NULL){
单词表*newstruct;
newstruct=malloc(sizeof*newstruct);
如果(newstruct==NULL)/*内存不足等*/
返回-1;
长度=strlen(单词)+1;
newstruct->word=malloc(长度);
if(newstruct->word==NULL){
免费(新闻特约);
返回-2;
}
memcpy(newstruct->word、word、length);
newstruct->occurse=0;
新闻结构->下一个单词=标题;
w=新结构;
printf(“地址:%p,标题:%p\n”,w,标题);
*w_ptr=新结构;
}
返回++(w->发生);
}
作废打印字表(字表*w){
对于(;w;w=w->下一个单词)
printf(“单词:%s\n当前:%d\n\n”,
w->单词,w->出现);
}
内部主(空){
int-rv=0;
WordList*w=NULL;
rv=添加头(&w,“世界”);
printf(“addhaad=%d\n”,rv);
rv=addAtHead(&w,“你好”);
printf(“addhaad=%d\n”,rv);
如果(w==NULL){
printf(“w==NULL\n”);
}否则{
printf(“指针地址:%p\n”,w);
}
打印字表(w);
返回0;
}

如果您想更改函数中的指针并想将更改后的指针取回:要么返回指针(函数的构建方式类似于
Wordlist*addAtHead(…)
),要么可以使用(在我们的例子中)指向该指针的指针。您必须获取对该指针的引用。

发布的代码无法编译。
单词列表的定义是什么?\include语句是
stdio.h
需要的。此语句:
单词列表w=NULL;
应该是:
单词列表*w=NULL;
请发布一个所以我们可以帮助您。@user3629249编译代码需要以下include语句。我选择不包含它们,因为它们是隐式的。
\include\include\include
WordList
定义为
typedef struct Word*WordList;
,与定义结构的位置相同。stackoverflow对于与运行时问题有关的问题,正如此问题所做的那样,需要一个完整的输入、输出、干净编译的代码等。请编辑此问题,不要将代码放入注释中。参考:
typedef struct Word{char*Word;int-occure;struct Word*next_Word;}*WordList;
不要在
typedef
s中隐藏指针。而是在声明typedef的实例时创建指针。此外,此:
*WordList;
应该是:
WordList*;
@user3629249实际上,优先级是可以的。问题在于创建循环链接的行
new->->nextWord=head;
将列表从最后一个节点返回到头部。
> Word: world Occurrences: 1
> 
> Word: hello Occurrences: 1
> 
> Word: world Occurrences: 1
> 
> Word: hello Occurrences: 1
> 
> Word: world Occurrences: 1
> 
> Word: hello Occurrences: 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Word {
  char *word;
  int occur;
  struct Word *next_word;
}WordList;

int addAtHead(WordList **w_ptr, char *word) {
  WordList *head, *w;
  w = *w_ptr;
  head = w;

  while (w != NULL && strcmp(w->word, word) != 0)
     w = w->next_word;

  if (w == NULL) {
     WordList *newstruct;
     newstruct = malloc(sizeof *newstruct);
     if(newstruct == NULL) /* out of memory etc. */
       return -1;
     size_t length = strlen(word) + 1;
     newstruct->word = malloc(length);
     if(newstruct->word == NULL){
       free(newstruct);
       return -2;
     }
     memcpy(newstruct->word, word, length);

     newstruct->occur = 0;
     newstruct->next_word = head;
     w = newstruct;
     printf("address: %p, head: %p\n", w, head);
     *w_ptr = newstruct;
  }
  return ++(w->occur);
}

void printWordList(WordList *w) {
  for ( ; w; w = w->next_word)
     printf("Word: %s\nOccurrences: %d\n\n",
        w->word, w->occur);
}

int main(void) {
  int rv = 0;    
  WordList *w = NULL;

  rv = addAtHead(&w, "world");
  printf("addAtHead = %d\n",rv);
  rv = addAtHead(&w, "hello");
  printf("addAtHead = %d\n",rv);
  if(w == NULL){
    printf("w == NULL\n");
  } else { 
    printf("pointer address: %p\n",w);  
  }
  printWordList(w);
  return 0;
}