0

我正在编写一个 C 程序来表示链表中的多项式。这是我到目前为止所做的。

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

struct poly
{
    float coef;
    int exp;
    struct poly* next;
};

void make(struct poly**, float, int);
void display(struct poly*);

void add(struct poly*, struct poly*, struct poly**);

int main()
{
    struct poly *first, *second, *final;
    int expa, expb, i;
    float data;

    first = second = final = NULL;

    printf("Enter maximum exponent for polynomial A ");
    scanf("%d", &expa);

    printf("Enter data for polynomial A\n");

    for(i=0;i<=expa;i++)
    {
        printf("Enter coefficient for exponent %d ", expa - i);
        scanf("%f", &data);

        make(&first, data, expa - i);
    }

    printf("Displaying polynomial A ");
    display(first);

    printf("Enter maximum exponent for polynomial B ");
    scanf("%d", &expb);

    printf("Enter data for polynomial B\n");

    for(i=0;i<=expb;i++)
    {
        printf("Enter coefficient for exponent %d ", expb - i);
        scanf("%f", &data);

        make(&second, data, expb - i);
    }

    printf("Displaying polynomial B ");
    display(second);

    printf("Now adding polynomials A and B \n");
    add(first, second, &final);

    display(final);
    return 1;
}

void make(struct poly**head, float coef, int exp)
{
    struct poly *new, *temp;

    new = (struct poly*)malloc(sizeof(struct poly));
    new->coef = coef;
    new->exp = exp;
    new->next = NULL;
    temp = *head;

    if(temp == NULL)
    {
        *head = new;
        return;
    }
    while(temp->next)
        temp = temp->next;

    temp->next = new;
}

void display(struct poly*head)
{
    struct poly*temp = head;

    while(temp)
    {
        printf("%.1fx^%d ", temp->coef, temp->exp);
        temp = temp->next;
    }
    printf("\nExiting display\n");
}

void add(struct poly*first, struct poly*second, struct poly**sum)
{
    struct poly* new;
    printf("Currently in add");
    if(first == NULL && second == NULL)
        return;

    while(first&&second)
    {
        if((*sum)==NULL)
        {
            new = (struct poly*)malloc(sizeof(struct poly));
            *sum = new;
        }
        else
        {
            new->next = (struct poly*)malloc(sizeof(struct poly));
            new = new->next;
        }

        if(first->exp == second->exp)
        {
            new->exp = first->exp;
            new->coef = first->coef + second->coef;

            first = first->next;
            second = second ->next;
        }

        if(first->exp > second->exp)
        {
            new->exp = first->exp;
            new->coef = first->coef;
            first = first->next;
        }

        if(first->exp < second->exp)
        {
            new->exp = second->exp;
            new->coef = second->coef;
            second = second->next;
        }
        new->next = NULL;
    }

    while(first)
    {
        new->next = (struct poly*)malloc(sizeof(struct poly));
        new->coef = first->coef;
        new->exp = first->exp;
        new->next = NULL;
        first = first->next;
    }

    while(second)
    {
        new->next = (struct poly*)malloc(sizeof(struct poly));
        new->coef = second->coef;
        new->exp = second->exp;
        new->next = NULL;
        second= second->next;
    }
}

I am receiving output:
./PolynomialAdditionLinkedList.out 
Enter maximum exponent for polynomial A 2
Enter data for polynomial A
Enter coefficient for exponent 2 1
Enter coefficient for exponent 1 2
Enter coefficient for exponent 0 1
Displaying polynomial A 1.0x^2 2.0x^1 1.0x^0 
Exiting display
Enter maximum exponent for polynomial B 2
Enter data for polynomial B
Enter coefficient for exponent 2 1
Enter coefficient for exponent 1 6
Enter coefficient for exponent 0 9
Displaying polynomial B 1.0x^2 6.0x^1 9.0x^0 
Exiting display
Now adding polynomials A and B 
Segmentation fault (core dumped)

从输出来看,我在下一行中似乎有错误。 add(first, second, &final); As the output doesn't prints当前在 add` 中,在它之前发生错误。我相信我没有以任何非法方式修改第一或第二的值?我在哪里犯错了?

4

3 回答 3

3

add函数中,您有以下代码:

if(first->exp == second->exp)
{
    new->exp = first->exp;
    new->coef = first->coef + second->coef;

    first = first->next;
    second = second ->next;
}

if(first->exp > second->exp)
{
    new->exp = first->exp;
    new->coef = first->coef;
    first = first->next;
}

if(first->exp < second->exp)
{
    new->exp = second->exp;
    new->coef = second->coef;
    second = second->next;
}

现在想一想,在第一个if语句中,当您位于其中一个列表的最后一个节点时会发生什么。这意味着您将设置first或设置secondNULL。那么其他if语句会发生什么?您将取消引用NULL指针!

你想要的是一个if-else if链条。

于 2013-10-09T10:03:18.313 回答
1

您可以通过删除重复、合并常见情况来大大简化 add() 函数。下面的函数使用goto,它没有你想象的那么有害:

struct poly *merge(struct poly *one, struct poly *two)
{
    struct poly *new,*result, **pp;
    fprintf(stderr, "Currently in merge\n");

    result=NULL;
    for(pp= &result; one || two; pp = &(*pp)->next ) {
       *pp = new = malloc (sizeof *new);
       new->next = NULL;
       if (!one) goto use_two;
       if (!two) goto use_one;
          /* when we get here, one and two are both non-null */
       if (one->exp > two->exp) goto use_one;
       if (one->exp < two->exp) goto use_two;
       if (one->exp == two->exp) goto use_both;

use_both: /* useless label for clarity */
       new->coef = one->coef + two->coef;
       new->exp = two->exp;
       two = two->next;
       one = one->next;
       continue;
use_two:
       new->coef = two->coef;
       new->exp = two->exp;
       two = two->next;
       continue;
use_one:
       new->coef = one->coef;
       new->exp = one->exp;
       one = one->next;
       continue;
       }

return result;
}

这应该从 main 调用为:

    ...
    printf("Now adding polynomials A and B \n");
    // add(first, second, &final);
    final = merge (first, second);

    display(final);
    return 0; // <<-- main() should return 0 or EXIT_SUCCESS 
}

几点注意事项:

  • 我更改了函数的签名,它现在返回创建的术语链接列表,而不是将其分配给作为参数传递的指针
  • 您可以尝试通过开关、内联函数或宏来替换 goto 和三个标签。结果会更加混乱,至少不那么紧凑。
  • 或列表之一用尽的特殊情况现在位于主循环中。没有特殊情况。onetwo
  • 仅通过移动到下一个位置进行插入,将分配第一个结果节点的这些特殊情况*head正常情况(其中*head不为 NULL)合并。*pp再说一遍:没有特殊情况。
于 2013-10-09T13:42:17.130 回答
0
Segmentation fault (core dumped)

由于它已经发生了段错误并生成了一个核心文件,因此您可以启动 gdb 或您选择的调试器并查看它崩溃的确切位置。

如果您发布它,它可能会有所帮助。

正如 Alter Mann 指出的那样,您在 add 中使用 new uninitialised:

else
{
    new->next = (struct poly*)malloc(sizeof(struct poly));

如果 SUM 不为空,则进入这种情况,并且在第一次迭代时尚未分配 new,因此您正在取消引用一些随机指针。哪个不是 NULL,因为你没有初始化它,所以即使你确实检查了新的 NULL,它可能仍然会出现段错误。

void add(struct poly*first, struct poly*second, struct poly**sum)
{
    struct poly* new;

应该:

void add(struct poly*first, struct poly*second, struct poly**sum)
{
    struct poly* new=NULL;

这一行不检查新的,它检查总和。

if((*sum)==NULL)
{

编辑:最后一个想法。您实际上并没有检查 malloc 是否在任何地方成功。

于 2013-10-09T10:48:59.057 回答