程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Error LNK2005 從敵人到朋友,errorlnk2005

Error LNK2005 從敵人到朋友,errorlnk2005

編輯:關於C語言

Error LNK2005 從敵人到朋友,errorlnk2005


本人在寫學生信息管理系統時遇到一個很頭疼的錯誤——error LNK2005重復定義錯誤,苦思冥想百度谷歌bing之後都沒能解決問題,於一清早剎那間覺得知道問題出在哪兒了,於是乎起床、開機、修改代碼一氣呵成,終於0 error(s)\0 warning(s)。

 

error LNK2005錯誤分為好幾種,我以下分析的是重復定義外部函數,如果是因為重復定義全局變量、頭文件的重復包含、或者使用第三方庫原因導致的error LNK2005請移步http://www.cnblogs.com/MuyouSome/p/3332699.html

一:問題描述

我的系統分為3個文件(stuheader.h、stufun.c、stuims.c)

  • stuheader.h:該文件中包含頭文件、結構體定義以及函數聲明等;
  • stufun.c:該文件是系統中除main函數外的其他自定義函數的實現和相互調用;
  • stuims.c:該文件是主函數main調用其他函數組裝的整個軟件系統。
#include<stdio.h> //I/O函數 #include<stdlib.h> //標准庫函數 #include<string.h> //字符串函數 #include<ctype.h> //字符操作函數 #define M 50 //定義常數表示記錄數 typedef struct { char no[20]; //學號 char name[20]; //姓名 char sex[5]; //性別 int age; //年齡 }STUDENTS; //以下是函數原型 int menu_select(); //主菜單函數 int enter(STUDENTS t[]); //輸入記錄 void list(STUDENTS t[],int n); //顯示記錄 void search(STUDENTS t[],int n); //按姓名查找顯示記錄 int del(STUDENTS t[],int n); //刪除記錄 int add(STUDENTS t[],int n); //插入記錄 void save(STUDENTS t[],int n); //記錄保存為文件 int load(STUDENTS t[]); //從文件中讀記錄 void display(STUDENTS t[],int n); //按序號查找顯示記錄 void sort(STUDENTS t[],int n); //按姓名排序 void copy(); //文件復制 void print(STUDENTS temp); //顯示單條記錄 int find_name(STUDENTS t[],int n,char *s); //按姓名查找函數 int find_no(STUDENTS t[],int n,char *no); //按學號查找 void modify(STUDENTS t[],int n); //修改記錄 stuheader.h代碼 #include "stuheader.h" //菜單函數,返回值為整數,代表所選的菜單項 int menu_select() { } int enter(STUDENTS t[]) { } //顯示記錄,參數為記錄數組和記錄條數 void list(STUDENTS t[],int n) { } //查找記錄 void search(STUDENTS t[],int n) { } //刪除函數,參數為記錄數組和記錄條數 static int del(STUDENTS t[],int n) { return 0; } //插入記錄函數,參數為結構體數組和記錄數 int add(STUDENTS t[],int n) { return 0; } //保存函數,參數為結構體數組和記錄數 void save(STUDENTS t[],int n) { } //讀入函數,參數為結構體數組 int load(STUDENTS t[]) { return 0; } //按序號顯示記錄函數 void display(STUDENTS t[],int n) { } //按姓名排序函數 void sort(STUDENTS t[],int n) { } //復制文件 void copy() { } //顯示指定的一條記錄 void print(STUDENTS temp) { } //按姓名查找函數,參數為記錄數組和記錄條數以及姓名s int find_name(STUDENTS t[],int n,char *s) { return 0; } //按學號查找函數,參數為記錄數組和記錄條數以及學號no int find_no(STUDENTS t[],int n,char *no) { return 0; } //修改函數,按照輸入學號修改 void modify(STUDENTS t[],int n) { } stufun.c 代碼(其中函數體已省略)

 stuims.c 文件中代碼如下:

#include "stufun.c"        //stufun.c中已經包含了stufun.h
void main()
{
    STUDENTS stu[M];    //定義結構體數組
    int length;            //保存記錄長度
    for(;;)                //無限循環
    {
        system("cls");
        
        switch(menu_select())
        {
        case 0:length=enter(stu);break;        //輸入記錄
        case 1:list(stu,length);break;        //顯示全部記錄
        case 2:search(stu,length);break;    //按姓名查找記錄
        case 3:length=del(stu,length);break;//按姓名刪除記錄
        case 4:modify(stu,length);break;    //按學號修改記錄
        case 5:length=add(stu,length);break;//插入記錄
        case 6:save(stu,length);break;        //保存文件
        case 7:length=load(stu);break;        //加載文件到內存            
        case 8:display(stu,length);break;    //按序號顯示記錄
        case 9:sort(stu,length);break;        //按姓名排序
        case 10:copy();break;                //復制文件到目標文件
        case 11:exit(0);                    //程序結束
        }
        printf("按回車鍵回主菜單...\n");
        getchar();
    }
}

 

 我的基本思路是用stufun.c文件包含stuheader.h文件,然後用stuims.c包含stufun.c文件,本覺得萬無一失,boom~boom~boom,error LNK2005來的如此突然、如此猛烈、瞬間呆若木雞。

二:原因分析

首先我們看向stufun.c文件中的函數頭,沒有加static、extern等關鍵字,所以所有的自定義函數都默認為外部函數(int menu_select、int enter等等);

接下來我們再來分析#include:文件包含預處理是指在文件編譯之前將源文件的全部內容包含進來(簡單的說就是將源文件的所有代碼copy過來代替該#include語句);

然後我們分析代碼:

這樣的話就導致項目中stufun.c有自定義函數的定義,而stuims.c中也有著一模一樣的自定義函數的定義,所以就出現了error LNK2005(重復定義錯誤)

所以我們該怎麼改呢?

三:代碼修改

知道問題所在就簡單了,我存在的問題是項目中有多個外部函數定義導致重復定義錯誤,所以我可以有兩種解決方法:

四:問題總結

出現這樣的問題在於做項目經驗太少,定義函數時沒有想到去添加其作用范圍,以後再定義全局變量和外部函數時一定謹慎謹慎再謹慎,一定要明確自己所定義的變量及函數的作用范圍,不然在軟件擴展時會出現意料之外的Bug。話已至此,還是非常感謝Bug2005,所以我決定:我——AboutSange和error2005在2016.04.09結為異性兄弟,一起去找尋成神路上尚未碰面的error!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved