reverse_string(char *string)递归实现字符串翻转 和对“++”操作的一些分析

来源:互联网 发布:1553b数据总线 编辑:程序博客网 时间:2024/06/02 14:49

函数实现之前 先看一个例子

void fun(int i){if (i > 0)fun(i / 2);printf("%d ",i);}int main(void){fun(10);return 0;}

输出结果是什么?



这是《c语言深度剖析》中的一个例子  在这个例子中 printf(“%d ”,i);语句是fun函数的一部分 必定执行一次fun函数,就要打印一次。函数展开过程如下:


void fun(int i){//fun(i/2);if (i > 0){if (i / 2 > 0){if (i / 4 > 0){....}printf("%d ",i/4);}printf("%d ", i / 2);}printf("%d ", i );}

是不是清晰很多?


同样的思路 来完成reverse_string(char *string)函数   代码如下:


/*编写一个函数reverse_string(char * string)(递归实现)*/#include<stdio.h>#include<math.h>void reverse_string(char *string){if (*(++string) != '\0')reverse_string(string);printf("%c",*(string-1));}int main(){char *a = "abcde";reverse_string(a);printf("\n");return 0;}



在这个程序的编写中 出现了很多意想不到的问题  看看下面的写法

void reverse_string(char *string){if (*string != '\0')reverse_string(string++);if (*string != '\0')printf("%c", *string);}int main(){char *a = "abcde";reverse_string(a);printf("\n");return 0;}

输出结果是什么?




来分析一下:在实现递归的过程中 我们使用了这样一句代码:

reverse_string(string++);

后置++   的操作方式 是首先将值进行相应的操作   然后进行自加

string一开始指向的是字符串的首地址处  可以狭义的理解为&a的地方  然后reverse_string(string);string++;++操作后string此时指向的狭义的理解为&b的地方(狭义的理解),但是函数的调用reverse_string(string)还是操作&a的地址  相当于死循环     程序不断地压栈   导致栈溢出 。


将程序改成前置++  结果又会怎么样:

#include<stdio.h>#include<math.h>void reverse_string(char *string){if (*string != '\0')reverse_string(++string);if (*string != '\0')printf("%c", *string);}int main(){char *a = "abcde";reverse_string(a);printf("\n");return 0;}




前置++  首先进行的自加操作 另string指向字符串中&b的地方(狭义理解)  因此输出的结果中没有a


结束了吗?这个程序仅仅是将一个字符串常量进行翻转输出,在内存中字符串并没有改变


因此对程序进行如下修改:


#include <stdio.h>void reverse_string(char * str){int n = 0;   //创建一个变量来记录字符串的长度char *p = str;   //  str并不会发生改变char tmp;while (*p++ != '\0'){n++;}if (n > 1){tmp = str[0];str[0] = str[n - 1];str[n - 1] = '\0';reverse_string(str + 1);str[n - 1] = tmp;}}void main(){char string[] = "abcd";//char* a  为字符串常量 在静态区 具有只读属性 不可修改reverse_string(string);printf("%s\n", string);}




3 0
原创粉丝点击