C语言内存函数的介绍

C语言中有许多有意思而且非常实用的内存函数,我们一起来看一下这些函数是怎么使用和实现的

strtok

这个函数应该是C语言中不常见到的一个函数,我给大家介绍介绍它的功能是什么,以及他是如何使用的。

char * strtok ( char * str, const char * delimiters );

这是这个函数的参数和返回类型,这个函数可以切割一个字符串,把一个字符串分成若干份,而切割的地方放入’\0’,这么说比较抽象,我用代码给大家演示

char arr[] = "jronggui@bitedu.com";
	char buf[200] = { 0 };
	strcpy(buf, arr);

	const char* p = "@.";
	char* str = strtok(buf, p);
	printf("%s\n", str);

	str = strtok(NULL, p);
	printf("%s\n", str);

	str = strtok(NULL, p);
	printf("%s\n", str);

我们如果切割arr就会使arr字符数组发生变化,所以我们可以复制到buf数组中,而字符指针p中放的是分隔字符,只要遇到’@‘或者’.‘就会把它换成’\0’。第一次调用函数第一个参数传的是数组首元素的地址,第二个参数是存放标记字符的指针p,返回的是切割这个字符串的起始位置,这个函数会记住第一次遇见分隔字符后面的位置,方便下次调用的时候可以找到,同理第二次调用之后函数也会记住第三次调用的起始位置,一直到这个字符串真正结束,结束之后会返回空指针。
我们看一下这个代码的运行结果:
在这里插入图片描述
而这个代码是有缺陷的,如果这个字符数组很长,我们怎么知道有几个分隔符呢?所以我们需要改进一下

int main() {
	char arr[] = "jronggui@bitedu.com";
	char buf[200] = { 0 };
	strcpy(buf, arr);

	const char* p = "@.";
	/*char* str = strtok(buf, p);
	printf("%s\n", str);

	str = strtok(NULL, p);
	printf("%s\n", str);

	str = strtok(NULL, p);
	printf("%s\n", str);*/

	char* str = NULL;
	for (str = strtok(buf, p); str != NULL; str = strtok(NULL, p)) {
		printf("%s\n", str);
	}
	return 0;
}

在这里插入图片描述
这样只要这个函数返回的不为空指针,那就一直打印。

strerror

这个函数的功能是把错误代码转换成信息,例如:
在这里插入图片描述

memcpy和memmove的区别

memcpy和memmove本质上都是复制一个空间内的元素到另一个空间,但是二者是有一些区别的,我们可以先看一下memcpy和memmove怎么使用的,然后我们可以模仿实现一下。

memcpy

void * memcpy ( void * destination, const void * source, size_t num );

这是memcpy函数的参数和返回类型,传进去两个指针分别给destination和source,还有一个size_t(unsigned int)类型的数字。
这个函数怎么用呢?就是把source这个指针指向的内容复制num个字节到起始位置为destination指向的空间内。
我们可以看一下代码:

	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = {0};
	memcpy(arr2, arr1, 20);
	int i = 0;
	for (i = 0; i < 10; i++) {
		printf("%d ", arr2[i]);
	}

在这里插入图片描述
这个函数我们也可以模拟实现一下:

#include <assert.h>
void* my_mecopy(void* dest, void* src, size_t num) {
	void* ret = dest;
	assert(dest);
	assert(src);
	while (num--) {
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}

memmove

这个函数跟momcpy使用方式是一样的

//这是参数列表和返回值
void * memmove ( void * destination, const void * source, size_t num );
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = {0};
	int i = 0;
	memmove(arr2, arr1, 20);
	for (i = 0; i < 10; i++) {
		printf("%d ", arr2[i]);
	}

在这里插入图片描述

区别

memcpy和memmove这两个函数看起来使用方式没有区别,而且都可以实现复制,但是真的是一样的吗?答案是否定的。
我们可以做一个小小的测试,让数组元素自己给自己复制,例如:

	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = {0};
	my_mecopy(arr1+2, arr1, 20);
	int i = 0;
	for (i = 0; i < 10; i++) {
		printf("%d ", arr1[i]);
	}

在这里插入图片描述
这个复制就出问题了,这个问题当然也是看编译器对函数的实现,有的会出错,而有的不会,这时候就要格外小心了。

而memmove用数组自己给自己复制的结果就不会出错了,我们看看代码:

	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int i = 0;
	memmove(arr1+2, arr1, 20);
	for (i = 0; i < 10; i++) {
		printf("%d ", arr1[i]);
	}
	return 0;

在这里插入图片描述
所以用的时候还是尽量用memmove就可以。

这是几个简单的库函数的使用和一些实现,希望对您有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值