почему моя переменная хранит значение из предыдущих запусков рекурсии?

#c

#c

Вопрос:

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

введите описание изображения здесьоднако во второй программе я не возвращаю никакого значения для натуральных чисел, единственный случай возврата — это когда аргумент равен 0.

В идеале (принимая 5 в качестве входных данных) рекурсия будет происходить до тех пор, пока значение num не будет равно 0. Сначала с

сумма = 5 добавить (5-1);

сумма = 4 добавить (4-1);

сумма = 3 добавить (3-1);

сумма = 2 добавить (2-1);

сумма = 1 добавить (1-1);

На этом этапе функция вернет 0, когда поток перейдет к блоку else, а значение sum для этого цикла равно 0.

Теперь, когда возвращается 0, мы поднимаемся на один шаг вверх, и вместо add (1-1) в строке будет 0 sum = num add(num-1); это должно выглядеть так

сумма = 1 0;

функция add (num) должна завершиться сейчас, после присвоения 1 переменной sum. Два основных вопроса.

  1. Для sum = 2 add (2-1) значение не должно увеличиваться, так как на предыдущем шаге значение не возвращается. для add(1), после получения значения из add(0), суммирование 1 и возвращаемого значения сохраняется в переменной sum, а затем выходит из тела функции.

  2. Каждый раз, когда происходит рекурсия, объявляется новая переменная sum и инициируется значением 0, поэтому я не понимаю, почему компьютер сохраняет значения sum из предыдущих вызовов функции, когда вместо этого он должен запускать новую переменную sum.

для меня, после завершения кода, значение переменной sum в add() должно быть 1.

Пожалуйста, кто-нибудь, если вы можете разобраться в этом коде. Дайте мне знать. С благодарностью

P.s: вы также можете попробовать это на любом онлайн-компиляторе C. Вот код:

 #include <stdlib.h>
#include <stdio.h>

int add(int num);

int main(){
    int number,sum;
    printf("enter a number of your choice: ");
    scanf("%d",amp;number);
    sum = add(number);
    printf("SUM = %d",sum);
}

int add(int num){
    int sum = 0;
    if(num != 0)
        sum = num   add(num-1);
    else
        return sum;
}
  

Ответ №1:

sum = add(number);

Использование возвращаемого значения функции, которая завершилась с конца, без явного возврата значения, является неопределенным поведением. UB означает, что разрешено все, что угодно, включая создание (ложной) иллюзии, что переменная «хранит значение из предыдущих запусков рекурсии«. Цитирую из C11 6.9.1 / 12:

Если достигнуто значение, } которое завершает функцию, и вызывающая функция использует значение вызова функции, поведение не определено.

Ответ №2:

Функция, объявленная для возврата int , всегда должна возвращать значение (т. Е. int значение). Ваш код этого не делает.

 int add(int num){
    int sum = 0;
    if(num != 0)
        // If the execution gets in here
        sum = num   add(num-1);
    else
        return sum;
    // it will continue here (when the recursion ends). 
    // And here it is WITHOUT a returned value - that's bad.
}
  

Вы, вероятно, хотите:

 int add(int num){
    int sum = 0;
    if(num != 0)
        sum = num   add(num-1);
    return sum;
}
  

или

 int add(int num){
    if(num != 0)
        return num   add(num-1);
    else
        return sum;
}
  

или (более понятный и безопасный):

 int add(int num){
    if(num <= 0) 
    {
        return 0;
    }
    return num   add(num-1);
}