находка gcd: не все пути управления возвращают значение - PullRequest
0 голосов
/ 12 февраля 2020
int gcd(int a, int b) {
    if (b == 0)
        return a;
    else {
        gcd(b, a % b);
    }
}

Когда я пытаюсь вычислить наибольший общий делитель, я знаю, что я должен назвать return gcd(b,a%b), а не gcd(b,a%b). Но я не понимаю причину почему. Разве b не становится 0 в какой-то момент?

Ответы [ 2 ]

0 голосов
/ 12 февраля 2020

На самом деле вам не нужно делать

return gcd(b,a%b)

, но это самый простой способ сделать это.

Кажется, вы понимаете, что вам нужно возвращаться во всех ситуациях, если int из функция с головой типа

int gcd(int a, int b) 

Выполнение в обеих ветвях if - это короткий способ сделать это.

Можно утверждать, что для таких побочных целей, как удобочитаемость, ремонтопригодность, надежность и т. Д. c. самый последний оператор возвращающих int функций всегда должен быть return SomeInt;. Но это не так просто сделать так, чтобы не получить жалобу на «недоступный код» многими инструментами анализа stati c. Локальная переменная int returnValue, инициализированная мудро выбранным значением по умолчанию и записанная во всех ветвях, может привести вас туда.
Но опять же, некоторые инструменты жалуются, что значение записывается в переменную, которая затем всегда перезаписывается перед использованием. .. Таким образом, инициализация по умолчанию может быть a, и тогда она не будет перезаписана в «тогда». Осчастливить инструменты анализа иногда - это игра l oop -the-loops ...

Кстати, код, который вы показываете, может (абсолютно без гарантии) действительно работать, потому что компиляторы иногда возвращают последний вычисленный результат по умолчанию, даже если он был проигнорирован. Но вы никогда не должны полагаться на это и заслуживать каких-либо жалоб со стороны людей или инструментов. Мы можем с уверенностью считать, что это BadIdea (тм).

0 голосов
/ 12 февраля 2020

Когда вы вызываете функцию в первый раз,。 если b!=0, то она продолжит выполняться else gcd(b, a % b); Но функция, которую вы вызывали в первый раз, не имеет возвращаемого значения.

Следующий код поможет вы понимаете рекурсию:

int gcd(int a, int b) {
    if (b == 0)
        return a;
    else {
        return gcd(b, a % b);
    }
}

int calc_gcd(int a, int b) {
    if (b == 0)
        return a;
    else {
        gcd(b, a % b);
        // return ?
    }
}

вызов функции calc_gcd эквивалентен вызову gcd в вашем коде. отсутствует возвращаемое значение. Правильная рекурсивная функция будет работать так:

gcd0                                         ... return value to user
   gcd1                                 .... ↑ 
      gcd2                         .... ↑
         gcd3 .... pass value to ↑
...