C语言-----函数功能实现---strcpy&&strlen

1.函数功能参数介绍

该函数的功能就是把一个字符串复制到另外的一个数组,包括'\0';

2.首先我们要明确字符串的复制也是包括最后的\0的;

void mystrcpy(char* dest, char* src)
{
	
	while (*src!='\0')
	{
		*dest = *src;
		dest++;
		src++;
	}
	*dest = *src;
	
}
int main()
{
	char arr1[] = "hello world";
	char arr2[20] = "xxxxxxxxxxxxxx";
	mystrcpy(arr2, arr1);
	printf("%s\n", arr2);
	return 0;
}

跳出while循环之后就会把末尾的\0实现复制;

3.继续优化----------------------------------------------

我们阅读上面的资料就会发现strcpy的返回值就是dest,所以我们利用这个就可以继续优化代码,

让自定义函数返回dest,因为循环的过程中dest发生了变化所以我们定义一个新的指针变量记录dest

的初始位置,并且作为返回值;

char* mystrcpy(char* dest, char* src)
{
	char* ret = dest;
	while (*src != '\0')
	{
		*dest = *src;
		dest++;
		src++;
	}
	*dest = *src;
	return ret;
}
int main()
{
	char arr1[] = "hello world";
	char arr2[20] = "xxxxxxxxxxxxxx";
	
	printf("%s\n", mystrcpy(arr2, arr1));
	return 0;
}

4.代码继续优化

像这样,如果有空指针,我们可以使用assert断言,这样就可以准确的找出程序的出错位置,如果没有断言,我们就无法知道自己错在哪里,但是断言会准确的告诉我们出错的位置,提高代码的可读性,但是记住需要包含assert.h的头文件;

#include<assert.h>
char* mystrcpy(char* dest, char* src)
{
	char* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	while (*src != '\0')
	{
		*dest = *src;
		dest++;
		src++;
	}
	*dest = *src;
	return ret;
}
int main()
{
	char arr1[] = "hello world";
	char arr2[20] = "xxxxxxxxxxxxxx";
	char* p = NULL;
	mystrcpy(p, arr1);
	printf("%s\n", arr2);
	return 0;
}

5.继续优化

#include<assert.h>
char* mystrcpy(char* dest, char* src)
{
	char* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	while (*dest++ = *src++)//到\0的时候就会结束,因为\0的ascii是0
	{
		;//空语句
	}
	return ret;
}
int main()
{
	char arr1[] = "hello world";
	char arr2[20] = "xxxxxxxxxxxxxx";
	char* p = mystrcpy(arr2, arr1);
	printf("%s\n", arr2);
	return 0;
}

这里面让while循环语句里面的内容变得更加精炼,把其实现的部分放到了判断条件里面;

解引用操作符不会作用于加加,这样指针继续向后移动,当到\0的时候,控制循环条件的赋值语句的结果是\0的ASCII值,也就是0,这样就结束了循环;

6.到这里,函数的功能就已经实现了,但是会发现少了参数里的const,补上就好了,其实const的作用就是让我们无法改变修饰的值;

char* mystrcpy(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	while (*src != '\0')
	{
		*dest = *src;
		dest++;
		src++;
	}
	*dest = *src;
	return ret;
}
int main()
{
	char arr1[] = "hello world";
	char arr2[20] = "xxxxxxxxxxxxxx";
	char* p = NULL;
	mystrcpy(arr2, arr1);
	printf("%s\n", arr2);
	return 0;
}

7.const修饰指针变量

(1)当const放在*左边的时候,指针指向的内容不能改变,指针本身可以改变;

(2)当const放在*右边的时候,指针本身不可以改变,但是指向的内容可以改变;

(3)当*的左右都有const,无论是指针本身还是指向的内容,都无法改变;

8.明白const的作用,再回到函数的功能实现,就会发现const的必要性,如果在过程里面,我们把*src和*dest的位置颠倒了,程序就会报错,因为这样改变了*src,加上const可以让我们的程序变得更加严谨。

9.利用const,assert我们实现strlen的功能

#include<assert.h>
size_t mystrlen(const char* p)
{
	assert(p != NULL);
	char* left = p;
	size_t count = 0;
	while (*p)
	{
		p++;
		count++;
	}
	return count;
}
int main()
{
	char arr[] = "wj djekd kedkkk";
	size_t len = mystrlen(arr);
	printf("%zd\n", len);
	//%u打印无符号数的,和%zd差别不大;
	return 0;
}

资料显示,strlen的返回类型是size_t,这个是位sizeof设计的一个类型,是unsigned int 或者是

unsigned long类型,所以我们把len,count都设计为size_t类型。

相关推荐
数据小小爬虫22 分钟前
如何用Java爬虫“偷窥”淘宝商品类目API的返回值
java·爬虫·php
暮春二十四23 分钟前
关于用postman调用接口成功但是使用Java代码调用却失败的问题
java·测试工具·postman
java小吕布1 小时前
Java中Properties的使用详解
java·开发语言·后端
Black蜡笔小新1 小时前
网页直播/点播播放器EasyPlayer.js播放器OffscreenCanvas这个特性是否需要特殊的环境和硬件支持
前端·javascript·html
爱吃土豆的程序员1 小时前
在oracle官网下载资源显示400 Bad Request Request Header Or Cookie Too Large 解决办法
java·数据库·oracle·cookie
尚学教辅学习资料1 小时前
基于微信小程序的电商平台+LW示例参考
java·微信小程序·小程序·毕业设计·springboot·电商平台
尘浮生1 小时前
Java项目实战II基于微信小程序的移动学习平台的设计与实现(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·学习·微信小程序·小程序
秦jh_2 小时前
【Linux】多线程(概念,控制)
linux·运维·前端
2401_857610032 小时前
Spring Boot框架:电商系统的技术优势
java·spring boot·后端
蜗牛快跑2132 小时前
面向对象编程 vs 函数式编程
前端·函数式编程·面向对象编程