Почему эта переменная изменяется при передаче в функцию - PullRequest
1 голос
/ 07 февраля 2020

Я недавно начал работать над шахматным движком, и у меня возникли проблемы с функцией применения ходов к доске. У меня есть тип структуры для состояния доски и другой для хранения ходов. Они оба в моем заголовочном файле ниже.

#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

Main. c вызывает функцию «Перемещение процесса» из поколения Move. c. Он проходит один из типов состояния доски и один из типов хода:

#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;
}

Ниже приведена генерация движения. c, которая содержит функцию для обработки движения:

#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

Это не весь код из файлов. c, но здесь все важно. Что делает это странным, так это то, что значения хода меняются, как только я вызываю функцию. Когда я помещаю весь код в один большой файл c и компилирую таким образом, проблема исчезает, но я пытаюсь сохранить отдельный код, чтобы оставаться организованным. Это меня полностью поставило в тупик. Буду признателен за любую помощь!

1 Ответ

2 голосов
/ 07 февраля 2020

Здесь как минимум 2 проблемы, вызывающие неопределенное поведение.

Во-первых, существует несколько определений boardState currentBoard;. Помните, что #include - это замена обычного текста, поэтому оба ваших c файла заканчиваются определением этого объекта. См. Здесь подробное объяснение с примерами .

Если вы хотите, чтобы глобальный объект был доступен из нескольких единиц перевода, тогда заголовочный файл должен содержать объявление только (т.е. добавьте extern к текущей строке), и точно один из файлов. c должен содержать определение.

Во-вторых, в main() вы вызываете необъявленную функцию processMove. Если вы компилируете в стандартном режиме, то компилятор должен сгенерировать сообщение об ошибке. Вероятно, это является причиной ваших симптомов, и я настоятельно рекомендую вызывать ваш компилятор в современном стандартном режиме с высоким уровнем диагностики c, так как это сэкономило бы вам много времени, чтобы быстрее узнать об этой проблеме.

Чтобы исправить это, объявление boardState processMove(boardState, move); должно быть в declarations.h.

...