我正在编写一个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
目前在添加中,错误发生在它之前。我相信我没有以任何非法的方式修改第一或第二的值?
我在哪里弄错了?
答案 0 :(得分: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
或second
设置为NULL
。那么其他if
语句会发生什么?您将取消引用NULL
指针!
您想要的是if-else if
链。
答案 1 :(得分: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
}
一些注意事项:
one
或two
列表之一已耗尽,现在位于主循环中。没有特殊情况。*head
的特殊情况与正常情况合并(其中*head
不为NULL)只需将*pp
移动到下一个插入位置即可。再说一遍:没有特殊情况。答案 2 :(得分:0)
Segmentation fault (core dumped)
由于它已经segfaulted并生成了一个核心文件,你可以启动gdb或你选择的调试器,看看它确切崩溃的位置。
如果您发布,可能有帮助。
正如Alter Mann指出的那样,你使用了新的未初始化的添加:
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在任何地方成功。