C 为什么这个变量在传递给函数时会发生变化
我最近开始开发一个国际象棋引擎,但在向棋盘应用移动的功能方面遇到了问题。我有一个用于董事会状态的结构类型,另一个用于存储移动。它们都在我下面的头文件中C 为什么这个变量在传递给函数时会发生变化,c,chess,C,Chess,我最近开始开发一个国际象棋引擎,但在向棋盘应用移动的功能方面遇到了问题。我有一个用于董事会状态的结构类型,另一个用于存储移动。它们都在我下面的头文件中 #ifndef DECLARATIONS_H #define DECLARATIONS_H #include <stdbool.h> #define BOARD_SIZE 120 typedef struct move { int startingSquare; int endingSquare; int
#ifndef DECLARATIONS_H
#define DECLARATIONS_H
#include <stdbool.h>
#define BOARD_SIZE 120
typedef struct move {
int startingSquare;
int endingSquare;
int promotionPiece;
} move;
typedef struct boardState {
int board[BOARD_SIZE];
bool whoseTurn;
int ply;
int threeMoveRuleCount;
int fiftyMoveRuleCount;
bool whiteCastleKingside;
bool whiteCastleQueenside;
bool blackCastleKingside;
bool blackCastleQueenside;
int enPassant;
float evaluation;
move previousMove;
} boardState;
boardState currentBoard;
#endif
这并不是.c文件中的全部代码,但它是这里所有相关的内容。奇怪的是,我一调用函数,move的值就改变了。当我把所有代码放在一个大的.c文件中并以这种方式编译时,问题就消失了,但我正试图将代码分开以保持组织。这件事把我彻底难住了。我将感谢任何帮助 这里至少有两个问题,导致未定义的行为 首先,
boardState-currentBoard有多种定义代码>。请记住,#include
是纯文本替换,因此两个c
文件都以该对象的定义结束
如果希望从多个翻译单元访问全局对象,则头文件应仅包含一个声明(即,将extern
前置到当前行),并且只有一个.c文件应包含该定义
其次,在main()
中调用未声明的函数processMove
。如果在标准模式下编译,则编译器应生成错误消息。这很可能是您出现症状的原因,我强烈建议您在现代标准模式下以高诊断级别调用编译器,因为这样可以节省您大量时间,以便更快地发现此问题
为了解决这个问题,声明boardState processMove(boardState,move)代码>应该在声明中。h
变量定义板状态currentBoard代码>位于头文件中。我猜这可能看起来像是编译movegeneration.c
,然后更改struct move
结构中的成员,然后编译main.c
并链接。如果重新编译所有内容,问题是否会重现?。当然,最好是明确的。@ikegami您的链接属于同一个暂定定义,在一个翻译单元中重复两次,但是在本代码中,它出现在多个翻译单元中。这会导致多个外部定义。没有提到暂定声明必须在同一个翻译单元中,gcc
可以忽略extern
(即使是-std=c99
)。这些事实都不是确定的,但它们似乎与你的主张相矛盾。@ikegami标准是权威的,你可以阅读或在Jerry Coffin的回答中看到相关信息。这是未定义的行为,不需要诊断。未定义的行为意味着任何事情都可能发生,您看到gcc做了一些事情,因此gcc与我的主张一致,即修复了它!非常感谢!
#include <stdio.h>
#include <string.h>
#include "declarations.h"
int main () {
move firstMove;
firstMove.startingSquare = 35;
firstMove.endingSquare = 55;
firstMove.promotionPiece = 0;
printf("Value of firstMove.endingSquare: %d\n", firstMove.endingSquare);
printf("Value of firstMove.startingSquare: %d\n", firstMove.startingSquare);
printf("Value of firstMove.promotionPiece: %d\n", firstMove.promotionPiece);
processMove(currentBoard, firstMove);
return 0;
}
#include <stdio.h>
#include "declarations.h"
boardState processMove(boardState, move);
boardState processMove(boardState oldBoardState, move moveToApply) {
boardState newBoardState = oldBoardState;
printf("Value of moveToApply.endingSquare: %d\n", moveToApply.endingSquare);
printf("Value of moveToApply.startingSquare: %d\n", moveToApply.startingSquare);
printf("Value of moveToApply.promotionPiece: %d\n", moveToApply.promotionPiece);
return newBoardState;
}
Value of firstMove.endingSquare: 55
Value of firstMove.startingSquare: 35
Value of firstMove.promotionPiece: 0
Value of moveToApply.endingSquare: 0
Value of moveToApply.startingSquare: 55
Value of moveToApply.promotionPiece: 1996058613