我正在制作一个有三个文件的程序:2.c,2tele.c,tele.h
2.c
#include <stdio.h>
#include <stdlib.h>
#include "2tele.c"
int main(void){
TELEFONE tf = preenche_telefone(tf.numero, tf.nome);
mostra_telefone(tf);
}2tele.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "tele.h"
void mostra_telefone(TELEFONE tf){
printf("\nNumero = %d\nNome = %s", tf.numero, tf.nome);
}
TELEFONE preenche_telefone(char nome[], int numero){
TELEFONE tf;
printf("Introduza o numero\n");
scanf("%d", numero);
tf.numero = numero;
printf("Introduza o nome\n");
scanf("%s", nome);
strcpy(tf.nome,nome);
return tf;
}tele.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct contacto{
int numero;
char nome[100];
}TELEFONE;
void mostra_telefone(TELEFONE tf);在2tele.c的第6行中,我得到了'mostra_telefone‘的错误多定义,但是我已经阅读了其他文章并在tele.h上定义了它。
我该怎么办?
编辑:当我包含“tel.h”而不是“2tel.c”时,它说"TELEFONE tf = preenche_telefone(tf.numero,tf.nome);“有一个糟糕的初始化器
发布于 2022-04-03 13:42:05
,在
2tele.c的第6行,我得到了'mostra_telefone‘的错误多重定义,
这是个误导的说法。当您试图链接程序时,您可能会收到这样的消息,但这将是构建过程的详细信息的一个函数。你似乎精心挑选了诊断的细节,这并不能传达问题的本质。始终给我们一个精确副本的完整的诊断信息。
,但是,我读过其他文章,也在
tele.h上定义了它。
不,你没有。你已经在tele.h中声明了它,这实际上是你应该做的。引用该函数的每个源文件都应该#include报头,以只获得一个声明,并避免#includeing 2tele.c,这将提供一个额外的定义。对于函数,区别在于定义包括函数体。
包括.c文件而不是.h文件意味着2.c提供了mostra_telefone()的定义。如果您编译2.c以创建对象文件,并编译2tele.c以创建对象文件,或者将两者一起编译以直接构建程序,那么每一个都提供了一个定义。这两个定义在词汇上是相同的,或者它们最终是从同一个源文件派生出来的,这并不重要。在相同或不同的翻译单元中,可以有多个函数声明,但在整个程序中,按照编译的方式,只能有一个定义。
解决方案:无文件#include的2tele.c。所有想要访问定义在其中的函数的人都会在使用之前声明这些函数,而不需要定义它们(除了2tele.c本身)。传统的方法是#include一个包含所需声明的头部--在您的例子中,这是tele.h。
但你说,
当我包含“tel.h”而不是“2tel.c”时,它说"TELEFONE tf = preenche_telefone(tf.numero,tf.nome);“有一个糟糕的初始化器
打开编译器的警告级别。例如,gcc和其他理解其选项的编译器至少打开了-Wall。这应该会让你了解这个问题的根源:
2.c:在函数‘main’:2.c:6:5:警告:函数‘preenche_telefone’的隐式声明-W隐函数声明tf = preenche_telefone(tf.numero,tf.nome);
这是因为preenche_telefone()在tele.h中没有声明。如果main()试图调用该函数而不对其进行作用域内声明,这是一个错误,但由于历史原因,许多编译器接受该调用并试图猜测声明。这种猜测总是假定函数的返回类型是int,而int不是像TELEFONE这样的结构的有效初始化器。
解决方案:将所需的preenche_telefone()声明添加到tele.h。
https://stackoverflow.com/questions/71725993
复制相似问题