c语言如何定义递归函数 c语言如何定义递归函数数据

C语言 编写递归函数标个记号准备上传对大神的源码分析 。好了 , 我分析了上楼大神的代码实现,具体参考他的代码 , 分享下 。注:可以看看《算法精解》Kyle Loudon著或者《数据结构》 主编 安训国 他们说的堆栈原理 。
#include stdio.h
char* dg(char* instr, char* outstr, char* outstr2)
{
if (*instr == 0)
{
*outstr = 0;
return outstr2;
}
*(outstr1) = *instr;
outstr = dg(instr1, outstr2, outstr2);
/* 下两句一直不执行,直到outstr = dg(instr5, outstr10, outstr2)返回后才执行 , 其后不断执行后三句!*/
*outstr = *instr - 32;
return outstr2;
}
int main()
{
char buf[50];
dg("aybdx", buf, buf);
puts(buf);
return 0;
}
c语言递归函数递归函数:
编程语言中 , 函数Func(Type a,……)直接或间接调用函数本身,则该函数称为递归函数 。递归函数不能定义为内联函数 。
在数学上,关于递归函数的定义如下:对于某一函数f(x),其定义域是集合A,那么若对于A集合中的某一个值X0 , 其函数值f(x0)由f(f(x0))决定,那么就称f(x)为递归函数 。
函数介绍:
在数理逻辑和计算机科学中,递归函数或μ-递归函数是一类从自然数到自然数的函数,它是在某种直觉意义上是"可计算的"。事实上,在可计算性理论中证明了递归函数精确的是图灵机的可计算函数 。递归函数有关于原始递归函数 , 并且它们的归纳定义(见下)建造在原始递归函数之上 。但是,不是所有递归函数都是原始递归函数 — 最著名的这种函数是阿克曼函数 。
其他等价的函数类是λ-递归函数和马尔可夫算法可计算的函数 。
例子:
//代码1
void func()
{
//...
if(...)
func();
else
//...
}
条件:
一个含直接或间接调用本函数语句的函数被称之为递归函数,在上面的例子中能够看出,它必须满足以下两个条件:
1) 在每一次调用自己时,必须是(在某种意义上)更接近于解;
2) 必须有一个终止处理或计算的准则 。
梵塔的递归函数:
//C
void hanoi(int n,char x,char y,char z)
{
if(n==1)
move(x,1,z);
else
{
hanoi(n-1,x,z,y);
move(x,n,z);
hanoi(n-1,y,x,z);
}
}
C语言:递归函数的定义疑惑几乎每一本c
语言基础的书都讲到了函数递归的问题,但是初学者仍然容易在这个地方犯错误 。先看看下面的例子:
void
fun(int
i)
{
if
(i0)
{
fun(i/2);
}
printf("%d\n",i);
}
intmain()
{
fun(10);
return
0;
}
问:输出结果是什么?
这是我上课时,一个学生问我的问题 。他不明白为什么输出的结果会是这样:
1
2
5
10
他认为应该输出0 。因为当i
小于或等于0
时递归调用结束,然后执行printf
函数打印i
的值 。
这就是典型的没明白什么是递归 。其实很简单,printf("%d\n",i);语句是fun
函数的一部分,肯定执行一次fun
函数,就要打印一行 。怎么可能只打印一次呢?关键就是不明白怎么展开递归函数 。展开过程如下:
void
fun(int
i)
{
if
(i0)
{
//fun(i/2);
if(i/20)
{
if(i/40)
{

}
printf("%d\n",i/4);
}
printf("%d\n",i/2);
}
printf("%d\n",i);
}
这样一展开 , 是不是清晰多了?其实递归本身并没有什么难处,关键是其展开过程别弄错了 。
二、不使用任何变量编写strlen
函数
看到这里,也许有人会说,strlen
函数这么简单,有什么好讨论的 。是的 , 我相信你能熟练应用这个函数,也相信你能轻易的写出这个函数 。但是如果我把要求提高一些呢:
不允许调用库函数,也不允许使用任何全局或局部变量编写intmy_strlen
(char
*strdest);似乎问题就没有那么简单了吧?这个问题曾经在网络上讨论的比较热烈,我几乎是全程“观战”,差点也忍不住手痒了 。不过因为我的解决办法在我看到帖子时已经有人提出了 , 所以作罢 。
解决这个问题的办法由好几种 , 比如嵌套有编语言 。因为嵌套汇编一般只在嵌入式底层开发中用到 , 所以本书就不打算讨论c
语言嵌套汇编的知识了 。有兴趣的读者,可以查找相关资料 。
也许有的读者想到了用递归函数来解决这个问题 。是的,你应该想得到,因为我把这个问题放在讲解函数递归的时候讨论 。既然已经有了思路,这个问题就很简单了 。代码如下:
intmy_strlen(
const
char*
strdest
)
{
assert(null
!=
strdest);
if
('\0'
==
*strdest)
{
return
0;
}
else
{
return
(1
my_strlen(strdest));
}
}
第一步:用assert
宏做入口校验 。
第二步:确定参数传递过来的地址上的内存存储的是否为'\0' 。如果是,表明这是一个空字符串,或者是字符串的结束标志 。
第三步:如果参数传递过来的地址上的内存不为'\0',则说明这个地址上的内存上存储的是一个字符 。既然这个地址上存储了一个字符,那就计数为1,然后将地址加1
个char类型元素的大小 , 然后再调用函数本身 。如此循环,当地址加到字符串的结束标志符'\0'时,递归停止 。
当然,同样是利用递归,还有人写出了更加简洁的代码:
intmy_strlen(
const
char*
strdest
)
{
return
*strdest?1 strlen(strdest 1):0;
}
这里很巧妙的利用了问号表达式,但是没有做参数入口校验 , 同时用*strdest
来代替('\0'==
*strdest)也不是很好 。所以,这种写法虽然很简洁,但不符合我们前面所讲的编码规范 。可以改写一下:
intmy_strlen(
const
char*
strdest
)
{
assert(null
!=
strdest);
return
('\0'
!=
*strdest)?(1 my_strlen(strdest 1)):0;
}
上面的问题利用函数递归的特性就轻易的搞定了,也就是说每调用一遍my_strlen
函数 , 其实只判断了一个字节上的内容 。但是,如果传入的字符串很长的话,就需要连续多次函数调用,而函数调用的开销比循环来说要大得多,所以,递归的效率很低,递归的深度太大甚至可能出现错误(比如栈溢出) 。所以,平时写代码,不到万不得已,尽量不要用递归 。即便是要用递归,也要注意递归的层次不要太深,防止出现栈溢出的错误;同时递归的停止条件一定要正确,否则,递归可能没完没了 。
请用C语言编写递归函数//循环实现
#includestdio.h
int main()
{
int n, t = 0;
scanf("%d", n);
if(n=0)return 0;
else
while(n){
t = t * 10n % 10;
n /= 10;
}
printf("%d", t);
return 0;
}
简单修改一下就可以变递归了 。代码如下
#includestdio.h
int fanzhuan(int n,int t){
t = t * 10n % 10;
n /= 10;
if(n0)return fanzhuan(n,t);
return t;
}
int main()
{
int n, t = 0;
scanf("%d", n);
if(n=0)return 0;
else t=fanzhuan(n,t);
printf("%d", t);
return 0;
}
用C语言编写一个递归函数?int findf( int n ){
int a,b,c;
b = n % 2;
c = 0;
if ( n4){
if (b==c){
a=findf( n-1 )findf( n-3 );
}
else{
a=findf( n-2 )findf( n-4 );
}
return a;
}
else if ( n0){
return -1;
}
else{
return 1;
}
}
【c语言如何定义递归函数 c语言如何定义递归函数数据】关于c语言如何定义递归函数和c语言如何定义递归函数数据的介绍到此就结束了 , 不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站 。

    推荐阅读