2 yzy401 yzy401 于 2014.05.17 11:41 提问

vc6.0 中extern使用时遇到的2个疑问,还望诸位帮忙看下,多谢

我在文件1CTestHello.cpp 声明了
extern void delete_string(char a[],char b[],char standard);
再调用文件2 file2.c中的delete_string(a,b,Standard);函数;
发现2个问题:
问题1;用extern实验发现必须用include,但查找资料,没有说这两个有必然关联。请问到底有没有必然关联?下面是实验:
如果文件1中不#include "file2.c",编译没问题,链接出错,提示:
CTestHello.obj : error LNK2001: unresolved external symbol "void __cdecl delete_string(char * const,char * const,char)" (?delete_string@@YAXQAD0D@Z)
Debug/TestHello.exe : fatal error LNK1120: 1 unresolved externals
执行 link.exe 时出错.

TestHello.exe - 1 error(s), 0 warning(s)

如果文件1中#include "file2.c",编译没问题,链接没问题,一切正常;
示例如下:

文件1:CTestHello.cpp
#define PI 3.14
#include
#include
#include
///#include "file2.c"
void main()
{

//015-1-2字符串查找删除,多文件:

char a[]="abcdccdefc";
int len=strlen(a);  
char b[10];    
char Standard='c';

extern void delete_string(char a[],char b[],char standard);
delete_string(a,b,Standard);

//void stringdel(char a[],char b[],char Standard);
//stringdel(a,b,Standard);
printf("字符串b:%s\n",b);

for(int t=0;b[t]!='\0';t++)
{
    printf("第i个元素:%c\n",b[t]);
}

}

文件二:file2.c
#include

extern void delete_string(char a[],char b[],char Standard)
{
int k=0;//a和b由于a有Standard,导致b下标相差的
int j=0;
int n=0;
int i=0;
for(;a[i]!='\0';i++)
{
if(a[i]!=Standard)
{
j=i-k;
b[j]=a[i];
n++;
}
else
{
k++;
}
}
b[n]='\0';
}

问题二:如果外部文件中的extern函数名,和本文件中的函数名重名,编译提示函数重定义,感觉不应该有这个提示啊?
编译提示:
--------------------Configuration: TestHello - Win32 Debug--------------------
Compiling...
CTestHello.cpp
d:\code\c\vc\testhello\ctesthello.cpp(321) : error C2375: 'stringdel' : redefinition; different linkage
d:\code\c\vc\testhello\file2.c(2) : see declaration of 'stringdel'
执行 cl.exe 时出错.

CTestHello.obj - 1 error(s), 0 warning(s)
实例如下:
文件1:CTestHello.cpp
#define PI 3.14
#include
#include
#include
///#include "file2.c"
void main()
{

//015-1-2字符串查找删除,多文件:

char a[]="abcdccdefc";
int len=strlen(a);  
char b[10];    
char Standard='c';

extern void stringdel(char a[],char b[],char standard);
stringdel(a,b,Standard);

//void stringdel(char a[],char b[],char Standard);
//stringdel(a,b,Standard);
printf("字符串b:%s\n",b);

for(int t=0;b[t]!='\0';t++)
{
    printf("第i个元素:%c\n",b[t]);
}

}

 static void  stringdel(char a[],char b[],char Standard)
{
    int k=0;//a和b由于a有Standard,导致b下标相差的
    int j=0;
    int n=0;
    for(int i=0;a[i]!='\0';i++)
    {
        if(a[i]!=Standard)
        {
            j=i-k;
            b[j]=a[i];
            n++;
        }
        else
        {
            k++;
        }
    }
    b[n]='\0';
}

文件二:file2.c
#include

extern void stringdel(char a[],char b[],char Standard)
{
int k=0;//a和b由于a有Standard,导致b下标相差的
int j=0;
int n=0;
int i=0;
for(;a[i]!='\0';i++)
{
if(a[i]!=Standard)
{
j=i-k;
b[j]=a[i];
n++;
}
else
{
k++;
}
}
b[n]='\0';
}

1个回答

lym753024200
lym753024200   2014.05.17 12:57

没见过用#include来包含一个源文件的,你的思路都是错的,或者多文件程序代码安排不合理。注意在一个源文件中使用一个函数时,在这个函数调用前一定要在这个文件内发现它的原型。如果没有就要包含原型所在的头文件,另外也应该在这个文件中发现该函数的定义。不过C++中函数连接性是外部的,也就是你在一个源文件中定义的函数,不使用extern就可以在其他源文件中调用,但是C中是内部的,也就是你在一个文件中定义了一个函数,就只能在这个文件中使用它,除非用extern将连接性扩展为外部。所以不要.c和.cpp的源文件混着用,最好将函数声明和定义分开放到对应的头文件和原文件中,调用前包含这个头文件,如果有必要就要用extern,这样就行了。

lym753024200
lym753024200 记得函数定义源文件也要包含函数声明头文件
3 年多之前 回复
lym753024200
lym753024200 你这上面代码就粘贴了下,格式太乱,不好看。你先把函数定义和原型放到.cpp和.h文件夹,然后需要调用函数的文件夹就用#include来包含头文件,这时不需要extern,试试,养成良好习惯
3 年多之前 回复
yzy401
yzy401 我都没有file2.c啊,怎么还提示无法打开file2.c呢?
3 年多之前 回复
yzy401
yzy401 不用include "file2....",编译ok,链接--------------------Configuration: TestHello - Win32 Debug-------------------- Build : warning : failed to (or don't know how to) build 'D:\code\C\VC\TestHello\file2.c' Compiling... file2.c fatal error C1083: Cannot open source file: 'D:\code\C\VC\TestHello\file2.c': No such file or directory 执行 cl.exe 时出错. TestHello.exe - 1 error(s), 1 warning(s)
3 年多之前 回复
yzy401
yzy401 我吧file2.c改为.cpp
3 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片