| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2150 人关注过本帖
标题:关于递归求自然数列和
只看楼主 加入收藏
勇敢坚毅
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2017-9-2
结帖率:0
收藏
已结贴  问题点数:20 回复次数:9 
关于递归求自然数列和
求自然数列N各位的和如N==4,sum=4+3+2+1=10;
代码如下:
 4 int main(void)
 5 {
 6    printf("fun:%d\n",func(4));
 7 }
 8
 9
 10 int func(int num)
 11 {
 12     if(num==0)
 13         return 0;
 14     return num+func(num-1);
 15 }
 
代码的运行结果是:10,这是正确的。
将第14行改为return num+func(--num);后结果输出是错误的6,这是为什么?
在棧中调用时 num-1 与 --num不是一样的吗?
求各位大神帮忙解答一下。
系统是linux:redhat 7.2
内核版本:3.10.0-327.el7.x86_64
编辑器用的是VIM
搜索更多相关主题的帖子: 递归 自然数 int num return 
2017-09-02 21:12
勇敢坚毅
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2017-9-2
收藏
得分:0 
自己顶下
2017-09-02 21:53
zghnxzdcx
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:4
帖 子:550
专家分:1176
注 册:2010-4-6
收藏
得分:7 
num+func(num-1)在num=4的时候,执行完func(num-1)之后,num值没有改变,还是4;
num+func(--num)在num=4的时候,执行完func(--num)之后,num已经变成3了,--num是先自减后调用函数
老师留的思考题,要动动脑子……


[此贴子已经被作者于2017-9-2 22:23编辑过]


你永远不可能战胜一个纯傻子,因为他会把你的智商拉到和他同一个水平,然后用他的丰富经验打败你。
2017-09-02 22:20
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9024
专家分:54030
注 册:2011-1-18
收藏
得分:7 
num+func(--num)
未定义行为
2017-09-03 17:56
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9024
专家分:54030
注 册:2011-1-18
收藏
得分:0 
以下是引用rjsp在2017-9-3 17:56:01的发言:

num+func(--num)
未定义行为

g++8.0 报
warning: operation on 'num' may be undefined

clang6.0 报
warning: unsequenced modification and access to 'num'
2017-09-04 10:53
zghnxzdcx
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:4
帖 子:550
专家分:1176
注 册:2010-4-6
收藏
得分:0 
回复 5楼 rjsp
大哥,那是递归函数里的一条语句,单独拿出来,你在逗我吗?

你永远不可能战胜一个纯傻子,因为他会把你的智商拉到和他同一个水平,然后用他的丰富经验打败你。
2017-09-04 21:52
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9024
专家分:54030
注 册:2011-1-18
收藏
得分:0 
回复 6楼 zghnxzdcx
你看不懂,但学过C或C++的别人看得懂
num+func(--num) 这个表达式属于“未定义行为”,就这么简单,有什么看不懂的呢?哦,我猜估计是不知道什么叫“未定义行为”,其它语言中确实没这概念。

程序代码:
#include <cstdio>

int func( int num )
{
    return num;
}

int main( void )
{
    int num = 0;
    int val = num+func(--num); // ------ 违反了“修改之后只许读一次”的限定
    printf( "%d\n", val );
}

无论是g++,还是clang,在编译时都会警告 num+func(--num) 这一句属于“未定义行为”
g++说的是 operation on 'num' may be undefined
clang说的是 unsequenced modification and access to 'num'
输出结果也各不相同,当然了,既然是“未定义行为”,那任何结果都没有意义。

BTW: 给有兴趣学C/C++的人介绍一下C/C++中的三种需要注意的行为

实现定义(implementation-defined)行为:
比如 char是有符合还是无符号,不同的编译器的行为不一样。

未指定(unspecified)行为:
比如 fun(a,b) 中是先求解a表达式还是b表达式,即使是同一个编译器,都可能各处不一样。

未定义(undefined)行为:
比如 ++i + ++i,编译器完全不认为有人会写出这样的代码,因此也从不考虑出现这种代码的可能。
gcc曾经就搞怪过一次,一旦代码中出现这种行为,就自动开启某个游戏。这样做是符合C/C++标准的。

总结一下:
实现定义行为:不同的编译器的行为不一样,但在同一个编译器中,可以保证一致。
未指定行为:在同一个编译器中都不能保证一致,但不管结果对错,起码有一个确定的结果。
未定义行为:连一个确定的结果都不能保证,可能输出一个错误的结果,也可能直接格式化掉你的硬盘。
2017-09-05 08:57
delphier_bc
Rank: 2
等 级:论坛游民
威 望:1
帖 子:4
专家分:17
注 册:2017-8-7
收藏
得分:7 
return num+func(num-1)
return num+func(--num)
先不考虑未定义行为的问题,我觉得这个应该涉及到运算优先级的问题吧
2017-09-06 21:47
zghnxzdcx
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:4
帖 子:550
专家分:1176
注 册:2010-4-6
收藏
得分:0 
回复 7楼 rjsp
    这的确不是正常人能写出的代码,求自然数列的和,可以用n(n+1)/2,,可以用循环,这俩都比递归效率高。
    很明显,这是老师在教++ 、 -- 运算符优先级的时候“设计”的题目。
    在这种“设计”的过程中,一般老师只考虑C语言的基础语法,而不考虑高级编译器对代码的限制。
    因为有一种东西叫做Turbo C,可以满足老师对入门学生的随意刁难……

[此贴子已经被作者于2017-9-6 23:05编辑过]


你永远不可能战胜一个纯傻子,因为他会把你的智商拉到和他同一个水平,然后用他的丰富经验打败你。
2017-09-06 22:46
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9024
专家分:54030
注 册:2011-1-18
收藏
得分:0 
回复 9楼 zghnxzdcx
num+func(--num) 中有优先级相关的内容吗?第一层只有一个加号,没有两个及以上的操作符自然不需要什么优先级,第二层前者是个变量表达式,后者是--,也只有一个操作符。
再者,优先级 是指“结合”的优先级,比如 a+b*c,因为*比+的优先级高,所以 a+b*c 等同于 a+(b*c),而非 (a+b)*c。优先级和表达式评估先后顺序无关,对于 a+(b*c),C/C++从未规定过先评估a表达式,还是先评估(b*c)表达式。

以 num+func(--num) 为例,C/C++ 从未规定过第一个num值是执行 --num 之前的值,还是之后的值。
仅仅如此也就罢了,只是输出一个不确定的值。见7楼内容,它属于大名鼎鼎的“未定义行为”!
2017-09-07 08:41
快速回复:关于递归求自然数列和
数据加载中...
 
   



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

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