我具有以下数据结构:
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;
}
我具有以下这些功能来测试上一个功能:
#include <stdio.h>
void printWordList(WordList w) {
for ( ; w; w = w->next_word)
printf("Word: %s\nOccurrences: %d\n\n",
w->word, w->occur);
}
int main(void) {
WordList w = NULL;
addAtHead(&w, "world");
addAtHead(&w, "hello");
printWordList(w);
return 0;
}
当我编译并运行可执行文件时,会得到以下结果:
> Word: world Occurrences: 1
>
> Word: hello Occurrences: 1
>
> Word: world Occurrences: 1
>
> Word: hello Occurrences: 1
>
> Word: world Occurrences: 1
>
> Word: hello Occurrences: 1
然后继续。
我假设我在代码中的某个地方将最后一个元素链接到第一个元素,因此我绘制了以下图表以找出发生这种情况的地方。
然后我假设问题出在*w = new;
行中。
如何在不创建循环列表的情况下再次将*w
设置为列表的开头?
答案 0 :(得分: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;
}
如果您想在函数中更改指针并想找回该更改后的指针,请执行以下操作:返回指针(该函数的构建类似于Wordlist * addAtHead(....)
,或者可以(在我们的情况下)使用指向该指针。您必须获得对该指针的引用。