栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言1. 字符串函数结尾+内存函数与它们的实现:任意类型拷贝的memcopy()+任意类型拷贝自己给自己的mymemmove()

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言1. 字符串函数结尾+内存函数与它们的实现:任意类型拷贝的memcopy()+任意类型拷贝自己给自己的mymemmove()

1. strtok():以分割符分割字符串的函数

它会直接改变字符串内容,直接以分割符切割,把分隔符换为。所以一般操作都是对临时拷贝的内容做修改。
第一次调用,strtok()必须给参数s字符串,即对谁分割,往后将S设置为NULL,每次调用成功会返回指定被分割出片段的指针,它每次分割都会记录上次分割到了哪里,即给的位置。
利用for的巧妙写法:

int main()
{
	char arr[] = "liuzheng@123.net";
	char buf[30] = { 0 };
	const char* sep = "@.";
	strcpy(buf, arr);
	char* str = NULL;
	for (str = strtok(buf, sep); str != NULL; str = strtok(NULL, sep))
	{
		printf("%sn", str);
	}
	return 0;
}

有人的疑问:它第n次调用,如何知道上次切割在哪儿,且为什么函数调用完释放了内存空间,还能找到上次的值?

它在内部创建了静态变量

2. strerror()返回错误信息库的函数

strerror(i):给不同码,对应不同错误信息
函数哪里执行出错,会把错误码放到全局变量errno错误码中,通过strerror(errno)可以拿到错误信息。

  • perror(”mystring“) 插入: 报错时会报你的字符串加系统对应错误

库中还有很多控制大小写,标点符号、图形字符的函数
putchar()打印字符 toupper()转为大写,tolower()转为小写

内存操作函数=== memcpy() 内存拷贝

· memcpy():(void* dest, const void* src, size_t count): void* 因为不知道拷贝的类型是什么,拷贝多少字节由于count参数决定
和strcpy()的区别就是这个可以拷贝任何类型,而strcpy()只能拷贝string

void* my_memcpy(void* dest, const void* src, size_t count)
{
	assert(dest && src);
	void* ret = dest;
	while (count--)
	{
		// 无类型的指针先强制转换,再解引用成char接收
		*(char*)dest = *(char*)src;
		dest = (char*)dest+1;
		src = (char*)src + 1;
	}
	return ret;
}

缺点是:不能把自己的内容拷贝给自己,因为这种实现方式,你把自己前面的字符串给后面的过程中,可能后面的字符就已经被覆盖掉了。

memmove()重叠内存拷贝,*自己拷贝给自己
  • 自己实现memmove(),主要需要考虑重叠的部分

拷贝部分dest和src位于不同位置,拷贝顺序也不同,如果全部按从前往后害怕后面需要拷贝的字符被前面的覆盖

拷贝顺序如下图示,src拷贝至dest

void* mymemmove(void* dest, const void*src, size_t count)
{
	assert(dest && src);
	void* ret = dest;
	if(dest顺序
	{
		// src前到后拷贝给dest
		while (count--)	// count是字节数,如果要拷贝4个整形,count会给20
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	// dest在src右边,即使要重合,但是重合部分是src的尾,按src -> 会让src的尾字符串丢失,按<-即可
	else
	{
		// 很巧妙的写法,不必在外面先赋值让各自指向最后
		while (count--)
		{
			*((char*)dest+count) = *((char*)src+count);
		}
	}
	return ret;
}

int main()
{
	int arr1[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	// 自己给自己赋值
	mymemmove(arr1 + 2, arr1, 20);
	int i = 0;
	int sz = sizeof(arr1) / sizeof(arr1[10]);
	for (i = 0;i
		printf("%d ", arr1[i]);
	}
	return 0;
}

注意函数中,void 任意类型的函数,返回任意类型的ret,*

memcmp():可选择字节数做字典序比较

前面一样,但是后面第二个更大,返回-1

memset():以字节为单位设置内容


查看内存情况,&arr位置前20个全设置为0,不是把数组每个元素设0,而以字节为单位设置值

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/935072.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号