如何在C语言中编写适当的包含和模块化应用程序?

如何在C语言中编写适当的包含和模块化应用程序?,c,include,c-preprocessor,C,Include,C Preprocessor,我再次请求您的帮助:在includes中找不到错误,检查了几次,并与geekstogeeks示例和类似问题进行了比较。所以我有: /tmp/ccWUaJkV.o:/home/felix/Programming/dypak/objects.obj:27: multiple definition of `RankNames' /tmp/ccA7hhxl.o:/home/felix/Programming/dypak/objects.obj:27: first defined here /tmp/cc

我再次请求您的帮助:在includes中找不到错误,检查了几次,并与geekstogeeks示例和类似问题进行了比较。所以我有:

/tmp/ccWUaJkV.o:/home/felix/Programming/dypak/objects.obj:27: multiple definition of `RankNames'
/tmp/ccA7hhxl.o:/home/felix/Programming/dypak/objects.obj:27: first defined here
/tmp/ccWUaJkV.o:/home/felix/Programming/dypak/objects.obj:28: multiple definition of `SuitNames'
/tmp/ccA7hhxl.o:/home/felix/Programming/dypak/objects.obj:28: first defined here
/tmp/ccWUaJkV.o:(.bss+0x0): multiple definition of `__odr_asan.SuitNames'
/tmp/ccA7hhxl.o:(.bss+0x0): first defined here
/tmp/ccWUaJkV.o:(.bss+0x1): multiple definition of `__odr_asan.RankNames'
/tmp/ccA7hhxl.o:(.bss+0x1): first defined here
collect2: error: ld returned 1 exit status

gcc-rdynamic-std=c11`pkg config-cflags gtk+-3.0`cardmethods.c main.c-o main`pkg config-libs gtk+-3.0`-lX11 objects.obj 方法 方法c main.c
您已经在头文件中定义了变量RankNames和SuitNames。因此,它们在main.c和cardmethods.c中都有定义。然后链接这些文件时,链接器会找到多个定义

将头文件更改为具有这些变量和组的外部声明:

并将定义放在一个源文件中,可能是cardmethods.c:

card *Deck;
char *RankNames[] = {"  6  ", "  7  ", "  8 ", ...};
char *SuitNames[] = {"Hearts", "Spades", "Diamonds", "Clubs"};

您已经在头文件中定义了变量RankNames和SuitNames。因此,它们在main.c和cardmethods.c中都有定义。然后链接这些文件时,链接器会找到多个定义

将头文件更改为具有这些变量和组的外部声明:

并将定义放在一个源文件中,可能是cardmethods.c:

card *Deck;
char *RankNames[] = {"  6  ", "  7  ", "  8 ", ...};
char *SuitNames[] = {"Hearts", "Spades", "Diamonds", "Clubs"};

您不能定义RANKANMES和SUITNAME全局相乘。如果要将它们用作某种常量,可以将它们声明为静态,以限制当前翻译单元的可视性,并避免多个定义错误。那么您也应该将它们声明为const。请注意,objects.obj将是Windows系统上的一个对象文件。选择不同的后缀,这是为了他人的理智,即使不是为了你自己。当你使用include-guards时,它们在标题中的第一个和最后一个是至关重要的。其他包括管线可遵循包括防护装置;它们不应先于它们。如果您不遵守此规则,则可能会在相互递归的头文件中遇到麻烦。您无法全局定义RankNames和SuiteNames。如果要将它们用作某种常量,可以将它们声明为静态,以限制当前翻译单元的可视性,并避免多个定义错误。那么您也应该将它们声明为const。请注意,objects.obj将是Windows系统上的一个对象文件。选择不同的后缀,这是为了他人的理智,即使不是为了你自己。当你使用include-guards时,它们在标题中的第一个和最后一个是至关重要的。其他包括管线可遵循包括防护装置;它们不应先于它们。如果你不遵循这条规则,你可能会在相互递归的头文件中遇到麻烦。非常感谢,它工作得非常好。问题是我重新定义了变量。非常感谢,它工作得非常好。问题是我重新定义了变量。
#include "cardmethods.h"
#include <time.h>
#include <stdio.h>
#include <stdlib.h>

void addCard(card *pile, card *cardAdded){
    ...
}
void printAll(card *pile){
    ...
}
...
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include "cardmethods.h"

 ...

int main (int    argc,
      char **argv)
{
  ...
  return 0;
}

extern card *Deck;
extern char *RankNames[];
extern char *SuitNames[];
card *Deck;
char *RankNames[] = {"  6  ", "  7  ", "  8 ", ...};
char *SuitNames[] = {"Hearts", "Spades", "Diamonds", "Clubs"};