如何链接C ansi中的所有文件?多重定义错误

问题描述

早上好

链接所有文件main.c、myFunc.c、myFuncHeaders.hMakeFile)对我来说是个大问题。 问题是多重定义,当我不知道该怎么处理它时。我使用了全局变量 char board[3][3]char board_checked[3][3]int playersRound。我知道 global 将是不必要的和设计糟糕的程序,但我想尝试一些新的东西。简单的井字游戏

一个文件中(合二为一),代码有效。这里:

#include<stdio.h>
#include <stdlib.h>

char board[3][3] = {{'_','_','_'},{'_','_'} };
char board_checked[3][3] = {{'+','+','+'},{'+','+'}};
int playersRound = 0;

// It shows board
void show_board(){
    char * space = "          ";
    puts("\tPlansza\n\t==================================");
    for(int i = 1; i < 4; i++)
    {
        printf("%s|%d|",space,i);
    }
        printf("\n");
    for(int i = 0; i < 3; i++){
        printf("\t|%d|",i+1);
        for(int j = 0; j < 3; j++)
        {
            printf("%c  %s",board[i][j],space);
        }
        printf("\n\n");
    }
    puts("\t==================================\n");
}


// This function add a player's mark - 'X' or 'O' - to board
void add_mark(int *p,int player){
    // If it isn't reserved by other mark
    if(board_checked[p[0]-1][p[1]-1] != '-'){
        // x (p[1]) and y (p[0]) vectors are (1,2,3)
        if(1 <= p[0] && p[0] <= 3 && 1 <= p[1] && p[1] <= 3)
        {
            if(player == 1)
            {
                // Add to board 'X'
                board[p[0]-1][p[1]-1] = 'O';
                // and unchecked at the same position 'board_checked'
                board_checked[p[0]-1][p[1]-1] = '-';

            }
            else
            {
                // Add to board 'X'
                board[p[0]-1][p[1]-1] = 'X';
                // and unchecked at the same position 'board_checked'
                board_checked[p[0]-1][p[1]-1] = '-';
            }
            // If Everything is Okey go to next playersRound
            playersRound++;
        }
    }
    else
        // On start variable is position[2] = {0,0}; it's mean that I made exception
        if(!(0 == p[0] && 0 == p[1]))
        {
            puts("Nie poDales poprawnych parametrow");
            sleep(2);
        }
}


// This function check every position where any mark have been added
int structure_check(int player){
    //return winner
    for(int i = 0; i < 2; i++){
        // Check horizontal
        for(int level = 0; level < 3; leveL++)
            if(board[level][0] == board[level][1] && board[level][0] == board[level][2] && board[level][0] != '_')return player;
        // Check vertical
        for(int level = 0; level < 3; leveL++)
            if(board[0][level] == board[1][level] && board[0][level] == board[2][level] && board[0][level] != '_')return player;
        // Check diagonal left
        if(board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] != '_')return player;
        // Check diagonal right
        if(board[2][0] == board[1][1] && board[2][0] == board[0][2] && board[0][2] != '_')return player;
    }
    // Draw - when no one of two players won
    return 0;
}



int main(char argc,char * argv[]){
    int player = 1;
    int position[2] = {0,0};
    int status = 0;



    show_board();


    while(playersRound < 10){
        // Short information
        if(player == 1) puts("Gracz 1:");
        else puts("Gracz 2:");
        // Get position
        printf("\tx:"); scanf("%d",&position[0]);
        printf("\ty:"); scanf("%d",&position[1]);
        // status game,win or draw
        status = structure_check(player);
        // Players movement in playersRounds
        if(playersRound%2 == 0) player = 1;
        else player = 2;
        // This add mark to board by player
        add_mark(position,player);
        // Clear console
        system("cls");
        // Show only board
        show_board();
        // To be sure it works
        status = structure_check(player);
        // It finish when someone won game
        if(status != 0) break;
    }

    if(player == 1)
        printf("Wygrywa gracz: 1 z  'O'");
    else
        printf("Wygrywa gracz: 2 z  'X'");
    puts("  ||| Gratulacje! |||");

    return 0;
}

问题出在这里

ma​​in.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "myFunc.c"
#include "myFuncHeaders.h"



int main(char argc,0};
    int status = 0;
    
    

    show_board();
    

    while(playersRound < 10){
        // Short information
        if(player == 1) puts("Gracz 1:");
        else puts("Gracz 2:");
        // Get position
        printf("\tx:"); scanf("%d",player);
        // Clear console
        system("clear");
        // Show only board
        show_board();
        // To be sure it works
        status = structure_check(player);
        // It finish when someone won game
        if(status != 0) break;
    }

    if(player == 1)
        printf("Wygrywa gracz: 1 z  'O'");
    else
        printf("Wygrywa gracz: 2 z  'X'");
    puts("  ||| Gratulacje! |||");

    return 0;
}

myFunc.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // sleep() 
#include "myFuncHeaders.h"

char board[3][3] = {{'_','+'}};
int playersRound = 0;

// It shows board 
void show_board(){
    char * space = "          ";
    puts("\tPlansza\n\t==================================");
    for(int i = 1; i < 4; i++)
    {
        printf("%s|%d|",0}; it's mean that I made exception
        if(!(0 == p[0] && 0 == p[1]))
        {
            puts("Nie poDales poprawnych parametrow");
            sleep(2);
        }
}


// This function check every position where any mark have been added
int structure_check(int player){
    //return winner
    for(int i = 0; i < 2; i++){
        // Check horizontal
        for(int level = 0; level < 3; leveL++)
            if(board[level][0] == board[level][1] && board[level][0] == board[level][2] && board[level][0] != '_')return player;
        // Check vertical
        for(int level = 0; level < 3; leveL++)
            if(board[0][level] == board[1][level] && board[0][level] == board[2][level] && board[0][level] != '_')return player;
        // Check diagonal left
        if(board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] != '_')return player;
        // Check diagonal right
        if(board[2][0] == board[1][1] && board[2][0] == board[0][2] && board[0][2] != '_')return player;
    }
    // Draw - when no one of two players won
    return 0;
}

myFuncHeaders.h

void show_board();
// This function add a player's mark - 'X' or 'O' - to board
void add_mark(int *p,int player);
// This function check every position where any mark have been added
int structure_check(int player);

制作文件

main:               main.o myFunc.o
                    gcc -o main main.o myFunc.o

myFunc.o:           myFunc.c myFunc.o
                    gcc -c -o myFunc.o myFunc.c

输出

*my foleder*
~/zadania_domowe/kolko_krzyzyk $ make
cc    -c -o main.o main.c
make: circular version myFunc.o <- myFunc.o lost.
gcc -c -o myFunc.o myFunc.c
gcc -o main main.o myFunc.o
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../x86_64-pc-linux-gnu/bin/ld: myFunc.o:(.data+0x0): multiple deFinition of `board'; main.o:(.data+0x0): first defined here
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../x86_64-pc-linux-gnu/bin/ld: myFunc.o:(.data+0x10): multiple deFinition of `board_checked'; main.o:(.data+0x10): first defined here
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../x86_64-pc-linux-gnu/bin/ld: myFunc.o:(.bss+0x0): multiple deFinition of `playersRound'; main.o:(.bss+0x0): first defined here
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../x86_64-pc-linux-gnu/bin/ld: myFunc.o: in function `show_board':
myFunc.c:(.text+0x0): multiple deFinition of `show_board'; main.o:main.c:(.text+0x0): first defined here
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../x86_64-pc-linux-gnu/bin/ld: myFunc.o: in function `add_mark':
myFunc.c:(.text+0xf5): multiple deFinition of `add_mark'; main.o:main.c:(.text+0xf5): first defined here
/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../x86_64-pc-linux-gnu/bin/ld: myFunc.o: in function `structure_check':
myFunc.c:(.text+0x2a6): multiple deFinition of `structure_check'; main.o:main.c:(.text+0x2a6): first defined here
collect2: error: ld returned 1 exit status
make: *** [makefile:2: main] Error 1

我尝试使用 extern 全局,将这个全局变量放入 main() 然后发送到函数。我的错误比我预期的要多。如果有人有相同问题的链接或来源,我会很高兴提供此信息。

解决方法

问题是您在 #include "myFunc.c"main.c,因此您在 show_board 编译对象中包含函数 add_markmain.o 等的实现,并且这些函数也包含在 myFunc.o 编译对象中,是直接编译相同源文件的结果。链接器在看到这一点时会抱怨,因为它不知道要使用哪个函数,以及何时调用例如add_markmain 中它不知道要调用哪个。

解决你的问题,你只需要下线

#include "myFunc.c"

并在文件 myFuncHeaders.h 中包含 myFunc.h,以便您可以检查头文件中给出的定义是否与您在文件 myFunc.c 中提供的实现兼容。>

还有一个错误来自 make 告诉你已经包含了一个规则,表明 myFunc.o 文件依赖于 myFunc.o,这是一个循环依赖,这是一个错误(make 不能被赋予带有循环的依赖规则,因为如果它必须允许它们就永远不会结束)你需要改变

myFunc.o: myFunc.c myFunc.o
    gcc -c -o myFunc.o myFunc.c

进入

myFunc.o: myFunc.c myFuncHeaders.h
    gcc -c -o myFunc.o myFunc.c

并为 main.o 编写一个类似的(默认情况下,内部 make 的版本,您将看到 make 调用了 cc 编译器,以编译 main.c 而不是gcc)

main.o: main.c myFuncHeaders.h
    gcc -c -o main.o main.c

规则是认为如果您触摸(编辑)任何文件 main.cmyFuncHeaders.h(最后一个是因为您已将接口修改为 myFunc.c 中定义的函数,那么你需要重新编译 main.cmain.o,否则最终的可执行文件会不一致(你的程序会崩溃)。