C语言 字符串 内存函数介绍 模拟实现strcpy strcmp strlen strcat strncpy strncmp strncat strstr strtok memcpy memmove

1.字符串相关函数

1.1strlen

strlen函数返回字符串中\0之前出现的字符个数,不包含\0。注意点:字符串中必须有\0,strlen函数返回值无符号。
在这里插入图片描述

int main()
{
	 const char*str1 = "abcdef";
	 const char*str2 = "bbb";
	 if(strlen(str2)-strlen(str1)>0)
	 {
	 printf("str2>str1\n");
	 } 
	 else
	 {
	 printf("srt1>str2\n");
	 }
	 return 0;
}

strlen返回类型是无符号整形,3-6得到-3,-3在内存中是以补码的形式存储的,将-3解析成无符号数,得到的结果是一个非常大的正数,所以程序输出的结果是str1 > str2。

strlen模拟实现

int my_strlen(const char* p)
{
	assert(p);
	int count = 0;
	while (*p++)
	{
		count++;
	}
	return count;
}

assert的作用:确保指针不是空指针。使用时要引<assert.h>该头文件。
在这里插入图片描述

1.2strcpy

在这里插入图片描述
strcpy有两个参数,前一个是要拷贝的目的地,后一个是要拷贝的内容。使用时要注意目标空间大小必须大于等于要拷贝的字符串。拷贝时会将\0拷贝到目标空间中,必须确保目标空间可修改。模拟实现时用const修饰sour确保要拷贝的字符串不能被修改。

函数返回目标空间的地址。

模拟实现

char* my_strcpy(char* dest, const char* sour)
{
	assert(dest && sour);
	char* tmp = dest;
	while (*dest++ = *sour++)
		;
	return tmp;
}

在这里插入图片描述

1.3strcmp

在这里插入图片描述
strcmp有两个参数,就是要比较的两个字符串,如果前一个字符串大,返回大于0的数字;相等则返回0;小于则返回一个负数。
模拟实现

int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);
	while (*str1 == *str2 && *str1 && *str2)
	{
		str1++;
		str2++;
	}
	return *str1 - *str2;
}

在这里插入图片描述
在这里插入图片描述

1.4strcat

在这里插入图片描述
strcat会找到目标空间的字符串结束标志,并从结束标志开始向后拷贝要拷贝的内容。参数分别是目标空间与要拷贝的内容。返回值时目标空间的地址。注意点:目标空间必须足够大,确保能存放下要拷贝的内容

模拟实现

char* my_strcat(char* dest, const char* sour)
{
	assert(dest && sour);
	char* tmp = dest;
	while (*dest)
	{
		dest++;
	}
	while (*dest++ = *sour++)
		;
	return tmp;
}

在这里插入图片描述

1.5strstr

在这里插入图片描述
strstr会从一个字符串中寻找另一个字符串。参数分别是元字符串与要查找的字符串,找到了就返回要查找的字符串在元字符串中首次出现的地址,注意,如果元字符串中有多个要查找的字符串,strstr函数只会返回要查找的字符串首次出现的地址。

模拟实现

char* my_strstr(const char* str, const char* charset)
{
	while (*str != '\0')
	{
		char* str1 = str;
		char* str2 = charset;
		while (*str1 == *str2 && *str2 && *str1)
		{
			str1++;
			str2++;
		}
		if (*str2 == '\0')
			return str;
		else if (*str1 == '\0')
			return NULL;
		else
			str++;
	}
	return NULL;

	
}

在这里插入图片描述

在这里插入图片描述

1.6strncpy

在这里插入图片描述
参数与strcpy一样,多了一个count,count表示要拷贝的字节数。

使用
在这里插入图片描述

1.7strncat

在这里插入图片描述
与srecat一样,count指定了要在目标空间后追加的字节个数。

使用
在这里插入图片描述

1.8strncmp

在这里插入图片描述count指定了要比较的字符数
使用
在这里插入图片描述

2.内存相关函数

2.1memcpy

在这里插入图片描述
与strncpy不同的是,memcpy的参数类型为void*,为了能应用于不同的类型,使用了void接收不同类型的数据。count是要copy的字节数,函数返回目标空间的地址,类型也是void

使用memcpy函数拷贝int类型数组内容
在这里插入图片描述
模拟实现

void* my_memcpy(void* dest, void* src, size_t num)
{
	void* tmp = dest;
	while (num--)
	{
		*((char*)dest) = *((char*)src);
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return tmp;
}

在这里插入图片描述
和strcpy的模拟实现差不多,注意在两个指针自增时最好不要直接写dest++,先将dest强转成char*类型的指针,再对其加1,把这个地址赋值给dest,这是比较规范的写法。

2.2memmove

在这里插入图片描述
将arr的内容拷贝到arr+2中,也就是把1,2,3,4拷贝到3以及后面的内容中。但是从打印结果看出这样拷贝是有问题的,因为将arr1中的3改成了1之后,在arr1中3就不存在了,被1替代后拷贝的数从3变成了1。这时我们能用memmove函数
在这里插入图片描述
在这里插入图片描述
原理是memmove将要拷贝的内容从后向前拷贝了,先把4拷贝,即使后面的拷贝中4会被其它数字替代,但已经完成了拷贝。

也就是说,dest在src的前面时,我们将src的内容从前向后拷贝,dest在src的后面时,我们将src的内容从后向前拷贝。

模拟实现

void* my_memmove(void* dest, void* src, size_t num)
{
	void* tmp = dest;
	if ((char*)dest - (char*)src < 0)
	{
		while (num--)

		{
			*((char*)dest) = *((char*)src);
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
		return tmp;

	}
	else
	{
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
		}
		return tmp;
	}

}

在这里插入图片描述

2.3memset

在这里插入图片描述
将指定内存设置为你要设置的字符。函数参数有三个,dest是要设置字符(目标空间)的地址,c是你要设置的字符,count是要设置的字节数。

使用
在这里插入图片描述

2.4memcmp

在这里插入图片描述
通过内存一个字节一个字节地比较两个地址所指向的内容,buf1大于buf2返回大于0的数,返回值与strcmp相同。

使用
在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值