1

给定以下代码,

按钮.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_

和按钮.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 中初始化它们,然后从我的主文件中访问它们?

谢谢

4

2 回答 2

1

您已经button1在头文件中定义了其他几个对象。如果您在多个翻译单元(阅读:源文件)中包含此标头,您最终会为您编译的每个翻译单元提供一个定义。然后稍后,当您尝试链接时 -> KABOOM。

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

于 2013-09-23T22:11:49.757 回答
0

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

因此,如果 2 个 c 文件包含相同的 h 文件,而后者又声明了一个变量,那么您最终会在两个文件中声明两次相同的变量。这可能就是这里发生的事情 - 你可能在另一个 c 文件中 #included button.h。

使变量应用程序全局化的最好方法是只在一个文件中声明它,然后extern在每个要使用它的 c 文件中声明它。

在你的例子中,做

BUTTONS button_1;
BUTTONS button_2; 
BUTTONS button_3;

在一个 c 文件中,以及在您要使用这些变量的所有其他 c 文件中,执行以下操作:

extern BUTTONS button_1;
extern BUTTONS button_2; 
extern BUTTONS button_3;

还有其他方法可以做到这一点。可以使用一些预处理器杂技并在头文件中声明变量,这样只有在一个文件中声明为全局变量,而在所有其他文件中声明为extern. 但我个人不喜欢这样,因为我确实认为变量声明不属于头文件。

此外,最好尽量不要使用应用程序全局变量,这会导致进行模块化编程、低耦合和所有这些事情的方式。这是一个非常有趣和重要的话题,但是对于这个答案来说很广泛.. :-)

于 2013-09-23T22:19:12.883 回答