鉴于以下代码,
button.h
#ifndef BUTTON_H_
#define BUTTON_H_
#define true 1
#define false 0
#include <avr/io.h>
#include <avr/interrupt.h>
#include <timer0.h>
typedef struct {
unsigned char port;
unsigned char pin;
unsigned long timestamp;
} BUTTONS;
BUTTONS button_1;
BUTTONS button_2;
BUTTONS button_3;
enum BUTTONS_ID{BUTTONS_ID_1,BUTTONS_ID_2,BUTTONS_ID_3,BUTTONS_ID_COUNT};
BUTTONS* button[BUTTONS_ID_COUNT] = {&button_1,&button_2,&button_3};
void Button_init(void);
#endif //BUTTON_H_
和button.c
#include <button.h>
enum BUTTONS_state{BUTTON_STATE_UNPRESSED,BUTTON_STATE_DEBOUNCING,BUTTON_STATE_PRESSED};
int state = BUTTON_STATE_UNPRESSED;
void Button_init(void){
button[BUTTONS_ID_1]->port = PINB;
button[BUTTONS_ID_1]->pin = PINB4;
button[BUTTONS_ID_1]->timestamp = 0;
}
我收到以下错误:button.cpp:`button_1'的多重定义。我知道我一定做错了。我很擅长使用结构,错误必须来自那里。基本上我想创建按钮变量,如果需要我可以从我的主程序访问。有没有办法在我的.h中定义它们并在我的.c中初始化它们然后从我的主文件中访问它们?
谢谢
答案 0 :(得分:1)
您已在头文件中定义了button1
和其他几个对象。如果将此标题包含在多个翻译单元(读取:源文件)中,则最终会为您编译的每个翻译单元定义一个定义。然后,当您尝试链接时 - &gt; KABOOM。
简单的解决方案是“不要在代码中放置定义对象的代码”。如果您需要在多个源文件中访问它们,可以保留声明,但是您需要将它们标记为extern
。然后,您可以在其他地方的源文件中进行定义。
答案 1 :(得分:0)
您不应在头文件中声明变量。这是因为当头文件在c文件中被#included时,预处理器就会将它复制到它。
因此,如果2个c文件包含相同的h文件,而h文件又声明了一个变量,那么最终会在两个文件中声明两次相同的变量。这可能就是这里发生的事情 - 你可能在另一个c文件中#include button.h。
将变量应用程序设置为全局的最佳方法是仅在一个文件中声明它,然后在每个要使用它的c文件中使用extern
声明它。
在您的示例中,执行
BUTTONS button_1;
BUTTONS button_2;
BUTTONS button_3;
在一个c文件中,以及要使用这些变量的所有其他c文件中,执行:
extern BUTTONS button_1;
extern BUTTONS button_2;
extern BUTTONS button_3;
还有其他方法可以做到这一点。可以使用一些预处理器杂技并在头文件中声明变量,使得只在一个文件中声明为全局变量,在所有其他文件中,它们用extern
声明。但我个人不喜欢这个,因为我认为变量声明不属于头文件。
此外,最好不要使用应用程序全局变量,这会导致进行模块化编程,低耦合和所有这些内容的方法。这是一个非常有趣和重要的话题,但是对于这个答案来说是广泛的......: - )