2009-05-06 3 views
0

В рамках задания, мне нужно написать две функции:печать удаляет значение из моего связанного списка

  1. функция, которая суммирует два натуральных числа, представленные в виде связанного списка
  2. а функции, которые печатает число, представленное таким же образом.

по какой-либо причине, обе функции работают отлично друг от друга, но когда я пытаюсь использовать функцию печати в результате функции sum, она меняет значение суммы в начале функции печати, и печатает неправильное значение. когда я использую printf для печати того же значения в главном, проблем нет. мой код подробно описан ниже. есть идеи?

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

Какой результат вы получаете при добавлении 2 + 1, точно? Что такое «изменение», как вы говорите? – ParoXoN

+0

Ваш код трудно компилировать. Нет типа, называемого Bool, или определения для arrToList. – dirkgently

ответ

5

Это ошибка в функции addNumbers. Когда вы добавляете узел для хранения суммы, вы передаете указатель на переменную currN1N2Sum, которая является локальной переменной (хранимой в стеке). Когда функция addNumbers завершается, хранилище локальной переменной освобождается. Значение, найденное в этом месте, останется неизменным и, по-видимому, действительным до тех пор, пока хранилище не будет повторно использовано.

Вот почему у вас создалось впечатление, что функция addNumbers верна. При вызове функции printNumber хранилище перезаписывается, и вы находите другое значение.

Это объясняет вашу ошибку.

Существует еще одна проблема с addNumbers. Когда вы попытаетесь добавить двузначные числа, содержимое currN1N2Sum будет перезаписано новым значением.

Что вам нужно сделать, это выделить буфер (malloc) и сохранить в нем значение, содержащееся в currN1N2Sum. Передайте указатель на буфер в новый узел.

BTW: вы можете изменить (* lst) .head в lst-> head. Это сделает ваш код более читаемым.

+0

Да, это была проблема! Я исправил ее, и она сработала! Большое вам спасибо =) – Lior

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; 

Является ли это проблема?

+0

Дело в том, что по отладке я знаю, что значение теряется прямо в начале функции, даже до строки: if (isEmptyList (num) == TRUE) – Lior

+0

Покажите нам определение List и, что самое важное, весь код. – dirkgently

0

Я не, если это проблема или нет, не видя реализации createNewListNode(), но вот что-то думать о:
Где dataPtr s в sum список указывающей после возвращения из addNumbers() вызова?

+0

dataPtr указывает на 0x0012fdf4 после возврата из addnumbers(). Он указывает тот же адрес, когда он входит в функцию печати, НО значение изменяется на -858993460, а currData, i и number имеют одинаковое значение. – Lior

+0

Это именно то, что я подозревал - вы указали на локальное хранилище. Я пытался указать вам на ответ @chmike, не делая домашнее задание. Изучение отладки - очень ценный навык для развития. – AShelly

0

Я думаю, что вы можете быть беспорядочным по отношению к указателю ... То, как вы выделяете список «sum» в addNumbers, кажется очень, очень странным. (И я не удивлюсь, если это ломать вещи ...)

Попробуйте сделать эти изменения:

В основной:

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

(В качестве альтернативы, изменение printNumbers принять (List *) вместо (List)).

Надеется, что это помогло XD


EDIT:

Попробуйте выделить 'сумму', прежде чем принимать звонки addNumbers().

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

Я все еще думаю так, что ваши структуры данных немного странно: S

+0

Просто попробовал. результат остается тем же = ( (и я не могу изменить прототип функции, потому что они являются частью упражнения) – Lior

0

У вас возникла проблема с createEmptyList. вы объявляете там список с именем res и возвращаете структуру, но в тот же момент, когда эта функция возвращает эту структуру, уже недействительна. попробуйте использовать malloc (для структуры), а затем верните указатель на вызывающий. Вы используете эту функцию в начале с * суммой.

Это похоже на ошибку, найденную в chmike, поэтому вы лучше исправите оба.

 Смежные вопросы

  • Нет связанных вопросов^_^