#c #pointers #linked-list #variadic
#c #указатели #связанный список #переменный
Вопрос:
Я работаю над разработкой API связанного списка для компилятора Lisp, но я решил написать эту часть на C, потому что писать ее на ассемблере было бы не очень весело. Я могу успешно создать связанный список из ряда элементов с list
помощью функции, приведенной ниже. Я убедился, что это работает, как показано в примерах main
ниже. Но почему моя функция print_list
печатает только первый элемент, а затем ноль? Я так запутался. Пожалуйста, предложите любую помощь, если вы понимаете, что происходит не так.
#include <stdio.h>
#include <stdarg.h>
typedef struct Node Node;
struct Node {
int head; // make to a union later
Node* tail;
};
//////////
Node cons(int curr, Node* next) {Node cell = {curr, next}; return cell;}
int car(Node node) {return node.head;}
Node* cdr(Node node) {return node.tail;}
//////////
void print_elems(Node node) {
printf("%d", node.head);
if (node.tail == NULL) return;
printf(" ");
print_elems(*node.tail);
}
void print_list(Node node) {
printf("(");
print_elems(node);
printf(")n");
}
//////////
Node make_pairs(va_list args, int argc) {
Node linked_list;
linked_list.head = va_arg(args, int);
if (argc == 0) {
linked_list.tail = NULL;
return linked_list;
}
Node tail = make_pairs(args, argc - 1);
linked_list.tail = amp;tail;
return linked_list;
}
Node list(int length, ...) {
va_list elems;
va_start(elems, length);
Node linked_list = make_pairs(elems, length);
va_end(elems);
return linked_list;
}
//////////
int main() {
Node big_list = list(5, 1, 2, 3, 4, 5);
/*
This is NULL, as expected:
big_list.tail -> tail -> tail -> tail -> tail -> head
And this is 1:
big_list.head
*/
// but why does this only print "(1 0)"?
print_list(big_list);
}
Комментарии:
1.
linked_list.tail = amp;tail;
вы создаете указатель на локальную переменную. После завершения функции этот указатель становится зависшим, поэтому ваш код имеет неопределенное поведение при попытке прочитать этот указатель2. @UnholySheep Понял, это исправлено, спасибо
Ответ №1:
Вы могли бы распечатать связанный список таким образом: это пример; Моя цель — просто заставить вас заметить, что с помощью указателя у вас нет проблем с локальной переменной
typedef struct Node Node;
Node* first_element = create_list; // just for understanding "first element" is the linked list
Node* ptr = first_element; // copy in another pointer your list then you will avoid loosing your first element and breaking your list (personnal advice : not needed)
while (ptr->tail){
ptrinf("%dn", ptr->head); // for exemple
ptr = ptr->tail;
}
//after the while ptr = the last element because ptr->tail == NULL
отформатированный для функции, он выглядит так :
#include <stdio.h>
typedef struct Node Node;
void display_list (Node* first_element)
{
Node* ptr = first_element; // copy in another pointer your list then you will avoid loosing your first element and breaking your list (personnal advice : not needed)
while (ptr->tail){
ptrinf("%dn", ptr->head); // for exemple
ptr = ptr->tail;
}
//after the while ptr = the last element because ptr->tail == NULL
}
если бы я не ответил на вопрос, хорошо скажите мне, я новичок в стеке, я бы улучшил ^^.
Надеюсь, я вам помог.