Вызов другой функции в рекурсивной функции приводит к ошибке. Почему?

#c #c 11 #recursion #visual-c #c 14

#c #c 11 #рекурсия #visual-c #c 14

Вопрос:

У меня есть две функции fun() и fun2();

fun() вызывает себя при увеличении глобальной переменной a=0 и завершается, если a==5 . Но если я вызываю другую функцию с именем fun2(), которая в основном возвращает и ничего не делает, тогда возникает ошибка сборки. Почему? Я просто экспериментирую с рекурсией, и я получил эту ошибку.

 #include<iostream>
using namespace std;
int a = 0;

void fun() {
    if (a == 5)
        return;
    a  ;
    fun();
    fun2();  //This is where the trouble happens
}
        
void fun2() {
    return;
}

int main() {
    fun();
    return 0;
}
  

Вывод:
введите описание изображения здесь

Комментарии:

1. Компилятор читает сверху вниз. Он еще не знает о fun2 функции, в которой вы пытаетесь ее вызвать. Либо переместите определение выше fun , либо добавьте прототип.

2. @RetiredNinja почему это происходит?

3. Вы пометили это как C , но использовали не один класс.

Ответ №1:

Вы получите аналогичную ошибку с

 void fun() {
    fun2(); 
}

void fun2() {}

int main() {
    fun();
}
  

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

 #include<iostream>

void fun2();   // declaration

void fun() {
    // ...
    fun2();  
}

void fun2() { }  // definition

int main() {
    fun();

    return 0;
}
  

…или просто определите fun2 раньше fun .

Комментарии:

1. @ALLAN невозможно запомнить все, хотя я, честно говоря, задаюсь вопросом, что было неясно в сообщении об ошибке

2. Я только начинаю. Мне нужно учиться, чтобы запомнить 🙂

3. @ALLAN Независимо от того, сколько вы изучаете, вы никогда не сможете запомнить все или избежать каждой ошибки. Важнее научиться читать сообщения об ошибках, они созданы для того, чтобы вы могли читать и показывать вам, что не так в коде.

Ответ №2:

Вы должны объявлять или определять функции перед их использованием.

 #include<iostream>
using namespace std;
int a = 0;
void fun2(); // add this (declaration of function fun2)
void fun() {
    if (a == 5)
        return;
    a  ;
    fun();
    fun2();  //This is where the trouble happens
}

void fun2() {
    return;
}
int main() {
    fun();

    return 0;
}
  

Ответ №3:

«почему это так?»

Ну, не из-за рекурсии.

В этом случае это происходит отчасти потому, что ваш код выполнен в стиле c, что в основном требует объявления пользовательских функций, которые вызывает ваш код.


Вы отметили этот пост с помощью c , но используете не один класс.

И, например, если эти функции были инкапсулированы в класс, тогда компилятор c (обычно) найдет функции … даже без предварительного объявления.

Пример:

Далее я инкапсулировал ваш код внутри функтора (упрощенный класс c )

И, поскольку ваш код не выводит, я добавил cout в местах, чтобы наглядно продемонстрировать, что код компилируется и функции выполняются.

 #include <iostream>
using std::cout, std::cerr, std::endl, std::hex, std::dec, std::cin; 

#include <string>
using std::string, std::to_string;



int a = 0;  // still global, though many discourage use


// functor ... a simple class
class F705_t // ctor and dtor are compiler provided defaults
{
public:

// main() enters at this function
int operator()(int argc, char* argv[]) 
{
  return exec(argc, argv);  // exec not yet declared!
}

private:

int exec(int , char** ) // line 31
{
  cout << "n  F705_t::exec()";
  fun();   // using fun() before declared
  cout << endl;
  return 0;
}

void fun() // line 37
{
  cout << "n  F705_t::fun()" << "  a: " << a;

  if (a == 5)
    return;
  a  ;
  fun();   // recursive call 
  fun2();  // using fun2() before declared
}
        
void fun2()  // line 47
{
  cout << "n  F705_t::fun2()" << "  a: " << a;;
  return; 
}
} // class F705_t

// main() is a c-ism, 
// and is required of the user in most (but not all) c   environments
int main(int argc, char* argv[]) { return F705_t()(argc, argv); }
//           how invoke a functor --------^^^^^^^^^^^^^^^^^^^^
  

Вывод:

   F705_t::exec()
  F705_t::fun()  a: 0
  F705_t::fun()  a: 1
  F705_t::fun()  a: 2
  F705_t::fun()  a: 3
  F705_t::fun()  a: 4
  F705_t::fun()  a: 5
  F705_t::fun2()  a: 5
  F705_t::fun2()  a: 5
  F705_t::fun2()  a: 5
  F705_t::fun2()  a: 5
  F705_t::fun2()  a: 5