如何link C ansi中的所有文件?多重定义错误
How to link all files in C ansi? Error with multiple definition
早上好
这对我来说 link 所有文件(main.c、myFunc.c、myFuncHeaders.h 和 生成文件)。
问题是 多重定义 当我不知道该怎么办时。我使用了全局变量 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;
}
问题在这里:
main.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "myFunc.c"
#include "myFuncHeaders.h"
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("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] = {{'_', '_', '_'},{'_', '_', '_'},{'_', '_', '_'} };
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;
}
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);
MakeFile
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()
,然后发送给函数。我遇到的错误比我预期的要多。如果有人 link 或有相同问题的来源,我将很高兴获得此信息。
问题是您 #include "myFunc.c"
在 main.c
中,所以您在编译的 main.o
中包含函数 show_board
、add_mark
等的实现对象,这些函数也包含在 myFunc.o
编译对象中,直接编译相同源文件的结果。链接器看到这一点后会抱怨,因为它不知道要使用哪个函数,以及您何时调用例如add_mark
在main
中不知道调用哪个
解决你的问题,你只需要摘下线
#include "myFunc.c"
并在文件 myFunc.h
中也包含 myFuncHeaders.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.c
或 myFuncHeaders.h
(这是最后一个,因为您已经修改了 [=24= 中定义的函数的接口],那么你需要重新编译main.c
到main.o
,否则最终的可执行文件会不一致(你的程序会崩溃)。
早上好
这对我来说 link 所有文件(main.c、myFunc.c、myFuncHeaders.h 和 生成文件)。
问题是 多重定义 当我不知道该怎么办时。我使用了全局变量 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;
}
问题在这里:
main.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "myFunc.c"
#include "myFuncHeaders.h"
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("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] = {{'_', '_', '_'},{'_', '_', '_'},{'_', '_', '_'} };
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;
}
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);
MakeFile
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()
,然后发送给函数。我遇到的错误比我预期的要多。如果有人 link 或有相同问题的来源,我将很高兴获得此信息。
问题是您 #include "myFunc.c"
在 main.c
中,所以您在编译的 main.o
中包含函数 show_board
、add_mark
等的实现对象,这些函数也包含在 myFunc.o
编译对象中,直接编译相同源文件的结果。链接器看到这一点后会抱怨,因为它不知道要使用哪个函数,以及您何时调用例如add_mark
在main
中不知道调用哪个
解决你的问题,你只需要摘下线
#include "myFunc.c"
并在文件 myFunc.h
中也包含 myFuncHeaders.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.c
或 myFuncHeaders.h
(这是最后一个,因为您已经修改了 [=24= 中定义的函数的接口],那么你需要重新编译main.c
到main.o
,否则最终的可执行文件会不一致(你的程序会崩溃)。