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

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

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);
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值