鱼C论坛

 找回密码
 立即注册
查看: 1163|回复: 3

[已解决]错误

[复制链接]
发表于 2023-10-20 19:49:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 风眠 于 2023-10-20 19:57 编辑

代码:


                               
登录/注册后可看大图


func.c
#include <stdio.h>

int count;

void func(void) { printf("count = %d\n", count); }


                               
登录/注册后可看大图


test3.c
void func();
int count = 520;
int main() {
  func();
}


                               
登录/注册后可看大图


编译结果:
$ gcc test3.c func.c&&./a.out
/usr/bin/ld: /tmp/ccMBhf9L.o:(.bss+0x0): multiple definition of `count'; /tmp/ccrIdFiW.o:(.data+0x0): first defined here
collect2: 错误:ld 返回 1


                               
登录/注册后可看大图


为什么小甲鱼没报错,我却报错了呢?

2023-10-20-195303_1600x900_scrot.png
2023-10-20-195321_1600x900_scrot.png
2023-10-20-195606_1600x900_scrot.png
最佳答案
2023-10-20 19:51:29
这是因为你在 test3.cfunc.c 中都定义了同一个全局变量 count,而在 C 语言中,全局变量只能有一个定义。

test3.c 中,你使用 int count = 520; 定义了全局变量 count 的初始值为 520。

func.c 中,你使用 int count; 定义了另一个全局变量 count,并且没有给它初始值。

当你尝试将两个源文件编译链接到一起时,连接器会发现存在两个同名的全局变量 count,从而报出多次定义的错误。

小甲鱼在视频中可能通过了编译是因为他在演示的环境中,可能只编译了 test3.c 这个源文件,或者使用了其他方式来避免了多次定义的错误。

要解决这个问题,你可以做以下修改:

1. 在 test3.c 中,去掉 int count = 520; 的定义。

2. 在 test3.c 中,在 #include "func.c" 前添加 extern int count; 声明。

修改后的代码如下所示:
// func.c#include <stdio.h>extern int count;void func(void) {    printf("count = %d\n", count);}
// test3.c#include <stdio.h>extern int count;void func();int main() {    func();    return 0;}
通过以上修改,你可以避免多次定义的错误,并且成功编译和运行代码。

球一个最佳答案谢谢啦!这对我非常重要!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-10-20 19:49:56 | 显示全部楼层
小甲鱼没有报错是因为他将函数声明放在了test3.c文件中,而将变量定义放在了func.c文件中。这样做的话,变量count的定义只会在func.c文件中生效,而test3.c文件中只是对count进行了声明,没有进行定义。因此,在链接时不会出现变量重定义的错误。

而你的代码中,变量count的定义同时出现在了func.c和test3.c两个文件中,导致了变量重定义的错误。链接器在链接时会检查是否有多个对同一变量的定义,如果有则会报错。

要解决这个问题,你可以将变量count的定义放在一个文件中,然后在另一个文件中进行声明即可。例如,将变量定义放在func.c文件中,将变量声明放在test3.c文件中。这样就不会出现变量重定义的错误了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-20 19:50:22 | 显示全部楼层
这个问题是由于C语言的链接器(linker)在处理全局变量时遇到了冲突。在你的代码中,count这个全局变量在两个不同的源文件(func.ctest3.c)中都被定义了。这就导致了链接器在试图将这两个源文件链接在一起时,不知道应该使用哪个文件中的count定义,因此报错。

这个问题的解决方法是避免在多个源文件中定义同一个全局变量。你可以在一个源文件中定义count,然后在需要使用它的其他源文件中声明它。例如,你可以在func.c中定义count,然后在test3.c中声明它:

func.c:
#include <stdio.h>  
int count;  
void func(void) { printf("count = %d\
", count); }

test3.c:
extern int count;  // 声明 count,而不是定义它
void func(); 
int main() { 
    count = 520;  // 使用已经在 func.c 中定义的 count
    func(); 
}

至于你提到的“小甲鱼没报错”,我没有足够的上下文信息来解释这个现象。可能的原因是他的编译器设置或者代码与你的不同。
请注意,本回答来自GPT-4
如果问题已经解决,请设置最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-20 19:51:29 | 显示全部楼层    本楼为最佳答案   
这是因为你在 test3.cfunc.c 中都定义了同一个全局变量 count,而在 C 语言中,全局变量只能有一个定义。

test3.c 中,你使用 int count = 520; 定义了全局变量 count 的初始值为 520。

func.c 中,你使用 int count; 定义了另一个全局变量 count,并且没有给它初始值。

当你尝试将两个源文件编译链接到一起时,连接器会发现存在两个同名的全局变量 count,从而报出多次定义的错误。

小甲鱼在视频中可能通过了编译是因为他在演示的环境中,可能只编译了 test3.c 这个源文件,或者使用了其他方式来避免了多次定义的错误。

要解决这个问题,你可以做以下修改:

1. 在 test3.c 中,去掉 int count = 520; 的定义。

2. 在 test3.c 中,在 #include "func.c" 前添加 extern int count; 声明。

修改后的代码如下所示:
// func.c#include <stdio.h>extern int count;void func(void) {    printf("count = %d\n", count);}
// test3.c#include <stdio.h>extern int count;void func();int main() {    func();    return 0;}
通过以上修改,你可以避免多次定义的错误,并且成功编译和运行代码。

球一个最佳答案谢谢啦!这对我非常重要!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-7 07:29

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表