| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2213 人关注过本帖
标题:c++ 递归的问题
只看楼主 加入收藏
tt138
Rank: 2
等 级:论坛游民
威 望:1
帖 子:16
专家分:17
注 册:2019-4-19
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:10 
c++ 递归的问题
课本程序清单7.16 recur.cpp
#include "pch.h"
#include <iostream>

void countdown(int n);

int main()
{
    countdown(4);
    return 0;
}
void countdown(int n)
{
    using namespace std;
    cout<<"counting down......"<<n<<endl;
    if (n > 0)
        countdown(n - 1);
    cout << n << ":kaboom!\n";        
}
图片附件: 游客没有浏览图片的权限,请 登录注册

当n=0时,执行cout << n << ":kaboom!\n"完后为什么不跳出void countdown(int n)函数而递归?递归的次数指令从那里来的?
就是:
1:kaboom!
2:kaboom!
3:kaboom!
4:kaboom!
显示这4句的指令是那里来的?cout << n << ":kaboom!\n";语句为什么自己在循环?   

请大神指点一下!

[此贴子已经被作者于2019-5-5 12:08编辑过]

搜索更多相关主题的帖子: c++ 递归 void int cout 
2019-05-05 11:57
Jonny0201
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:52
帖 子:488
专家分:2603
注 册:2016-11-7
收藏
得分:5 
因为前面的调用并没有执行完
2019-05-05 12:06
zhulei1978
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:53
帖 子:1351
专家分:1200
注 册:2006-12-17
收藏
得分:5 
先正向逐层调用,再反向逐层返回

其实我就是改变社会风气,提高少女素质,刺激电影市道,提高年轻人内涵,玉树临风,风度翩翩的整蛊专家,我名叫古晶,英文名叫JingKoo!
2019-05-05 12:06
tt138
Rank: 2
等 级:论坛游民
威 望:1
帖 子:16
专家分:17
注 册:2019-4-19
收藏
得分:0 
回复 3楼 zhulei1978
2楼说的不存在,那是if语句,满足条件就不用执行else语句了,明显执行完了。(这里还不是if else语句,加上else后就不回归了,还奇怪些,按if else语句,这里应该有一个隐藏的else,但实际这里没有,是个if语句)。
3楼说的“先正向逐层调用,再反向逐层返回”,我问的就是为什么要“再反向逐层返回”?
为什么这里会返回?是什么让cout << n << ":kaboom!\n"按原路返回执行?这里明显有一个隐性的循环体,不知道是个什么东西。

[此贴子已经被作者于2019-5-5 12:33编辑过]

2019-05-05 12:13
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9007
专家分:53942
注 册:2011-1-18
收藏
得分:5 
以下是引用tt138在2019-5-5 12:13:37的发言:

2楼说的不存在
2楼说的是正确的
你的递归代码相当于
#include <iostream>
using namespace std;

void countdown0()
{
    cout << "counting down......" << 0 << endl;
    cout << 0 << ":kaboom!\n";
}

void countdown1()
{
    cout << "counting down......" << 1 << endl;
    countdown0();
    cout << 1 << ":kaboom!\n";
}

void countdown2()
{
    cout << "counting down......" << 2 << endl;
    countdown1();
    cout << 2 << ":kaboom!\n";
}

void countdown3()
{
    cout << "counting down......" << 3 << endl;
    countdown2();
    cout << 3 << ":kaboom!\n";
}

void countdown4()
{
    cout << "counting down......" << 4 << endl;
    countdown3();
    cout << 4 << ":kaboom!\n";
}

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

2019-05-05 14:38
tt138
Rank: 2
等 级:论坛游民
威 望:1
帖 子:16
专家分:17
注 册:2019-4-19
收藏
得分:0 
回复 5楼 rjsp
真的是这样哦,高手,我先是怎么都想不明白,虽然我现在还是看不明白这个程序是我知识不够,但知道了有办法解释这个问题。谢谢
这个例子经典,完全可以进教科书啊,教科书中就笼统地说怎么来怎么去,象我这种脑子怎么都看不明白。
我刚自学到 函数--c++编程模块,下一章是 函数探幽,我现在知道的函数调用是什么名字就调用什么,
这个例子countdown4()调用居然把函数countdown0()、countdown1()、countdown2()、countdown3()都调用了。
这里countdown后面的0 1 2 3 4好像是变成了参数而不是函数名字的组成部分了,在调试台上试就是这样的。
请问版主这种函数调用和解释在那本书里可以学到,我现在看的是c++ primer plus 第6版这本书。这本书没你说的这种函数调用。

[此贴子已经被作者于2019-5-5 18:49编辑过]

2019-05-05 18:05
zhulei1978
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:53
帖 子:1351
专家分:1200
注 册:2006-12-17
收藏
得分:0 
没执行完,countdown(n-1);这一句后面有个断点

其实我就是改变社会风气,提高少女素质,刺激电影市道,提高年轻人内涵,玉树临风,风度翩翩的整蛊专家,我名叫古晶,英文名叫JingKoo!
2019-05-07 07:30
zhulei1978
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:53
帖 子:1351
专家分:1200
注 册:2006-12-17
收藏
得分:0 
函数嵌套

其实我就是改变社会风气,提高少女素质,刺激电影市道,提高年轻人内涵,玉树临风,风度翩翩的整蛊专家,我名叫古晶,英文名叫JingKoo!
2019-05-07 07:31
tt138
Rank: 2
等 级:论坛游民
威 望:1
帖 子:16
专家分:17
注 册:2019-4-19
收藏
得分:0 
查明白了,5楼这个程序是摸板元编程程序。这种原始的元编程程序是在编译阶段运行完成的。
这种元编程的变量是固定的,也就是说没有变量,因为在编译阶段完成运行, countdown4()中的4就已经把运行中的
数字固定了,除非修改程序,否则这个4无法在运行阶段再赋值。前面的函数都是摸板自己生成的。
5楼这么解释其实是拿递归解释递归,没说明什么问题,根本没说明递归为什么先执行一半然后执行回程。
5楼的摸板程序也是每个函数执行一半就执行另外一个去了,全部执行一半后再跑回来执行剩下的一半,
根本没解释这是怎么一回事情。
7楼说的“没执行完,countdown(n-1);这一句后面有个断点”,就是要你解释这个断点是怎么一回事情。
8楼说的“函数嵌套”不知道是什么,我还没学到那里去。听名字好像能蛮高级。
我问的是递归为什么会有回程?像弹簧一样怎么压下去就会怎么弹回来,一般的函数就没有回程。
是编译器系统里面设置的还是内存本身或指针本身释放回归形成的?
如果是编译器搞的,就没什么解释的,编译阶段完成运行的程序,我觉得是懒汉或为了搞钱才玩的方法,一点都不好玩。
如果是内存管理或指针之类机器自己搞的,这个好玩,那么摸板之类的编程估计就可以用于高级智能了,
我是这么想的,所以才问这个问题。




[此贴子已经被作者于2019-5-9 08:15编辑过]

2019-05-09 08:04
Jonny0201
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:52
帖 子:488
专家分:2603
注 册:2016-11-7
收藏
得分:0 
你搞错了, 这只不过是简单的函数递归而已, 和什么模板元编程一点关系都没有
递归回来的根本原因就是前面的代码只是执行了一部分而已, 后面的没有执行完, 所以还要回去执行后面的代码
rjsp 的代码已经很好的解释了为什么后面会回来, 你只需要跟着他的代码一步一步走或者一步一步调试即可
另外, 以后遇到递归, 手动把代码展开, 不关是用笔还是用键盘, 手动地把代码展开, 像 5 楼一样就能很快理解了

最后, 我帮你把代码改成了模板元编程的写法
程序代码:
#include <iostream>

using std::cout;
using std::endl;

template <typename T, T Value>
struct value_holder {
    using type = T;
    constexpr static inline auto value {Value};
};
template <bool, typename T, typename>
struct conditional {
    using type = T;
};
template <typename T, typename U>
struct conditional<false, T, U> {
    using type = U;
};
template <typename T>
struct if_ {
    constexpr static inline auto value {T::value > 0};
};
template <typename T>
struct decrease {
    using type = value_holder<typename T::type, T::value - 1>;
};
/* 放入正数后, 给出新的数字必定等于 0; 否则, 返回原来的数字 */
template <typename T, template <typename ...> typename Decrease, template <typename...> typename If>
struct count_down {
public:
    using type = typename conditional<If<T>::value, count_down<typename Decrease<T>::type, Decrease, If>, T>::type;
    constexpr static inline auto value {type::value};
};
int main(int argc, char *argv[]) {
    cout << count_down<value_holder<int, 1022 /* 这个正数只要不超过编译器的能力, 可以无限大, 最终结果都是 0 */>, decrease, if_>::value;
}
收到的鲜花
  • tt1382019-05-15 21:10 送鲜花  1朵  
2019-05-13 02:10
快速回复:c++ 递归的问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.026221 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved