目录
目录详情
1.strtok
2.strerror
编辑3.内存操作函数
3.1 memcpy
3.2memmove
3.3内存比较函数memcmp
3.4内存设置函数memset
3.5一些其他的内存分类函数
4.金句省身
char* strtok(char*str,const char*sep);
sep参数是个字符串,定义了用作分隔符的字符集合;
str是一个指定的字符串,它里面包含了0个或者以上的sep字符串中的字符;
strtok函数的功能:
1.strtok函数会找到str中下一个含有sep字符串中的字符的位置,并将其修改为'\0',并且返回一个指向这个标记的指针(注意strtok函数操作会改变原字符串,所以需要拷贝后再使用)
2.strtok函数的第一个参数不为NULL时,strtok函数在str中找到它的第一个标记,strtok函数会将它在原字符串的位置保存下来
3.strtok函数的第一个参数若为0,则strtok会在str中从保存的位置开始遍历字符串寻找下一个标记的位置;
4.如果字符串不存在标记,则返回空指针NULL
下面,我们来用具体的代码来解释其功能,
char* strerror(int num);
功能:返回错误码所对应的错误信息。
请看下面的代码和运行结果:
C语言在调用函数库失败时,会将错误信息存放在一个叫errno的变量中,当我们想知道具体的错误信息时,就可以将errno所代表的错误码翻译成错误信息打印出来。
拓展一下:
C语言中有打开文件的操作,需要用到指针,注意需要包含头文件errno.h
顺便的,我们这还有一个perror函数,可以直接打印其错误的原因
memcpy函数的功能是将src的前count个字节拷贝到dest数组中去。
其中void可以看成是任意类型,函数的设计者考虑到未来不知道我们会拷贝什么类型的数据,所以设置其参数类型为void*,这个是通用类型指针,可以接收任意类型的指针类型的数据。
下面,我们来自己实现一下这个函数的功能:
我们不难写出这样的函数
但是,这样会出现漏洞,如果我们的目的数组就是src的一部分呢?比如把src的前半部分拷贝到后半部分,如果这两部分有重叠,势必会导致循环出现问题,这个时候我们就要想办法来避免出现这个错误,这个时候,就要请出我们的memmove函数了
我们可以看到,memmove函数和memcpy函数在参数类型上完全一致,我们来试一下刚才的重叠的情况
显然,实验是成功的,那么,我们能不能把我们上面写的memcpy函数改造一下,让他拥有memmove函数的功能呢?话不多说,我们开整
首先,要相对有重叠的子串进行区间拷贝,我们需要考虑到底是左边的区间拷贝到右边还是右边的区间拷贝到左边,因为我们在拷贝的过程中,如果方法不得当,就会出现重叠的部分被覆盖导致出错,所以我们要分情况讨论,即到底是从前往后拷贝还是从后往前拷贝,那么紧接着下一个问题又来了,如何判断,这个就相对简单了,这里提供一中方法,判断目的子串和原子串的首地址,通过首地址的大小比较来确定是哪一种情况,想到这里,不难写出如下的代码:
#include
using namespace std;
void* my_memmove(void* dest, const void* src, size_t num)
{
assert(dest && src);
void* ret = dest;
//从前面拷贝到后面,也即dest的地址在src前面
if (src > dest)
{
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
//后面拷贝到前面,对于src和dest,我们选择从数组的最后一个元素拷贝到第一个元素
else
{
while (num--)
{
*((char*)dest+num) = *((char*)src+num);//找到最后一个元素转换为单个字节逐字节复制拷贝
}
}
return ret;
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[20] = { 0 };
for (int i = 0; i < 10; i++)
arr2[i] = arr[i];//注意这里不能用strcpy,那是字符串操作函数,这里是数组
//把arr数组中的前五个元素拷贝到原来的3,4,5,6,7的位置上去,即覆盖原来的值
my_memmove(arr+2, arr, 20);
for (int i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
//把arr数组的2,3,4,5,6拷贝到原来的1,2,3,4,5的位置上去
my_memmove(arr2, arr2+1, 20);
for (int i = 0; i < 10; i++)
{
printf("%d ", arr2[i]);
}
printf("\n");
return 0;
}
输出结果如下:
其返回值类型如下
在逐字节进行比较的时候要考虑大小端存储带来的影响
具体的就不在多介绍了,毕竟函数功能比较简单。
memset函数是以字节为单位进行设置的,所以要传入的参数是字节数不是数据个数。
路遥说,每个人都有一个觉醒期,但是觉醒的早晚决定着一个人的命运,人生最可悲的事情莫过于胸怀大志却又虚度着光阴,平凡普通却又习惯拖延。学历不高又不怒力,不满意自己,又自我安慰。你一定要努力,因为如果有一天,当你接触到优秀的人的时候,你是否拥有与之匹配的分量,你会发现那些优秀的人,阳光且温柔自律且上进,各方面都很优秀,不要整天动不动就emo,在崩溃的世界中前行是成年人的基本素养。