简体   繁体   English

为什么我在C中得到一个未定义的引用错误,用于实现单链表

[英]why am I getting an undefined reference error in C for my implementation of a singly linked list

I am getting an error that reads like this 我收到的错误是这样的

$ gcc -o app llistdriver.c llistlib.c -Wall
 llistdriver.c:7: warning: return type defaults to `int'
 llistdriver.c: In function `printinsts':
 llistdriver.c:15: warning: control reaches end of non-void function
 llistlib.c: In function `insert':
 llistlib.c:25: warning: statement with no effect
 llistlib.c:41: warning: control reaches end of non-void function
 /tmp/ccqYmK3M.o:llistdriver.c:(.text+0x157): undefined reference to `_search'
 collect2: ld returned 1 exit status

and I cannot figure out why I am getting this error message have written a library file that contains the methods for the linked list. 我无法弄清楚为什么我收到此错误消息已写入包含链接列表的方法的库文件。

  int search( struct node *front, int val)// 
 {
     while(front != NULL)
    {
       if( front->modmark == val ) //this is to find the value 
       return 1;  // found it

    front=front->next;
    }
    return 0;  // Not found
  }

I assume that it is complaining about the only reference in the main file 我假设它抱怨主文件中唯一的引用

        case 5: 
                printf("please enter a search value?\n");
                scanf("%i",&mark);
                choice = search(first,mark);//here
                if (choice == -1)
                {

                    printf("the modmark was not found\n");
                }
                else 
                {   
                    printf("the first occurence of the mark is at the %i th index of the list",choice); 
                };
                    break;

and first and mark are variables that are defined like this 首先,标记是这样定义的变量

                 struct node *first;
              int mark = 0;

any help on this would be much appreciated I have spent hours trying to debug this error. 我将非常感谢您花了好几个小时尝试调试此错误。 Writing C code is of the the banes of my life at the moment. 编写C代码是我生命中的祸根。

Ps I have checked all the #include "llistlib.h" there are included in the llistlib.c file and the llistdriver.c file. Ps我检查了所有#include“llistlib.h”,它包含在llistlib.c文件和llistdriver.c文件中。

Ok maybe this will make it much clearer 好吧也许这会让它更清晰

// llistlib.c - the library which implements the functions defined in the listlib.h file #include #include #include "llistlib.h" // llistlib.c - 实现listlib.h文件中定义的函数的库#include #include #include“llistlib.h”

void initialise(struct node **ps)
{

printf("initialise function\n");

*ps = NULL;   //initialise list to empty

}


int insert(struct node **fn)
{
printf("insert function\n");
struct node *newnode;
newnode =  (struct node*) malloc(sizeof (struct node)); //make new node and give it memory
if (newnode == NULL) //if fsiled return to the program saying it failed
    return -1;
if (*fn == NULL) // for the first of the list
{
    newnode -> next == NULL; // sets the next value to nothing
    printf("what mark do you want to enter\n");
    scanf("%i",&newnode -> modmark); // this gets the modmark
    *fn = newnode; //the head of the list is set to the new node
}
else
{
    newnode -> next = *fn; // sets the newnodes next value to the head node
    printf("what mark do you want to enter\n");
    scanf("%i",&newnode -> modmark); // gets the modmark
    *fn = newnode; // the head becomes the new node


    printf("%p %i",newnode,newnode->modmark); // just for debugging

}
 }



void traverse(struct node *ps)
{   

if (ps != NULL) // if the current node is null 
{
    printf("%p - %i\n",ps,ps -> modmark);
    traverse(ps -> next); 

}
else
{
    printf("your list is empty\n");
}
}


void delete(struct node **dn)
{
printf("delete function\n");
struct node *delnode;
delnode = *dn; //sets the head node so that it can be deleted later
if (delnode != NULL)
{
    *dn = delnode -> next; // sets the head to the next node
    free(delnode); //deletes the previous head node
}

}


void finish(struct node **ps) //this function goes through the list and removes all items
{
printf("finish function\n");
struct node *finishnode;
finishnode = *ps;
while (finishnode != NULL)
{
    *ps = finishnode -> next;
    free(finishnode);
    finishnode = *ps;
}

int search(struct node *front,int val)
{
 while(front != NULL)
 {
    if( front->modmark == val ) // Assuming struct node has val member which you are trying to compare to
       return 1;  // found it

    front=front->next;
 }
  return 0;  // Not found
}

}

and then the llistdriver.c file is 然后是llistdriver.c文件

#include <stdio.h>
#include <stdlib.h>
#include "llistlib.h"


printinsts()
{
printf("Enter:- \n");
printf("\t0 to exit\n");
printf("\t1 to initialise list\n");
printf("\t2 to insert item at front of list\n");
printf("\t3 to delete item from front of list\n");
printf("\t4 to traverse list\n");
printf("\t5 to search through the list\n");
}




int main()
{
int choice;
struct node *first;
int mark = 0;

printinsts();
scanf("%d",&choice);

while (1)
{
    switch (choice)
    {
        case 0 : finish(&first);
                    exit(0);
                    break;

        case 1 : initialise(&first);
                    break;

        case 2 : if (insert(&first)== -1)
                    {
                        printf("insert not successful");
                        choice = 0;
                     };
                    break;

        case 3 : delete(&first);
                    break;

        case 4 : traverse(first);
                     break;
        case 5: 
                printf("please enter a search value?\n");
                scanf("%i",&mark);
                choice = search(first,mark);
                if (choice == -1)
                {

                    printf("the modmark was not found\n");
                }
                else 
                {   
                    printf("the first occurence of the mark is at the %i th index of the list",choice); 
                };
                    break;

        default : printf("Invalid choice of %d \n", choice);

    };  // end of switch

    printinsts();
    scanf("%d", &choice);

}  // end of while

}

and the header file llistlib.h reads as 头文件llistlib.h读作

struct node {
int     modmark;
struct node *next;
 };


void initialise(struct node **ps);


int insert(struct node **fn);


void traverse(struct node *ps);


void delete(struct node **dn);


void finish(struct node **ps);


int search(struct node *front,int val);

I havent been able to spot a obvious problem among any of the code yet 我还没有能够发现任何代码中的明显问题

Just include llistlib.h in your llistlib.c file as follows: 只需在llistlib.c文件中包含llistlib.h ,如下所示:

#include "llistlib.h"

and use folloeing command for compilation: 并使用folloeing命令进行编译:

gcc -o app llistdriver.c llistlib.c

Hope this helps... 希望这可以帮助...

First error: 第一个错误:

 llistdriver.c:7: warning: return type defaults to `int'
 llistdriver.c: In function `printinsts':
 llistdriver.c:15: warning: control reaches end of non-void function

The function looks like: 该功能如下:

printinsts() {}

Please give this function a return type, and if it's not void, return it. 请给这个函数一个返回类型,如果它不是void,则返回它。

Secondly: 其次:

llistlib.c: In function `insert':
llistlib.c:25: warning: statement with no effect

That line is: 那条线是:

newnode -> next == NULL; // sets the next value to nothing

The comment is not true, this line does not set anything, as it uses the equality operator, not the assignment operator. 注释不正确,此行不设置任何内容,因为它使用相等运算符,而不是赋值运算符。

(it's partly a matter of taste, but I don't like comments like these, which simply try to state the same thing as the code itself. In cases like these, they become misleading, as you may read, and believe, the comment, rather than parsing the code when looking for a bug.) (这部分是一个品味的问题,但我不喜欢像这样的评论,它只是试图说出与代码本身相同的东西。在这样的情况下,它们会变得误导,你可能会读到并相信评论而不是在寻找bug时解析代码。)

Then: 然后:

llistlib.c:41: warning: control reaches end of non-void function

Which again refers to: 这又指:

int insert(struct node **fn)
{
printf("insert function\n");
struct node *newnode;
newnode =  (struct node*) malloc(sizeof (struct node)); //make new node and give it memory
if (newnode == NULL) //if fsiled return to the program saying it failed
    return -1;
...
}

There are no returns from this function other than that -1. 除了-1之外,此函数没有返回。 It should return something no matter what happens. 无论发生什么,它都应该返回一些东西。

Lastly: 最后:

/tmp/ccqYmK3M.o:llistdriver.c:(.text+0x157): undefined reference to `_search'

Because you missed a closing brace from the end of finish(); 因为你在结束时错过了一个结束括号();

Do NOT ignore warnings just because your code compiles. 不要因为代码编译而忽略警告。 Fixing just the errors is not enough! 修复错误是不够的!

You are compiling with the default GCC setting, which is "roughly follow the C99 standard, then add non-standard GNU goo". 您正在使用默认GCC设置进行编译,该设置“大致遵循C99标准,然后添加非标准GNU goo”。 The C99 standard, as well as the current C standard, do not allow functions to have a default type. C99标准以及当前的C标准不允许函数具有默认类型。 That is why you get a warning with -Wall, the return type must be explicit. 这就是你用-Wall得到警告的原因,返回类型必须是显式的。

printinsts() {} is not valid C. You should declare/define this as void printinsts (void) and nothing else. printinsts() {}无效C.您应该将此声明/定义为void printinsts (void)而不是其他内容。

In the future, make sure to always compile with -std=c99 or -std=c11, to ensure that you are compiling the code as standard C language and not something else. 将来,请确保始终使用-std = c99或-std = c11进行编译,以确保您将代码编译为标准C语言而不是其他内容。

Your finish function is missing a closing brace {. 你的finish功能缺少一个右括号{。 And search has an extra closing brace. search有一个额外的结束支撑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM