C 令牌的多重定义

C 令牌的多重定义,c,header-files,avr-gcc,C,Header Files,Avr Gcc,给定以下代码 按钮 #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 tim

给定以下代码

按钮

#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_
\ifndef按钮_
#定义按钮_
#定义真1
#定义false 0
#包括
#包括
#包括
类型定义结构{
无符号字符端口;
无符号字符引脚;
无符号长时间戳;
}按钮;
按钮1;
按钮2;
按钮3;
枚举按钮\u ID{BUTTONS\u ID\u 1、BUTTONS\u ID\u 2、BUTTONS\u ID\u 3、BUTTONS\u ID\u COUNT};
按钮*按钮[按钮ID\U计数]={&按钮1、&按钮2、&按钮3};
无效按钮_init(无效);
#endif//按钮_
和按钮

#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;
}
#包括
枚举按钮状态{按钮状态未按下,按钮状态取消抖动,按钮状态按下};
int state=按钮\状态\未按下;
无效按钮_init(无效){
按钮[BUTTONS\u ID\u 1]->端口=PINB;
按钮[BUTTONS_ID_1]->pin=PINB4;
按钮[BUTTONS\u ID\u 1]->时间戳=0;
}
我得到以下错误:button.cpp:button_1的多个定义。我知道我一定做错了什么。我在使用结构方面是个新手,错误一定是从那里来的。基本上,我想创建一个按钮变量,如果需要的话,我可以从我的主程序访问它。有没有办法在my.h中定义它们,在my.c中初始化它们,然后从我的主文件访问它们


谢谢

您已经在头文件中定义了
按钮1
和其他几个对象。如果在多个翻译单元(读:源文件)中包含此标题,则最终将为编译的每个翻译单元生成一个定义。然后稍后,当您尝试链接->KABOOM时


简单的解决方案是“不要将定义对象的代码放在标题中”。如果需要在多个源文件中访问它们,可以保留声明,但需要将它们标记为
extern
。然后您可以在其他地方的源文件中进行定义。

您已经在头文件中定义了
按钮1
和其他几个对象。如果在多个翻译单元(读:源文件)中包含此标题,则最终将为编译的每个翻译单元生成一个定义。然后稍后,当您尝试链接->KABOOM时


简单的解决方案是“不要将定义对象的代码放在标题中”。如果需要在多个源文件中访问它们,可以保留声明,但需要将它们标记为
extern
。然后您可以在其他地方的源文件中进行定义。

您不应该在头文件中声明变量。这是因为当一个头文件包含在一个c文件中时,它实际上是由预处理器复制到它的

因此,如果两个c文件包含相同的h文件,而h文件又声明了一个变量,那么两个文件中都会声明两次相同的变量。这可能就是这里发生的事情——您可能在另一个c文件中包含了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;
还有其他方法可以做到这一点。可以使用一些预处理器技巧,在头文件中声明变量,只在一个文件中声明为全局变量,在所有其他文件中声明为外部变量。但我个人不喜欢这样,因为我确实认为变量声明不属于头文件


此外,最好不要使用应用程序全局变量,这会导致采用模块化编程、低耦合等方式。这是一个非常有趣和重要的话题,但对于这个答案来说,这是一个非常广泛的话题

不应在头文件中声明变量。这是因为当一个头文件包含在一个c文件中时,它实际上是由预处理器复制到它的

因此,如果两个c文件包含相同的h文件,而h文件又声明了一个变量,那么两个文件中都会声明两次相同的变量。这可能就是这里发生的事情——您可能在另一个c文件中包含了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;
还有其他方法可以做到这一点。可以使用一些预处理器技巧,在头文件中声明变量,只在一个文件中声明为全局变量,在所有其他文件中声明为外部变量。但我个人不喜欢这样,因为我确实认为变量声明不属于头文件


此外,最好不要使用应用程序全局变量,这会导致采用模块化编程、低耦合等方式。这是一个非常有趣和重要的话题,但对于这个答案来说,这是一个非常广泛的话题一个'CPP '文件扩展意味着你在用C++编译器编译,而不是C。所以你的问题实际上是关于C++的。一个'CPP '文件扩展意味着你在用C++编译器编译,而不是C。所以你的问题实际上是关于C++的。在my.h和我的其他文件中写入
按钮[BUTTONS\u ID\u COUNT]={&button\u 1、&button\u 2和&button\u 3}
正确吗?是的,但是您也需要对
按钮1
按钮2
按钮3
执行相同的操作。例如,我将在my.h和我的其他文件中声明
外部按钮*按钮[BUTTONS\u ID\u COUNT]
按钮[BUTTONS\u ID\u COUNT]{&button\u 1、&button\u 2和button\u 3}正确吗?是的,但是您还需要对
按钮1
按钮2
按钮3
执行相同的操作。