C语言 使用链表的现有实现实现队列:错误文件编号错误



我得到了一些现有的C代码(一个头文件和一些源代码)来实现链表,并被赋予了一个任务来使用它来实现队列。

以下是我得到的头文件的一部分,其中包含相关的函数描述:

/* List is a pointer to a list_t struct */
typedef struct list_t* List;
struct list_t {
    void *data;
    List next;
};
/* Pushes data as the new head of list. May be used to create a new list:
 * new_list = push(NULL, data) */
extern List push(List list, void *data);
/* Pop the head off the list */
extern void *pop(List *list);
/* Return the length of the list */
extern int len(List list);
/* Returns a reversed copy of list */
List reverse(List list);
/* Prepend data to list and update list */
extern List prepend(List *list, void *data);
/* Append l1 to the end of l2 */
void append(List l1, List *l2);
/* Inserts data into the tail of list */
void insert(void *data, List *list);
/* Inserts data into the tail of list or position equal to the next element     */
void insert_by(bool (*eq)(void *data, void *node), void *data, List *list);
/* Inserts data into the tail of list. Returns true if sucessful,
 * false if it finds an element already equal to data */
bool insert_if(bool (*eq)(void *data, void *node), void *data, List *list);
/* Returns the node equal to aim in list, returns NULL if not found */
extern List find(bool (*eq)(void *aim, void *node), void *aim, List list);
/* Removes and returns the element equal to aim in list,
 * returns NULL if not found */
extern void *del(bool (*eq)(void *aim, void *node), void *aim, List *list);
/* Returns a new list that passes the predicate p */
List filter(bool (*p)(void *data), List list);
/* Print list to f by applying print to each node that is not NULL */
extern void print_list(void (*print)(FILE *f, void *data), FILE *f, List node);
/* Free the memory allocated to each list node */
extern void free_list(List node);

我知道为了实现队列,我至少需要两个函数,enqueue()dequeue() .我继续使用上述头文件中的 List 类型为队列创建自己的头文件和用于队列的 typedef:

//Queue.h
#include "list.h"
typedef List Queue;
//Add item to queue...
void enqueue(Queue q, void *data);
//removes and returns an item from the queue...
void dequeue(Queue *q);

然后我继续在queue.c中实现了源代码。我现在只实现了enqueue,因为我想确保它在继续之前有效:

#include "queue.h"
void enqueue(Queue q, void *data){
    if (q == NULL){
        q = push(q, data);
    }
    else {
        insert(data, &q);
    }
}

很简单,我知道。我计划使用以下文件,main.c测试队列:

#include <stdio.h>
#include "queue.h"
int main(int argc, char **argv){
    Queue q = NULL;
    int i;
    for (i = 0; i < 10; i++){ enqueue(q, &i); } //one line for brevity
    return 0;
}

在这一点上,我没想到在运行时会看到任何输出 main.c ,我所期望的只是程序运行没有错误然后停止。一切都编译得很好,但是当我运行main.c时,我得到的只是:

sh: ./main.exe: bad file number

这意味着什么,任何人都可以确定可能导致此问题的原因吗?

编辑:源代码是这样编译的:

gcc -c list.c
gcc -c queue.c
gcc -c main.c -o main.exe

您的enqueue函数破坏了push方法的协定。

push方法返回新头。

您将需要:

Queue enqueue(Queue q, void *data){
    return push(q, data);
}

在您的通话中:

for (i = 0; i < 10; i++){ 
    q = enqueue(q, &i); 
}

但请注意,这将在每次迭代时推送相同的指针。如果更改i则将更改队列中每个节点的值。这可能不是你想要的!

另请注意,对局部(自动)变量的地址进行排队可能是一件坏事,当变量超出范围时,可能会导致堆栈问题。(在您的情况下,i 是在 main 中声明的,因此在程序结束之前它不会超出范围。

这不仅仅是关于 C 编程问题,而是关于未正确调用的编译器命令。

编译命令不完整。

使用这个:

gcc -c list.c
gcc -c queue.c
gcc -c main.c
gcc list.o main.o queue.o -o main.exe
./main.exe

解释:

gcc -c list.c                           produces list.o
gcc -c queue.c                          produces queue.o
gcc -c main.c                           produces main.o
gcc list.o main.o queue.o -o main.exe   invokes the linker that links the .o files
                                        together producing main.exe
./main.exe                              run the program

C 代码中可能存在其他与编程相关的问题。

最新更新