关于递归调用,函数指针,数组,字符串的一些理解
2015-07-16 12:43
736 查看
先放自己写得一段代码和问题,下面给出自己想出来的解答,有不对的地方请指正,谢谢。
#include <stdio.h>
void reverse( const char *const sPtr );
int main( void )
{
char sentence[ 80 ];
printf( "Enter a line of text: " );
gets( sentence );
printf( "\nThe line printed backward is:\n" );
reverse( sentence );
return 0;
}
void reverse( const char *const sPtr )
{
if( sPtr[0]=='\0' ){
return;
}
else {
reverse( &sPtr[ 1 ] );
putchar( sPtr[ 0 ] );
}
}
比如我输入We!输出的是 !eW,但过程理解不了,是否可以详细讲解下这个递归过程,谢谢。
通过别人的解释后自己的理解:
说一下自己这2天的理解,不对的请指正,谢谢。
比如We!这个字符串,数组元素分别是‘W’, ‘e’, ‘!’, ‘\0’,方便讨论编号1,2,3,4。
步骤一(第一次调用函数):先检测1号‘W’(第一次调用里的sPtr[ 0 ]),发现不是'\0',
步骤二:进入else,调用函数(第二次调用函数),这时sPtr[ 1 ]是2号,是第二次调用函数的实参所存的数据。/* sPtr[ 1 ]是指针的下标表示法,等同于*( sPtr+1 ),sPtr[ 0 ]等同于*sPtr,之前把sPtr[
1 ]理解成了数组的第二个元素,sPtr[ 0 ]理解成了数组的第一个元素,导致整个函数无法理解。*/
步骤三:检测2号,发现不是'\0',
步骤四:进入else,调用函数(第三次调用函数),这时sPtr[ 1 ]是即3号,是函数的实参所存的数据。
步骤五:检测3号,发现不是'\0',
步骤六:进入else,调用函数(第四次调用函数),这时sPtr[ 1 ]是即4号,是函数的实参所存的数据。发现是‘\0’,return回第三次调用,
步骤七:return回第三次调用,运行putchar( sPtr[ 0 ] );此时第三次调用函数的sPtr[ 0 ]正好是3号'!',打印出来。/*此处应该再写一个return就更好理解了,当然不写也可以,遇到函数最后的大括号也自动return*/
步骤八:return回第二次调用,运行putchar( sPtr[ 0 ] );此时第二次调用函数的sPtr[ 0 ]正好是2号'e',打印出来。
步骤九:return回第一次调用,运行putchar( sPtr[ 0 ] );此时第一次调用函数的sPtr[ 0 ]正好是1号'W',打印出来。
步骤十:return会main函数。
就如薛非在问题评论写得,如果sPtr[ 0 ]写成*sPtr,&sPtr[ 1 ]写成sPtr+1,这个函数就好理解多了
另外,在函数中&sPtr[
1 ],是作为参数用在reverse函数里面的。所以,它虽然指向的是2的地址,但是代表的却是除去首字符以外的整个字符串,也就是234。
这个是可以测试的。修改以上else部分代码:
else {
printf("%s\n",&sPtr[ 1 ]);
reverse( &sPtr[ 1 ] );
putchar( sPtr[ 0 ] );
}
可以测试&sPtr[ 1 ]代表的确实是后面一串字符而不是一个字符。
详细请见链接:http://www.zhihu.com/question/32228601
#include <stdio.h>
void reverse( const char *const sPtr );
int main( void )
{
char sentence[ 80 ];
printf( "Enter a line of text: " );
gets( sentence );
printf( "\nThe line printed backward is:\n" );
reverse( sentence );
return 0;
}
void reverse( const char *const sPtr )
{
if( sPtr[0]=='\0' ){
return;
}
else {
reverse( &sPtr[ 1 ] );
putchar( sPtr[ 0 ] );
}
}
比如我输入We!输出的是 !eW,但过程理解不了,是否可以详细讲解下这个递归过程,谢谢。
通过别人的解释后自己的理解:
说一下自己这2天的理解,不对的请指正,谢谢。
比如We!这个字符串,数组元素分别是‘W’, ‘e’, ‘!’, ‘\0’,方便讨论编号1,2,3,4。
步骤一(第一次调用函数):先检测1号‘W’(第一次调用里的sPtr[ 0 ]),发现不是'\0',
步骤二:进入else,调用函数(第二次调用函数),这时sPtr[ 1 ]是2号,是第二次调用函数的实参所存的数据。/* sPtr[ 1 ]是指针的下标表示法,等同于*( sPtr+1 ),sPtr[ 0 ]等同于*sPtr,之前把sPtr[
1 ]理解成了数组的第二个元素,sPtr[ 0 ]理解成了数组的第一个元素,导致整个函数无法理解。*/
步骤三:检测2号,发现不是'\0',
步骤四:进入else,调用函数(第三次调用函数),这时sPtr[ 1 ]是即3号,是函数的实参所存的数据。
步骤五:检测3号,发现不是'\0',
步骤六:进入else,调用函数(第四次调用函数),这时sPtr[ 1 ]是即4号,是函数的实参所存的数据。发现是‘\0’,return回第三次调用,
步骤七:return回第三次调用,运行putchar( sPtr[ 0 ] );此时第三次调用函数的sPtr[ 0 ]正好是3号'!',打印出来。/*此处应该再写一个return就更好理解了,当然不写也可以,遇到函数最后的大括号也自动return*/
步骤八:return回第二次调用,运行putchar( sPtr[ 0 ] );此时第二次调用函数的sPtr[ 0 ]正好是2号'e',打印出来。
步骤九:return回第一次调用,运行putchar( sPtr[ 0 ] );此时第一次调用函数的sPtr[ 0 ]正好是1号'W',打印出来。
步骤十:return会main函数。
就如薛非在问题评论写得,如果sPtr[ 0 ]写成*sPtr,&sPtr[ 1 ]写成sPtr+1,这个函数就好理解多了
另外,在函数中&sPtr[
1 ],是作为参数用在reverse函数里面的。所以,它虽然指向的是2的地址,但是代表的却是除去首字符以外的整个字符串,也就是234。
这个是可以测试的。修改以上else部分代码:
else {
printf("%s\n",&sPtr[ 1 ]);
reverse( &sPtr[ 1 ] );
putchar( sPtr[ 0 ] );
}
可以测试&sPtr[ 1 ]代表的确实是后面一串字符而不是一个字符。
详细请见链接:http://www.zhihu.com/question/32228601
相关文章推荐
- 关于指针的一些事情
- 数据库链接字符串查询网站
- Flex字符串比较 还有Flex字符串操作
- ruby 数组使用教程
- Ruby中的数组和散列表的使用详解
- C#实现AddRange为数组添加多个元素的方法
- C#动态调整数组大小的方法
- Ruby中创建字符串的一些技巧小结
- ASP下经常用的字符串等函数参考资料
- 将字符串小写转大写并延时输出的批处理代码
- 将字符串转换成System.Drawing.Color类型的方法
- Lua和C语言的交互详解
- 详解Lua中的数组概念知识
- Lua源码中字符串类型的实现
- Lua性能优化技巧(四):关于字符串
- 字符串聚合函数(去除重复值)
- Perl中的列表和数组学习笔记
- 总结的5个C#字符串操作方法分享
- sqlserver中求字符串中汉字的个数的sql语句
- sql server字符串非空判断实现方法