一.现象及原因
现象:在一个工程中有2个带有main函数的文件:InsertSort.cpp,ShellSort.cpp
InsertSort.cpp
1 #include <stdio.h> 2 3 void InsertSort(int A[],int n) 4 { 5 int i,j; 6 for(i=2;i<=n;i++) 7 { 8 if(A[i]<A[i-1]) 9 { 10 A[0]=A[i]; 11 for(j=i-1;A[0]<A[j];--j) 12 { 13 A[j+1]=A[j]; 14 15 } 16 17 A[j+1]=A[0]; 18 } 19 } 20 } 21 22 void InsertSort_1(int A[],int n) 23 { 24 int i,j,temp; 25 for(i=1;i<n;i++) 26 { 27 if(A[i]<A[i-1]) 28 { 29 temp=A[i]; 30 for(j=i-1;A[j]>temp;j--) 31 { 32 A[j+1]=A[j]; 33 34 } 35 36 A[j+1]=temp; 37 } 38 } 39 } 40 41 int main() 42 { 43 int i,a[10]={5,2,6,0,3,9,1,7,4,8}; 44 InsertSort(a,10); 45 printf("InsertSort排序后的结果是:"); 46 for(i=0;i<10;i++) 47 { 48 printf("%d",a[i]); 49 } 50 printf("\n\n"); 51 return 0; 52 }
ShellSort.cpp
1 #include <stdio.h> 2 void shellSort(int A[],int n) 3 { 4 int dk; 5 int i,j; 6 int temp; 7 for(dk=n/2; dk>=1;dk/=2) //用来控制步长,最后递减到1 8 { 9 for(i=dk+1;i<=n;i++) 10 { 11 if(A[i]<A[i-dk]) 12 { 13 A[0]=A[i]; 14 for(j=i-dk;j>0&&A[0]<A[j];j-=dk) 15 A[j+dk]=A[j]; 16 A[j+dk]=A[0]; 17 18 } 19 } 20 } 21 } 22 int shellSort_main() 23 { 24 int i,a[10]={0,5,2,6,3,9,1,7,4,8}; 25 shellSort(a,10); 26 printf("ShellSort排序后的结果是:"); 27 for(i=0;i<10;i++) 28 { 29 printf("%d",a[i]); 30 } 31 printf("\n\n"); 32 return 0; 33 }
当运行过第一个文件后,再编写并运行第二个文件时,会抛出异常。
抛出异常:shellsort.obj : error LNK2005: _main already defined in insertsort.obj
Debug/chapter2.exe : fatal error LNK1169: one or more multiply defined symbols found
原因:main函数重定义。注意,程序是按照一个工程为单位进行编译,每个工程只能有且只有一个main函数,也就是只有一个函数入口。
那么我又想偷懒,不想再重新建立一个工程。否则每建立一个算法程序打开新的一个工程,这样做是不会死太麻烦了。那么我们可以怎样来解决呢?
二.解决办法
【方法一】:最笨的方法,既然说是只能允许一个main()主函数入口,那么我在之前那一个里面用/*......*/注释掉不就可以了吗?不错,这样倒是一个解决方案。
【方法二】:从操作看来,方法一这样太麻烦了,假如有几十个文件或者更多,每次都是这样干,也太费事,浪费光阴和青春了吧?那么我们该怎么做呢?
(1)在编好第2个新程序之后,在工程左边fileview里工程下的source files中,选中前一个带main函数的文件,点键盘的【Delete】键,删除该文件(其实只是从工程中移除出去, 并 没有删除,您可以打开该工程目录查看,它依然存在,只是不在VC6.0中显示了,表示已经不在该工程编译范围之内)。
(2) 然后,执行VC6.0菜单命令“组建”→“清除”,
(3)再按F7或者编译快捷键,重新编译新建的C++程序。
这样,每个cpp文件(包括已移除的前main()文件)都留在当前工程所在目录中,而每次只有一个带main函数的cpp文件存在于工程当中执行。
【如果想恢复到原来的那个文件】:在工程左边fileview里工程下的source files中单击【右键】→选择【添加文件到当前目录】→选择需要导入到文件cpp,打开确认就可以把删除的文件导入进来。
【方法三】:将main函数单独写在一个文件里,并通过头文件将其他文件中的函数引入进来
如:(1)将InsertSort.cpp中的main函数重命名为普通字母
(2)再编写InsertSort.h来声明InsertSort.cpp中的函数
(3)新建一个带main函数的文件main.cpp,在main.cpp中引入头文件,调用InsertSort.cpp中的方法
修改后的源码如下:
InsertSort.cpp
1 #include <stdio.h> 2 3 void InsertSort(int A[],int n) 4 { 5 int i,j; 6 for(i=2;i<=n;i++) 7 { 8 if(A[i]<A[i-1]) 9 { 10 A[0]=A[i]; 11 for(j=i-1;A[0]<A[j];--j) 12 { 13 A[j+1]=A[j]; 14 15 } 16 17 A[j+1]=A[0]; 18 } 19 } 20 } 21 22 void InsertSort_1(int A[],int n) 23 { 24 int i,j,temp; 25 for(i=1;i<n;i++) 26 { 27 if(A[i]<A[i-1]) 28 { 29 temp=A[i]; 30 for(j=i-1;A[j]>temp;j--) 31 { 32 A[j+1]=A[j]; 33 34 } 35 36 A[j+1]=temp; 37 } 38 } 39 } 40 41 int InsertSort_main() 42 { 43 int i,a[10]={5,2,6,0,3,9,1,7,4,8}; 44 InsertSort(a,10); 45 printf("InsertSort排序后的结果是:"); 46 for(i=0;i<10;i++) 47 { 48 printf("%d",a[i]); 49 } 50 printf("\n\n"); 51 return 0; 52 }
InsertSort.h
void InsertSort(int A[],int n); int InsertSort_main();
main.cpp
1 #include <stdio.h> 2 #include "InsertSort.h" 3 void main() 4 { 5 InsertSort_main(); 6 //ShellSort_main(); 7 }
(1)