2.字符串操作系统的实现:strcpy

目录


前言

          真别学计算机,你会后悔。


一、题目

        不包含字符串头文件,手搓代码实现字符串的复制功能。


二、分析

        我们之前学习了gets_s()函数的使用,我们继续使用其输入即可,本题的难点在于数组指针的使用,为了学习数组指针,我们不妨将我们之前写的strlen改写成函数形式。


三、代码

1.strlen的函数形式:

为了更好地理解有关指针的自定义函数,我们从较为简单的输入为指针的函数写起。

根据原题,我们可以知道我们希望返回一个整型数值,因此我们的函数类型定义为int型,我们的函数参数为两个字符数组,数组是可以直接作为函数参数的,代码实现如下:

#include<iostream>
#include<stdio.h>
using namespace std;

int strlen(char str[]);

int main()
{
	char str[30];
	gets_s(str);
	cout << "该字符串有效字符长度为:" << strlen(str) << endl;
}

int strlen(char str[])
{
	int count = 0;
	for (int i = 0;; i++)
	{
		if (str[i] >= 32 && str[i] <= 126)
			count++;
		else if (str[i] == '\0')
			break;
	}
	return count;
}

为了练习指针,我们不妨将参数改为指针类型,只能说易如反掌啊。代码实现如下:

#include<iostream>
#include<stdio.h>
using namespace std;

int strlen(char* str);//函数的声明

int main()
{
	char str[30];
	gets_s(str);
	cout << "该字符串有效字符长度为:" << strlen(str) << endl;
    //函数的调用
}

//函数的定义(宋桂琴上课问的时候其实我会,单纯是因为我是一个害羞小男孩嘻嘻)
int strlen(char* str)//这里用str的指针代替str数组传入函数
{
	int count = 0;
	for (int i = 0;; i++)
	{
		if (str[i] >= 32 && str[i] <= 126)
			count++;
		else if (str[i] == '\0')
			break;
	}
	return count;
}
2.返回数组的函数:

strlen函数只要求我们返回一个整型变量的值,当我们需要返回一个数组的时候我们直接返回数组可以吗?我们尝试下面这个代码进行简单的输入输出:

//错的别学!!试验品!!
#include<iostream>
#include<stdio.h>
using namespace std;
char* junk()
{
	char str[100] = "yjb666";
	return str;
}
int main()
{
	char* p;
	p = junk();
	cout<<p;
}
3.问题:

我们的本意是将“yjb666”这个字符串作为一个字符数组作为函数的返回值返回到主调函数的指针*p中,进而输出,但是结果却是这样的:

这是因为我们在函数中,定义局部变量char str,返回的是str的地址,而str是一个局部变量,当函数调用结束时,局部变量中数据可能已经不复存在了。换一种说法来说,也就是这个局部的变量生命周期和函数相同,当函数的调用结束后,这个变量也同时会被系统回收,于是就出现了乱码。因此,我们不可以简单的开辟一个字符数组的空间直接返回,而要在主调函数中也开辟空间,再调用函数赋值后进行输出操作。于是就有了程序的雏形:

#include<iostream>
#include<stdio.h>
using namespace std;

char* strcpy(char* str, char* copy);

int main()
{
	char str[100];
	gets_s (str);
	char copy1[100];
	cout << strcpy(str, copy1);
}

char* strcpy(char* str, char* copy)
{
	for (int i = 0; i < 100; i++)
		*(copy + i) = *(str + i);
        //利用for循环赋值使被指向的元素相等
        //详见谭浩强教材P165,str[i]与*(str+i)等价
	return copy;
}
4.润色

这个程序已经基本完成了将str字符数组的元素都赋值给copy1的操作,我们再对程序的输出进一步优化,得到了最后的结果,代码如下:


#include <stdio.h>
#include<iostream>
using namespace std;

char* define_strcpy(char* str1, const char* copy)
//这里第二个形参添加了const关键字以确保其指向内容不会被修改
{
	char* result = str1;
	while (*str1++ = *copy++)
        ;//不要忘了加一个空语句确保循环判断正常运行!!!
//这里的while语句实现了“只要copy有指向的内容就赋值”的操作,节约不必要的循环时间
	return result;
}
int main()//主调函数改动不大,更多的是优化输出
{
	char str1[99];
	char copy[99];
	cout << "请输入复制的字符串:";
	gets_s(str1);
	cout << "请输入被复制的字符串:";
	gets_s(copy);
	define_strcpy(str1, copy);
	cout << "复制后的字符串:" << endl;
	cout << str1 << endl;
	cout << copy << endl;
	return 0;
}

四、运行

1个运行示例,包含了空格,文字,数字的复制。


五、致谢

       还是继续感谢一下华南师范大学计算机学院网络工程专业C++程序设计与实验课名师宋桂琴吧。敝人不才,今天早上十点起来连学带写写了五个小时才整明白,真的温暖了四季。

  • 28
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蜜汁博哥

我是大学生,给钱

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值