C语言内存函数和字符串函数(入门必看)

江河入海,知识涌动,这是我参与江海计划的第3篇。 

<一>字符串函数
1.strstr
    1.1 strstr的介绍
    1.2 strstr的模拟实现
2.strerror
    2.1 strerror的介绍
    2.2 strerror的模拟实现
<二>内存函数
3.memcpy
    2.1 memcpy的介绍
    2.2 memcpy的模拟实现
4.memmove
    2.1 memmove的介绍
    2.2 memmove的模拟实现
5.memset
    5.1 memset的介绍和注意事项
    5.2 memset的使用
6.memcmp
    5.1 memcmp的介绍和注意事项
    5.2 memcmp的使用 
c语言中还有很多库函数,等待着大家学习!   

<一>字符串函数
1.strstr
    1.1 strstr的介绍

Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.

(函数返回字符串str2在字符串str1第一次出现的位置,简单点说就是:返回地址。)

The matching process does not include the terminating null-characters, but it stops there.

(字符串的比配不包含'\0',以字符\0作为结束的标志.
    1.2 strstr的模拟实现

strstr的模拟实现
#include<assert.h>
const char* my_strstr(const char* str1,const char* str2)
{
	assert(str1 && str2);
	const char* s1 = NULL;
	const char* s2 = NULL;
	const char* cur = str1;
	if (*str2 == '\0')
		return NULL;
	while (*cur != '\0')
	{
		s1 = cur;
		s2 = str2;
		while (*s1 && *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return cur;
		cur++;
	}
}
int main()
{
	char str1[20] = "abbbcdefgd";
	char str2[20] = "bbcde";
	const char* p = my_strstr(str1, str2);
	if (p != NULL)
	{
		printf("%s\n", p);
	}
	else
	{
		printf("不存在\n");
	}
}

1.3运行结果


2.strerror
    2.1 strerror的介绍

strerror函数可以把参数部分错误码对应的错误信息的字符串地址返回.

每个不同的C语言标准库或系统的实现中规定错误码,一般是在errno.h这个头文件中说明。C语言程序启动时都会使用一个全局变量errno来记录程序的错误码,程序启动时errno为0,表示没有错误,当我们在使用标准库函数发生某种错误,将会转化为对应的错误码,错误码难理解,所以没一个错误码都有对应的信息,strerror函数可以将对应的错误信息字符串的地址返回。
    2.2 strerror的使用例子

#include<string.h>
int main()
{
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d: %s\n",i ,strerror(i));
	}
	return 0;

 }

2.3运行结果

上面可以看到0表示无错误,其他的表示不同的错误信息。
<二>内存函数
3.memcpy
    2.1 memcpy的介绍

.函数memcpy从source的位置开始从后复制num个字节的数据到destination的指定位置上。

.这个函数在遇到'\0'的时候不会停止下来。

.如果destinnation和source有任何的重叠,复制的结果不会如我们所愿。

注意:size_t num;---------->num为字节的个数,不是元素的个数。

char类型占一个字节,int占四个字节,double占八个字节。。。。。。。
    2.2 memcpy的模拟实现

#include<assert.h>
void* my_memcpy(void* destination, const void* source, size_t num)
{
	char* ret = destination;
	assert(destination && source);
	while (num--)
	{
		(*(char*)destination) = (*(char*)source);
		destination=(char*)destination+1;//(*(char*)source)++报错,强制转换是临时的,本质还是void*
		source = (char*)source + 1;
	}
	return ret;
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[20] = { 0 };
	void* r=my_memcpy(arr2, arr, 20);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ",arr2[i]);
	}
	return 0;
}

3.3运行结果

对第三点的补充认知

问题:假如我们想从3~7改为1,2,3,4,5,
即改变后的arr[10]={1,2,1,2,3,4,5,8,9,10}

我们可能会这样写代码:

void* my_memcpy(void* destination, const void* source, size_t num)
{
	char* ret = destination;
	assert(destination && source);
	while (num--)
	{
		(*(char*)destination) = (*(char*)source);
		destination=(char*)destination+1;//(*(char*)source)++报错,强制转换是临时的,本质还是void*
		source = (char*)source + 1;
	}
	return ret;
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	void* r=my_memcpy(arr+2, arr, 20);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ",arr[i]);
	}
	return 0;
}

运行结果:


4.memmove
    2.1 memmove的介绍

memmove函数具有memcpy的特点,具有唯一特性就是:memmove可以对重叠的部分进行拷贝。

.如果destination和source具有重叠的部分,切还要进行拷贝就得使用memmove函数。
    2.2 memmove的模拟实现

void* my_memmove(void* destination, const void* source, size_t num)
{
	char* ret = destination;
	assert(destination && source);
	if (destination < source)
	{
		while (num--)
		{
			(char*)destination = (char*)source;
			destination = (char*)destination + 1;
			source = (char*)source + 1;
		}
	}
	else
	{
		while (num--)
		{
			*((char*)destination+num) = *((char*)source+num);
		}
	}
	return ret;
}
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	void* r=my_memmove(arr + 2, arr, 20);
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}


5.memset
    5.1 memset的介绍和注意事项

memset用来设置内存的,将内存中的值以字节为单位设置想要设置成的内容。
    5.2 memset的使用

5.2.1对int类型的使用

#include<string.h>
int main()
{
	int a[20] = {1,2,3,4,5,6,7,8,9,10};
	memset(a, 2, 5);
	for(int i=0;i<10;i++)
	printf("%d\n", a);
	return 0;
}

修改前:

修改后:

运行结果:

十六进制(02020202)等价于十进制(33686018)

5.2.2对char的使用

内存展示:

修改前:

修改后:

可以看到是对一个字节单位进行修改的。


6.memcmp
    5.1 memcmp的介绍和注意事项

. 比较ptr1和ptr2指针指向的位置开始,向后的num个字节.

. 返回值如下


    5.2 memcmp的使用 

C语言还有很多库函数等待着大家学习,go,go,go!

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值