实现字符串函数和内存操作函数

明白库函数的实现过程,能帮助我们去更好的使用和理解它们。下面就对于字符串函数:strlen(),strcpy(),strcmp(),strstr(),内存函数:memcpy(),memmove(),进行实现~

一、字符串函数

1.求字符串的实际长度:strlen()

库函数中是这样声明的:

代码实现:

#include<stdio.h>
#include<windows.h>

size_t myStrlen(const char* str)
{
    //if语句校验合法性
	if (str == NULL){
		return 0;
	}
	size_t len = 0;
	while (str[len]!= '\0'){
		len++;
	}
	return len;
}
int main()
{
	char str[] = "hello world";
	printf("%d\n",myStrlen(str));
	system("pause");
	return 0;
}

运行结果:

注意:

①size_t表示无符号整型

const修饰的变量一般不能改变,为了防止我们在求字符串的长度过程中,修改了字符串的内容,所以需要const来修饰,确保我们的字符串安然无恙~

③在进行计算长度之前,一定要校验,检验字符串的合法性

2.字符串拷贝函数:strcpy()

库函数中的声明:

代码实现:

#include<stdio.h>
#include<windows.h>

char* myStrcpy(char* dest, const char* src)
{
    //if语句校验合法性
	if (dest == NULL || src == NULL){
		return NULL;
	}
	char* pdest = dest;
	const char* psrc = src;
	while (*psrc != '\0'){
		*pdest = *psrc;
		pdest++;
		psrc++;
	}
	*pdest = '\0';
	return dest;
}
int main()
{
	char dest[1024] = "hello";
	char src[] = "heihei";
	printf("%s\n", myStrcpy(dest, src));
	system("pause");
	return 0;
}

运行结果:

需要注意的是:除了要进行字符串合法性地检验之外,因为我们在进行拷贝,所以要保证目的地的空间足够

3.字符串比较函数:strcmp()

库函数中的声明:

思路:如果str1<str2则返回小于0的数,如:-1

           如果str1=str2则返回0

           如果str1>str2则返回大于0的数,如:1

代码实现:

#include<stdio.h>
#include<windows.h>
#include<assert.h>

int myStrcmp(const char*str1, const char* str2)
{
    //assert检验字符串的合法性
	assert(str1!= NULL&&str2!=NULL);
	while (*str1 != '\0'&&*str2 != '\0'){
		if (*str1<*str2){
			return -1;
		}else if (*str1 > *str2){
			return 1;
		}else{
			str1++;
			str2++;
		}
	}
    //str1<str2,相减之后得到的是小于0的数
    //str1=str2,相减之后得到0
    //str1>str2,相减之后得到的是大于0的数
	return *str1 - *str2;
}
int main()
{
	const char str1[] = "helloapple";
	const char str2[] = "helloworld";
	printf("%d\n", myStrcmp(str1, str2));
	system("pause");
	return 0;
}

运行结果:

注意:除了可以使用if语句进行合法性的校验,我们还可以使用assert(),括号内的逻辑如果为0,那么直接中断程序~它的头文件为#include<assert.h>

4.字符串查找子串的起始位置函数:strstr()

库函数中的声明:

思路:

这个函数相对复杂一点,定义三个指针,black指针指向dest的首元素,依次向后遍历,如果遍历到最后还没有找到,那就代表dest中没有和src匹配的子串。定义red指针,指向black,定义psrc指向src的首元素,我们在比较的时候,如果red和psrc不相等,那么black指针往后挪,我们的red还是重新指向black,psrc重新指向src;如果red和psrc相等,那么继续使用red比较是否和src中剩余字符也相等,直到src都遍历完了,那么就说明找到了,返回black所指位置即可。

代码实现:

#include<stdio.h>
#include<windows.h>

char* myStrstr(const char* dest, const char* src)
{
    //if语句校验合法性
	if (dest == NULL || src == NULL){
		return NULL;
	}
	const char* black= dest;
	while (*black != '\0'){
		const char* red = black;
		const char* psrc = src;
		while (*red == *psrc && *red != '\0' && *psrc != '\0'){
			red++;
			psrc++;
		}
		if (*psrc == '\0'){
			return black;
		}
		black++;
	}
	return NULL;
}
int main()
{
	char dest[] = "helloworld";
	printf("%s\n", myStrstr(dest, "ow"));
	system("pause");
	return 0;
}

运行结果:

注意校验合法性~

二、内存操作函数

1.内存拷贝函数:memcpy()

库函数中的声明:

在写内存拷贝函数的时候,我想出了一个很傻的问题,不是有字符串拷贝了吗,还要这个干嘛,然后很快意识到,字符串函拷贝只针对字符串,而内存拷贝函数它的返回值为void*,也就代表了它可以拷贝任何类型的数据!!为了能够拷贝任何类型,我们需要一个字节一个字节拷贝,char类型刚好占1个字节,所以在函数中,我们把(void *)强转为(char*)类型的,size_t num是我们要拷贝的字节数。

代码实现:

#include<stdio.h>
#include<windows.h>
#include<assert.h>

void* myMemcpy(void* dest, const void* src,size_t num)
{
    //assert校验合法性
	assert(dest!= NULL&&src!=NULL);
	char* pdest = (char*)dest;
	const char* psrc = (char*)src;
	for (size_t i = 0; i < num; i++){
		*(pdest+i) = *(psrc+i);
	}
	return dest;
}
int main()
{
	int dest1[4] = {1,0,2,4};
	const int src1[4] = { 6, 6, 6, 6 };
	char dest2[1024] = "hei";
	const char src2[1024] = "helloworld";
	for (int i = 0; i < (sizeof(dest1) / sizeof(dest1[0])); i++){
		printf("%d", dest1[i]);
	}
	printf("\n%s\n", myMemcpy(dest2, src2, sizeof(src2)));
	system("pause");
	return 0;
}

运行结果:

注意校验合法性~~

2.内存拷贝函数:memmove()

库函数中的声明:

和memcpy的差别就是memmove函数处理的源内存块目标内存块可以重叠的。如果源空间和目标空间出现重叠,就得使用memmove函数处理。

如果目标内存块在源内存块中,那么就要反向拷贝(反向拷贝就是将source中的最后一个位置拷贝给destination中的最后一个位置,依次从后往前拷贝,如果不晓得为什么,可以在纸上稍微比划一下),反之呢,就正常地执行上面我们的memcpy就行啦~

代码实现:

#include<stdio.h>
#include<windows.h>
#include<assert.h>

void* myMemcpy(void* dest, const void* src,size_t num)
{
	assert(dest!= NULL&&src!=NULL);
	char* pdest = (char*)dest;
	const char* psrc = (char*)src;
	for (size_t i = 0; i < num; i++){
		*(pdest+i) = *(psrc+i);
	}
	return dest;
}

void* myMemmove(void* dest, const void* src, size_t num)
{
	assert(dest != NULL&&src != NULL);
	char* pdest = (char*)dest;
	const char* psrc = (char*)src;
	if (pdest>=psrc&&pdest<=psrc){
		for (size_t i =num-1; i >= 0; i--){
			*(pdest + i) = *(psrc + i);
		}
		return dest;
	}
	return myMemcpy(dest, src, num);
}
int main()
{
	char str[] = "hello world ni hao shi jie..";
	printf("%s\n", myMemmove(str+11,str+12,18));
	system("pause");
	return 0;
}

运行结果:

注意校验合法性~~~

bye~~~~~~

猜你喜欢

转载自blog.csdn.net/weixin_43939602/article/details/110014263