使用后删除typedef语句后,C链表不再有效

时间:2013-12-16 05:09:48

标签: c pointers linked-list typedef

我这里有一个程序来显示输入日的一周中的第二天。它不是一个实用或有效的程序,我只是用它来测试我学到的概念。它工作了一段时间,但在学习了typedef语句之后,我尝试将它们用于程序结构“工作日”来声明该类型的变量,但随后删除了typedef,因为它创建了错误(例如“不兼容的指针”和“不完整的定义”)。现在,即使我拿出了typedef语句,该文件也会显示错误。最奇怪的是,如果我将所有代码复制并粘贴到新文件中,则不会出现错误。有谁知道可能导致错误的原因?

#include <stdio.h>
#include <stdbool.h>

    struct weekday {
        char *ptrday;
        struct weekday *next;
    };

void matchtest(char *eday, struct weekday *head, struct weekday *cursor) {
    cursor=head;
    bool equalstring=true;

    while (cursor!=NULL) {
        char *p=cursor->ptrday;
        equalstring=true;

        while (*eday!='\0') {
            if (*eday!=*p) {
                equalstring=false;
                break;
            }
            ++eday; ++p;
        }
        if (equalstring==1) {
            printf("The next day of the week is %s\n", cursor->next->ptrday);
            break;
        }
        cursor=cursor->next;
    }
    if (equalstring==false)
        printf("The next day of the week is Sunday\n");
}

int main (void) {
    char enteredday[80], *ptreday=enteredday;
    struct weekday sunday, monday, tuesday, wednesday, thursday, friday, saturday;
    struct weekday *head=&sunday;
    struct weekday *cursor=NULL;

    sunday.ptrday="Sunday"; monday.ptrday="Monday"; tuesday.ptrday="Tuesday";
        wednesday.ptrday="Wednesday"; thursday.ptrday="Thursday";
        friday.ptrday="Friday"; saturday.ptrday="Saturday";

    sunday.next=&monday; monday.next=&tuesday; tuesday.next=&wednesday;
        wednesday.next=&thursday; thursday.next=&friday; friday.next=&saturday;
        saturday.next=NULL;


    printf("This is a test for the next day of the week.\n\n");
    printf("Enter a day ");

    scanf("%s", enteredday);
    matchtest(ptreday, head, cursor);

    return 0;
}

1 个答案:

答案 0 :(得分:1)

你遇到的一个问题是你在比较器函数中修改eday,但是如果比较失败,你就无法将搜索设置为从字符串的开头开始,因为你不知道字符串开始的地方了。这折磨了“星期四”,报道“第二天”是星期天。对于其他一些测试,这个工作正常。星期六之后的第二天被报告为星期日,因为有污泥。

您还有一个问题,即星期六之后的第二天未定义。

这是明智的工作代码。我使用strcmp()(因此也<string.h>)进行比较。我将while (cursor != NULL)循环转换为do { ... } while (cursor != head);循环,以便循环链接列表正常工作。我还会在读取时打印输入,并在正式输出中再次输出。这允许我使用bash的{​​{3}}符号(<<< string)进行测试,这很方便。请注意,输入检查EOF并将输入字符串限制为79个字符,从而防止缓冲区溢出(即堆栈溢出)。函数的'cursor'参数是不必要的;它在调用代码中设置为null,但被调用函数立即将其设置为head。所以该参数不再存在,但仍然需要该变量,因此它对于函数来说纯粹是局部的。

代码

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

struct weekday
{
    char *ptrday;
    struct weekday *next;
};

static void matchtest(char *eday, struct weekday *head)
{
    struct weekday *cursor = head;

    do
    {
        if (strcmp(eday, cursor->ptrday) == 0)
        {
            printf("The next day of the week after %s is %s\n", eday, cursor->next->ptrday);
            return;
        }
        cursor = cursor->next;
    } while (cursor != head);

    printf("The 'day of the week' %s does not match any day of the week!\n", eday);
}

int main(void)
{
    char enteredday[80];
    struct weekday sunday, monday, tuesday, wednesday, thursday, friday, saturday;
    struct weekday *head = &sunday;

    sunday.ptrday = "Sunday";
    monday.ptrday = "Monday";
    tuesday.ptrday = "Tuesday";
    wednesday.ptrday = "Wednesday";
    thursday.ptrday = "Thursday";
    friday.ptrday = "Friday";
    saturday.ptrday = "Saturday";

    sunday.next = &monday;
    monday.next = &tuesday;
    tuesday.next = &wednesday;
    wednesday.next = &thursday;
    thursday.next = &friday;
    friday.next = &saturday;
    saturday.next = &sunday;

    printf("This is a test for the next day of the week.\n\n");
    printf("Enter a day ");

    if (scanf("%79s", enteredday) == 1)
    {
        printf("Got: [%s]\n", enteredday);
        matchtest(enteredday, head);
    }

    return 0;
}

示例运行

$ for d in Sunday Monday Tuesday Wednesday Thursday Friday Saturday Otherday; do ./nwd <<< $d; done
This is a test for the next day of the week.

Enter a day Got: [Sunday]
The next day of the week after Sunday is Monday
This is a test for the next day of the week.

Enter a day Got: [Monday]
The next day of the week after Monday is Tuesday
This is a test for the next day of the week.

Enter a day Got: [Tuesday]
The next day of the week after Tuesday is Wednesday
This is a test for the next day of the week.

Enter a day Got: [Wednesday]
The next day of the week after Wednesday is Thursday
This is a test for the next day of the week.

Enter a day Got: [Thursday]
The next day of the week after Thursday is Friday
This is a test for the next day of the week.

Enter a day Got: [Friday]
The next day of the week after Friday is Saturday
This is a test for the next day of the week.

Enter a day Got: [Saturday]
The next day of the week after Saturday is Sunday
This is a test for the next day of the week.

Enter a day Got: [Otherday]
The 'day of the week' Otherday does not match any day of the week!
$

正如您所知,我不喜欢不止一次输入输入。


使用typedef

的代码

还在数组中使用链接列表(尽管你也可以使用日期名称数组)。

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

typedef struct Weekday Weekday;
struct Weekday
{
    char *ptrday;
    Weekday *next;
};

Weekday days_of_the_week[7] =
{
    { "Sunday",    &days_of_the_week[1] },
    { "Monday",    &days_of_the_week[2] },
    { "Tuesday",   &days_of_the_week[3] },
    { "Wednesday", &days_of_the_week[4] },
    { "Thursday",  &days_of_the_week[5] },
    { "Friday",    &days_of_the_week[6] },
    { "Saturday",  &days_of_the_week[0] },
};

static void matchtest(char *eday, Weekday *head)
{
    Weekday *cursor = head;

    do
    {
        if (strcmp(eday, cursor->ptrday) == 0)
        {
            printf("The next day of the week after %s is %s\n", eday, cursor->next->ptrday);
            return;
        }
        cursor = cursor->next;
    } while (cursor != head);

    printf("The 'day of the week' %s does not match any day of the week!\n", eday);
}

int main(void)
{
    char enteredday[80];

    printf("This is a test for the next day of the week.\n\n");
    printf("Enter a day ");

    if (scanf("%79s", enteredday) == 1)
    {
        printf("Got: [%s]\n", enteredday);
        matchtest(enteredday, days_of_the_week);
    }

    return 0;
}