Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么这个变量在传递给函数时会发生变化_C_Chess - Fatal编程技术网

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