C语言字符串库函数和内存库函数

发布时间:2023-01-26 23:00

简介:

介绍字符串库函数:strlenstrcpystrcmpstrstrstrcat;

内存库函数:memmove,memcpy的使用和模拟实现

#1:strlen

具体用法:

C语言字符串库函数和内存库函数_第1张图片

从图中可得知,这是一个获取字符串长度的库函数;从传过来的地址开始依次往后遍历,直到遇到‘\0'时停止;返回遍历过的次数,但不包括’\0‘本身;最后返回一个无符号的整形。

需要注意的是,函数需要的是一个字符串,而字符串中自动会创建一个’\0‘,但如果用的时候创建的是一个由单个组成的字符数组,strlen就没用了,因为没用’\0‘,致使strlen只能不停往后遍历,直到找到’\0‘为止。

得到这些内容我们就可以着手实现它了;

具体实现

三种方法实现

#include
#include
#include
//模拟实现库函数strlen(求字符串长度)
//1.参数部分需要一个被查找字符串首元素的地址
//2.从首元素开始,遇到'\0'时停止,返回一个无符号整形

//#计数器方式实现
size_t my_strlen1(const char* ptr)//const修饰,指针指向的内容不可被修改
{
	assert(ptr != NULL);//断言assert不为空指针
	int count = 0;
	while (*ptr!='\0')
	{
		ptr++;
		count++;
	}
	return count;

}
//#递归方式实现
 
 size_t my_strlen2(const char* ptr)//const修饰,指针指向的内容不可被修改
{
	assert(ptr != NULL);//断言assert不为空指针
	if (*ptr != '\0')
	{
		return 1 + my_strlen2(ptr + 1);
	}
	else
	{
		return 0;
	}
}
 //1+"bcdef"
 //1+1+"cdef"
 //1+1+1+"def"
 //...
//指针-指针方式实现
 size_t my_strlen3(const char* ptr)//const修饰,指针指向的内容不可被修改
{
	assert(ptr != NULL);//断言assert不为空指针
	char* str = ptr;
	while (*ptr)
	{
		ptr++;
	}
	return ptr - str;//指针减指针得出它俩间元素的个数,且它们指向同一块空间
}
int main()
{
	char arr[20] = "abcdef\0ghijklmn";
	size_t ret=my_strlen3(arr);
	printf("%d\n", (int)ret);
	return 0;
}

#2.strcpy

C语言字符串库函数和内存库函数_第2张图片

具体作用:将源字符串的内容拷贝到目标字符串内

 函数应该有两个参数,第一个destination为被拷贝的字符串首元素地址,第二个source为源字符串首元素地址,返回类型应该为字符串首元素地址。

需要注意的是被拷贝的字符串必须要有足够的空间接受源字符串,否则程序会越界访问。

具体实现

//模拟实现strcpy(字符串拷贝)
//1.参数部分需要两个地址,返回类型是目标的首元素地址
//2.解引用指针,依次拷贝,在源字符串遇到‘\0’时停止
//3.目标首元素的地址创建一个变量存储,返回它
//#在目标空间不够源字符串拷贝时,依然会打印,但程序会报错(总结来说就是愣头青)
char* my_strcpy(char* arr1,const char* arr2)
{
	assert(arr1 && arr2);
	char* str = arr1;
	while (*arr1++ = *arr2++)
	{
		;
	}
	return str;
}
int main()
{
	char arr1[20] = { 0 };
	char arr2[] = "hello bit";
	//printf("%s", strcpy(arr1, arr2));
	printf("%s\n",my_strcpy(arr1, arr2));
	return 0;
}

#3.strcat

C语言字符串库函数和内存库函数_第3张图片

 具体作用:

函数参数跟strcpy一样,但strcat是在目标字符串后,从’\0‘直接进行追加,并且替换掉’\0‘;

在源字符串遇到’\0‘时停止,’\0‘会追加。

具体实现:

//模拟实现strcat(字符串追加)
//1.参数是两个字符串的首元素地址,返回类型是目标的首元素地址
//2.找到目标字符串‘\0’的位置,源字符串再依次追加,源字符串遇到‘\0’是停止,执行返回
//
char* my_strcat( char* arr1, const char* arr2)
{
	assert(arr1 && arr2);
	char* str = arr1;
	while (*arr1)
	{
		arr1++;
	}
	while (*arr2)
	{
		*arr1 = *arr2;
		arr1++;
		arr2++;
	}
	return str;
}
int main()
{
	char arr1[20] = "hi! ";
	char arr2[] = "hello bit";
	printf("%s\n", my_strcat(arr1, arr2));
	return 0;
}

#4.strcmp

C语言字符串库函数和内存库函数_第4张图片

 具体作用:

比较两个字符串大小,以一个字符的ASCII码进行比较,相等则往后继续,小于则返回<0的数,大于则返回>0的数;当找到一个小于或大于的数时后面不进行比较。

具体实现:


//模拟实现库函数strcmp
int my_strcmp(const char* arr1, const char* arr2)
{
	assert(arr1 && arr2);
	while (*arr1 == *arr2)
	{
		if (*arr1 == '\0')
		{
			return 0;
		}
		arr1++;
		arr2++;
	}
	return *arr1 - *arr2;
}

int main()
{
	char arr1[] = "abcdefg";
	char arr2[] = "abcdac";
	int ret = my_strcmp(arr1, arr2);
	if (ret == 0)
	{
		printf("相等\n");
	}
	else if (ret < 0)
	{
		printf("<\n");
	}
	else if (ret > 0)
	{
		printf(">\n");
	}
	return 0;
}

#5.strstr

C语言字符串库函数和内存库函数_第5张图片

具体作用:

在字符串1中找字符串2,找到就返回第一次出现的地址,找不到就返回空指针。

具体实现:

char* my_strstr(const char* arr1, const char* arr2)
{
	const char* s1 = arr1;
	const char* s2 = arr2;
	const char* cur = arr1;
	assert(arr1 && arr2);
	while (*cur)
	{
		s2 = arr2;
		s1 = cur;
		while (*s1 && *s2 && (*s1 == *s2))
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return (char*)cur;
		}
		cur++;
	}
	return NULL;
}
int main()
{
	char arr1[] = "abbbc";
	char arr2[] = "bbc";
	char* ret = my_strstr(arr1, arr2);
	if (ret == NULL)
	{
		printf("找不到\n");
	}
	else
	{
		printf("%s", ret);
	}
	return 0;
}

#6.memcpy

C语言字符串库函数和内存库函数_第6张图片

具体作用: 

将源字符串的具体字节数num拷贝到目标字符串中,不检测是不是有’\0‘存在

为避免溢出,目标参数和参数所指向的数组的大小应至少为 num 字节,并且不应重叠

参数为两个void*,一个int,返回类型为void*;

具体实现 :

//模拟实现memcpy(内存拷贝)
//一个字节一个字节移动,循环num次
//强转为char*,再+i
void* my_memcpy(void* ptr1, void* ptr2, int num)
{
	assert(ptr1 && ptr2);
	void* ret = ptr1;
	while (num--)
	{
		*(char*)ptr1 = *(char*)ptr2;
		ptr1 = (char*)ptr1 + 1;//ptr1原来类型为void*
		ptr2 = (char*)ptr2 + 1;
	}
	return ret;
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9 };
	int arr2[] = { 3,3,3,3,3,3,3,3 };
	my_memcpy(arr1, arr2, 20);
	int sz = sizeof(arr1) / sizeof(arr1[0]);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

   #7.memmove

C语言字符串库函数和内存库函数_第7张图片

 具体作用:

memcpy的升级版,现在可以拷贝自身的数了

参数为两个void*,一个int,返回类型为void*;

具体实现:

//模拟实现memmove
//循环num次
//在ptr1小于ptr2时,从前向后拷贝;ptr1>ptr2时,从后向前拷贝
void* my_memmove(void* ptr1, void* ptr2, int num)
{
	assert(ptr1 && ptr2);
	void* ret = ptr1;
	if (ptr1 < ptr2)
	{
		while (num--)
		{
			*(char*)ptr1 = *(char*)ptr2;
			ptr1 = (char*)ptr1 + 1;//ptr1原来类型为void*
			ptr2 = (char*)ptr2 + 1;
		}
	}
	else
	{
		while (num--)
		{
			*((char*)ptr1 + num) = *((char*)ptr2 + num);
		}
	}
	return ret;
}
int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9 };
	int arr2[] = { 3,3,3,3,3,3,3,3 };
	my_memmove(arr1, arr1+4, 20);
	int sz = sizeof(arr1) / sizeof(arr1[0]);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

C语言字符串库函数和内存库函数_第8张图片

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号