目录
前言
真别学计算机,你会后悔。
一、题目
不包含字符串头文件,手搓代码实现字符串的复制功能。
二、分析
我们之前学习了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++程序设计与实验课名师宋桂琴吧。敝人不才,今天早上十点起来连学带写写了五个小时才整明白,真的温暖了四季。