#c #if-statement #return-value
#c #if-оператор #возвращаемое значение
Вопрос:
У меня есть рекурсивная функция, которая имитирует игру в Башни (разновидность игры в шашки). Моя функция получает поле и мой цвет. Он проверяет, закончилась ли игра, что является условием отмены моей рекурсии. Для -1 это означает, что игра не закончена, поэтому она вызывает себя рекурсивно с измененным цветом и новой игровой доской. Если игра окончена, она возвращает либо 0, либо 1.
int simulate(int myColour, char field[WIDTH][HEIGTH][MAX_TOWER_LENGTH]){
int cancel = checkForEndOfGame(field);
//int returnValue=50;
struct moveArray moves;
memset(amp;moves, 0, sizeof(moves));
printf("DEBUG: CANCEL-Value: %in", cancel);
if(cancel==-1){
moves=calculatePossibleMoves(moves, field, myColour);
int indexMove = rand() % moves.count;
makeMove(field, moves.moves[indexMove]);
printGameboard(field);
int colourChange;
if(myColour==WHITE){
colourChange=BLACK;
} else colourChange=WHITE;
simulate(colourChange, field);
}
if(cancel==0){
printGameboard(field);
return 1;
}
if(cancel==1){
printGameboard(field);
return 0;
}
return 13;
}
Даже если cancel имеет значение 1 (что означает, что я должен получить возврат 0), моя функция возвращает 13.
Я ввожу значение return 13 только потому, что в противном случае мой компилятор (gcc) выдает мою ошибку:
error: non-void function does not return a value in all control paths
[-Werror,-Wreturn-type]
Комментарии:
1.Поскольку компилятор не может проверить
checkForEndOfGame
, он должен предположить, что может быть возвращено любоеint
значение. Например, если бы он вернулся2
, ни одно из вашихif
значений не было бы истинным. Таким образом, элемент управления будет находиться в нижней части функции. Компилятор понимает, чтоreturn
для этого управляющего пути не существует, поэтому он помечает его. Вот почему вам это нужно.2. Подсказка: когда
cancel == -1
, чтоsimulate()
вернется?3. но даже если я добавлю: else возвращает 12; он не будет компилироваться
4. @Нейт Элдридж: но разве не так работает рекурсия, что она переходит к условию отмены и возвращает 0 или 1 в конце?
5. В этом пути кода он вызывает
simulate()
. Когда рекурсивный вызовsimulate()
возвращает, выполнение продолжается. Значениеcancel
в этом экземпляреsimulate()
не изменилось и остается-1
неизменным, поэтому ни один из оставшихсяif
блоков не выполняется, и мы переходим кreturn 13
концу.
Ответ №1:
Ваш рекурсивный вызов не предпринимает никаких попыток передать причину отмены вызывающему. Кажется, вы ожидаете, что это произойдет как-то автоматически, но этого не произойдет. Каждый рекурсивный вызов simulate
имеет свои собственные локальные переменные — что очень важно, cancel
— поэтому после возврата рекурсивного вызова локальное значение cancel
останется неизменным (и все равно -1), и поэтому будет возвращено 13.
То, что вы, вероятно, хотели сделать, это просто передать возвращаемое значение, сделав рекурсивный вызов конечным вызовом:
return simulate(colourChange, field);