Frage

Als Teil einer Aufgabe, ich brauche zwei Funktionen zu schreiben:

  1. eine Funktion, die zwei natürliche Zahlen als eine verknüpfte Liste dargestellt fasst
  2. a-Funktionen, die eine Zahl in der gleichen Art und Weise dargestellt druckt.

aus irgendeinem Grunde, beide Funktion Arbeit völlig in Ordnung getrennt, aber wenn ich versuche, die Druckfunktion auf dem Ergebnis der Summenfunktion zu verwenden, ändert es den Wert der Summe gleich zu Beginn der Druckfunktion und druckt die falscher Wert. wenn ich printf den gleichen Wert in der Haupt zu drucken, gibt es kein Problem. mein Code wird unten detailliert beschrieben. irgendwelche Ideen?

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))
}

Hier ist der Rest des Codes:

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; 
    }
}
War es hilfreich?

Lösung

Der Fehler liegt in der Funktion addNumbers. Wenn Sie einen Knoten hinzufügen, um die Summe zu speichern, übergeben Sie einen Zeiger auf die Variable currN1N2Sum die eine lokale Variable ist (auf dem Stapel gespeichert). Wenn die addNumbers Funktion beendet wird, wird die Speicherung der lokalen Variablen frei. Der Wert an dieser Stelle gefunden bleibt unverändert und somit offenbar gültig, solange der Speicher nicht wiederverwendet wird.

Aus diesem Grunde hat man den Eindruck hatte die addNumbers Funktion richtig war. Wenn die printNumber Aufruf Funktion die Speicherung überschrieben ist und Sie finden einen anderen Wert drin.

Dieses Ihre Fehler erklären.

Es gibt ein weiteres Problem mit addNumbers. Wenn Sie versuchen, zweistellige Zahlen zu addieren, wird der Inhalt des currN1N2Sum durch einen neuen Wert überschrieben.

Was Sie tun sollten, einen Puffer (malloc) zuzuweisen und den Wert in currN1N2Sum in ihm enthaltenen speichern. Passiert die Zeiger auf den Puffer in den neuen Knoten.

BTW: Sie kann sich ändern (* lst) .head in lst-> Kopf. Es wird Ihr Code besser lesbar machen.

Andere Tipps

Wir brauchen etwas mehr Code sehen:., Wie Sie die Datenstruktur zum Halten Knoten definieren, wie Sie Knoten usw. hinzufügen

Die folgende Zeile ist verdächtig:

    number=number+currData*((int)pow(10,i));

Sagen Sie, Sie haben 123 gespeichert, wie 1, 2, und 3 Knoten:

    number =  0;
    number =  0 + 1 * 1   = 1;
    number =  1 + 2 * 10  = 21;
    number = 21 + 3 * 100 = 321;

Aber wenn Sie speichern ist als 3, 2 und 1 Knoten, die Sie würden erhalten:

    number =  0;
    number =  0 + 3 * 1   = 3;
    number =  3 + 2 * 10  = 23;
    number = 23 + 1 * 100 = 123;

Ist das Ihr Problem?

Ich bin nicht, ob dies ein Problem ist oder nicht, ohne dass die Durchführung des createNewListNode() zu sehen, aber hier ist etwas zu denken:
Wo sind die dataPtrs in der sum Liste zeigt, nachdem Sie aus dem addNumbers() zurückrufen?

Sie haben ein Problem mit createEmptyList bekommen. Sie erklären es eine Liste namens res und die Struktur zurück, aber die Minute, liefert diese Funktion die Struktur nicht mehr gültig ist. versuchen malloc (für die Struktur) und dann den Zeiger an den Aufrufer zurück. Sie verwenden diese Funktion am Anfang mit * Summe.

Dies ist ein ähnlicher Fehler zu dem, was gefunden chmike, so dass Sie beide besser beheben.

Ich glaube, Sie könnten Dinge Zeiger-weise werden durcheinander ... Die Art und Weise Sie die Liste ‚Summe‘ in addNumbers sind Zuteilung scheint sehr, sehr seltsam. (Und ich wäre nicht überrascht, wenn es Dinge zu brechen ...)

Versuchen Sie, diese Änderungen vorzunehmen:

Im Haupt:

List *sum;
<...>
addNumbers(lst1,lst2,sum); //Note the absence of the reference operator &
printNumbers(*sum);

(Alternativ printNumbers ändern, um eine (List *) anstelle von (List) zu akzeptieren).

Hope this half XD


EDIT:

Versuchen Sie die Zuteilung 'Summe', bevor sie Anrufe addNumbers ().

lst1 = arrToList(pa, 1);
lst2 = arrToList(pb, 1);
sum = createEmptyList();

Ich denke immer noch die Art und Weise, die Ihre Datenstrukturen sind ein wenig seltsam: S

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top