作为作业的一部分,我需要写两个函数:
由于某种原因,两个函数分别完美地工作,但是当我尝试在sum函数的结果上使用print函数时,它会在print函数的开头改变sum的值,并打印出错误的价值。当我使用printf在main中打印相同的值时,没有问题。我的代码详述如下。有任何想法吗?
void main()
{
int a[1] = { 1 },
b[1] = { 2 };
int * *pa, **pb;
List lst1, lst2;
List sum;
pa = (int * *) malloc(sizeof(int * )); * pa = &a[0];
pb = (int * *) malloc(sizeof(int * )); * pb = &b[0];
lst1 = arrToList(pa, 1);
lst2 = arrToList(pb, 1);
addNumbers(lst1, lst2, &sum);
//printf("%d\n",*(sum.head->dataPtr));
printNumber(sum);
}
//a function that recieves a number represented ad a list and prints it
void printNumber(List num)
{
ListNode * curr;
int currData,
i,
number;
if (isEmptyList(num) == TRUE)
printf("the input was an empty list, nothing to print");
else
{
i = 0;
number = 0;
curr = num.head;
while (curr != NULL)
{
currData = *(curr - >dataPtr);
number = number + currData * ((int) pow(10, i));
curr = curr - >next;
i++;
}
printf("%d \n", number);
}
}
// a function that sums in list
// representation two numbers,
// each represented as a list
void addNumbers(List n1, List n2, List * sum)
{
ListNode * currN1;
ListNode * currN2;
ListNode * currSum;
int currN1N2Sum; //stores the sum of the current digits in n1 and n2
int carrier,
prevCarrier; //current and previous carriers that carries +1 to the
next digit of sum
if the lst sum was bigger then 9
if ((isEmptyList(n1) == TRUE) || (isEmptyList(n2) == TRUE))
printf("bad input =(");
else
{
currN1 = n1.head;
currN2 = n2.head; * sum = createEmptyList();
carrier = 0;
prevCarrier = 0;
while ((currN1 != NULL) && (currN2 != NULL))
{
currN1N2Sum = *(currN1->dataPtr) + *(currN2->dataPtr) + prevCarrier;
if (currN1N2Sum > 9)
{
carrier = 1;
currN1N2Sum = currN1N2Sum - 10;
}
currSum = creatNewListNode( & currN1N2Sum, NULL);
insertNodeToEnd(sum, currSum);
prevCarrier = carrier;
carrier = 0;
currN1 = currN1 - >next;
currN2 = currN2 - >next;
} //while ((currL1!=NULL)&&(currL2!=NULL))
while (currN1 != NULL)
{
currN1N2Sum = *(currN1 - >dataPtr) + prevCarrier;
currN1 = currN1 - >next;
if (prevCarrier != 0) prevCarrier = 0;
}
while (currN2 != NULL)
{
currN1N2Sum = *(currN2 - >dataPtr) + prevCarrier;
currN2 = currN2 - >next;
if (prevCarrier != 0) prevCarrier = 0;
}
} // ! ((isEmptyList(n1)==TRUE)||(isEmptyList(n2)==TRUE))
}
这是代码的其余部分:
typedef struct listNode{
int* dataPtr;
struct listNode* next;
} ListNode;
typedef struct list
{
ListNode* head;
ListNode* tail;
} List;
List createEmptyList()//creates and returns an empty linked list
{
List res;
res.head = res.tail = NULL;
return res;
}
Bool isEmptyList ( List lst )//checks if a given list is empty or not
{
if (lst.head == NULL && lst.tail == NULL)
return TRUE;
else
return FALSE;
}
void insertDataToEnd ( List * lst, int *dataPtr ) //inserts new data to the end of an existing linked list
{
ListNode * newTail;
newTail = creatNewListNode ( dataPtr, NULL );
insertNodeToEnd(lst,newTail);
}
void insertNodeToEnd ( List * lst, ListNode * newTail )//insert an existing node to an existing linked list
{
if (isEmptyList(*lst) == TRUE )
insertNodeToStart ( lst,newTail );
else
{
(*lst).tail -> next = newTail;
newTail->next = NULL;
(*lst).tail = newTail;
}
}
ListNode * creatNewListNode ( int * dataPtr, ListNode * next )//inserts new node in an existing linked list
{
ListNode * res;
res = (ListNode *) malloc (sizeof(ListNode));
res -> dataPtr = dataPtr;
res -> next = next;
return res;
}
void insertNodeToStart ( List * lst, ListNode * newHead )//inserts node to the begining of a given linked list
{
if ( isEmptyList( *lst ) == TRUE )
{
(*lst).head = newHead;
(*lst).tail = newHead;
newHead -> next = NULL;
}
else
{
newHead -> next = (*lst).head;
(*lst).head = newHead;
}
}
答案 0 :(得分:5)
错误在addNumbers函数中。 当您添加节点以存储总和时,您将指针传递给变量currN1N2Sum,该变量是一个局部变量(存储在堆栈中)。当addNumbers函数终止时,局部变量的存储被释放。在该位置找到的值将保持不变,因此只要存储不被重用,它就显然是有效的。
这就是为什么你对addNumbers函数的印象是正确的。当调用printNumber函数时,存储被覆盖,你在那里找到一个不同的值。
这解释了你的错误。
addNumbers还有另一个问题。当您尝试添加两位数字时,currN1N2Sum的内容将被新值覆盖。
你应该做的是分配一个缓冲区(malloc)并将包含在currN1N2Sum中的值存储到其中。将指向缓冲区的指针传递给新节点。
顺便说一句:你可以在lst-> head中改变(* lst).head。它将使您的代码更具可读性。答案 1 :(得分:0)
我们需要看一些代码:如何定义用于保存节点的数据结构,如何添加节点等。
以下行是可疑的:
number=number+currData*((int)pow(10,i));
说,你有123个存储为1,2和3个节点:
number = 0;
number = 0 + 1 * 1 = 1;
number = 1 + 2 * 10 = 21;
number = 21 + 3 * 100 = 321;
但如果您存储的是3个,2个和1个节点,则可以获得:
number = 0;
number = 0 + 3 * 1 = 3;
number = 3 + 2 * 10 = 23;
number = 23 + 1 * 100 = 123;
这是你的问题吗?
答案 2 :(得分:0)
如果没有看到createNewListNode()
的实施,我不是,如果这是一个问题,但这里需要考虑的事项:
从dataPtr
电话回来后,sum
列表中的addNumbers()
指向何处?
答案 3 :(得分:0)
我认为你可能会在指针方面搞乱事情......你在addNumbers中分配列表'sum'的方式似乎非常非常奇怪。 (如果它破坏了我就不会感到惊讶......)
尝试进行这些更改:
主要:
List *sum;
<...>
addNumbers(lst1,lst2,sum); //Note the absence of the reference operator &
printNumbers(*sum);
(或者,将printNumbers更改为接受(List *)而不是(List))。
希望这有助于XD
的 尝试在调用addNumbers()之前分配'sum'。
lst1 = arrToList(pa, 1);
lst2 = arrToList(pb, 1);
sum = createEmptyList();
我仍然认为你的数据结构有点奇怪:S
答案 4 :(得分:0)
你遇到了createEmptyList的问题。你在那里声明一个名为res的列表并返回结构,但是这个函数返回该结构的时间不再有效。 尝试使用malloc(用于struct),然后将指针返回给调用者。您可以在* sum。
的开头使用此功能这是与chmike发现的类似的错误,所以你最好解决这两个问题。