c - 打印从我的链接列表中删除值

标签 c linked-list traversal

作为作业的一部分,我需要编写两个函数:

  1. 一个将两个自然数相加的函数,表示为一个链表
  2. 一个打印以相同方式表示的数字的函数。

出于某种原因,这两个函数分别工作得很好,但是当我尝试对 sum 函数的结果使用 print 函数时,它会在 print 函数的开头更改 sum 的值,并打印错误的值(value)。当我使用 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; 
    }
}

最佳答案

错误在函数 addNumbers 中。 当您添加一个节点来存储总和时,您将一个指针传递给变量 currN1N2Sum,这是一个局部变量(存储在堆栈中)。当 addNumbers 函数终止时,局部变量的存储被释放。在该位置找到的值将保持不变,因此只要不重复使用存储就显然有效。

这就是为什么您认为 addNumbers 函数是正确的。当调用 printNumber 函数时,存储被覆盖,您会发现其中有一个不同的值。

这解释了你的错误。

addNumbers 还有一个问题。当您尝试将两位数字相加时,currN1N2Sum 的内容将被新值覆盖。

您应该做的是分配一个缓冲区 (malloc) 并将包含在 currN1N2Sum 中的值存储到其中。将指向缓冲区的指针传递到新节点中。

顺便说一句:您可以在 lst->head 中更改 (*lst).head。这将使您的代码更具可读性。

关于c - 打印从我的链接列表中删除值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/830613/

相关文章:

取消或杀死 pthread

c++ - 为什么 SDL 和 OpenGL 相关?

c - 将指针分配给链表: does not contain data

python - 链表中节点的可变性

c - 防止 gcc 删除未使用的变量

c - 获取对正确定义的全局变量的 undefined reference

C - 创建链表的函数仅返回第一个节点

traversal - ArangoDB:通过图遍历聚合计数

r - 如何遍历对角条状矩阵并返回每个位置的索引?

java - DFS树遍历函数修改