函数原型
void* memcpy( void* _Dst, void const* _Src, size_t _Size); // 内存拷贝
void* memmove( void* _Dst, void const* _Src, size_t _Size); // 内存移动
void* memset(void* _Dst, int _Val, size_t _Size); // 内存设置
int memcmp(void const* _Buf1, void const* _Buf2, size_t _Size) // 内存比较void* memchr(void const* _Buf, int _Val, size_t _MaxCount) // 内存查找
概述
这些函数在字符串操作函数的那一节提到的函数好像都是类似的。
区别在于,那块的函数主要用于操作字符串,这里的函数用于操作内存。简单来说就是可以操作任何类型,因为其参数接受的是void*类型的(任何类型的指针都可以隐式转换为void*类型的指针)
如果你是要操作字符串,那么可以使用相应的字符串操作函数,如果是要操作别的类型,那么可以使用这里提到的函数。
函数使用
memcpy() -- 拷贝的内存不能重叠
- void* memcpy( void* _Dst, void const* _Src, size_t _Size);
将src指向的位置的size个字节拷贝到dst指向的位置,返回一个指向dst空间的指针。
例子: int buffer[] = { 1,23,4,5,6 };
int dst[20];
memcpy(dst, buffer, 5 * sizeof(int));例子中,我们将buffer所指空间的20字节(也就是5个整数,因为一个int占四个字节)拷贝到了dst所指向的空间。
我们通过第三个参数来指定内存拷贝多少个字节,如果我们指向拷贝1个整数,一个整数是4字节,那么我们在第三个参数传入4,这样就只会拷贝一个整数了。(建议使用sizeof来计算对应类型占有的字节数,比如: sizeof(int));
注意:
1. 拷贝的两个内存不能重叠。2. 你需要保证dst指向的空间能够放得下你指定的拷贝的字节数,而且也应该保证指定的字节数不能超过src所拥有的字节数。
memmove()-- 拷贝的内存可以重叠
- void* memmove( void* _Dst, void const* _Src, size_t _Size);
memmove()函数的用法和memcpy()的用法基本是相同的,区别在于: memmove()允许移动(拷贝)的内存有重叠,memcpy()不允许。
例子: 删除字符串中的指定子串:
char buffer[] = "abcdefgh";
memmove(buffer+2,buffer+5,4);
printf("%s\n", buffer);例子中,我们要删除某个特定的子串,此处为cde,我们可以将e后面的字符串复制或者移动到c的位置,这样cde这个串就被覆盖了,所以函数中我们需要传入指向c位置的指指针,指向f位置的指针。
这两个都是字符指针,也就是说传入的都是buffer存放字符串的子串,但你细看会发现以c位置开始的子串明显包含以f位置开始的子串。所以我们操作的这两个子串出现位置重叠,所以我们使用memmove()来实现。
此时注意: 我们将f后面的字符移动到前面的时候,应该多移动一位,因为移动的是字符串,还有一个字符串结束符。-- 当然移动别的类型就不用考虑这个问题了
- 因为mommove()通常无法使用某些机器所提供的特殊字节-字符串处理指令来实现,所以它可能比memcpy()要慢。
所以,如果拷贝的内存存在重叠,那就使用memmove(),没有那么就使用memcpy()
memset()
- void* memset(void* _Dst, int _Val, size_t _Size);
此函数可以将一个空间的对应字节都设置为某个数值,返回一个指向dst对应空间的指针
例: int buffer[50];
memset(buffer, 0, 50 * sizeof(int));例子中,我们定义了一个50个元素的整形数组,我们要将其全部的元素设置为0,这样我们可以遍历这个数组一个一个设置。
当然,我们也可以选择使用memset()函数,将指定字节的位置设置成指定的值。
显然,使用memset()函数更加的方便。所以,上面我们将buffer所有的位置都设置为0。这也是memset()常用的场景: 将一块数组空间设置为特定的值。
为什么50*sizeof(int)就是全部的空间呢?
数组有50个整形数据,一个整形数据占有的字节数为4,我们使用sizeof(int)得到,所以50个整形占有的字节为50*sizeof(int),也就是全部数据。
注意:
1. 还是要注意,指定的字节数不能超过dst的空间字节数。
memcmp()
- int memcmp(void const* _Buf1, void const* _Buf2, size_t _Size)
用于比较对应字节的两份数据,返回比较结果: 如果buf1<buf2返回-1,buf1>buf2返回1,buf1=buf2返回0。
例: 和strcmp的用法是类似的,只是这个函数可以比较任意类型
int buf1[] = { 1,10,3 };
int buf2[] = { 4,5,6 };
int ret = memcmp(buf1, buf2, 3 * sizeof(int)); // 返回-1
printf("%d\n", ret);从前往后比较,只要比较出结果就返回。虽然buf1的第二个数比buf2的大,但是在第一个数据的时候就已经比较出结果,所以直接返回了。
注意:
1. 还是要注意,指定的字节数不能超过dst的空间字节数。
memchr() -- 可用于查找某个正数是否存在与整形数组中
- void* memchr(void const* _Buf, int _Val, size_t _MaxCount)
此函数和strchr()的用法类似,只是可以指定字节数了,也可以找整数类型了,找到返回指向目标元素所在位置的指针,没有找到返回NULL。
例: int buf1[] = { 1,10,3 };
int* ret = (int*)memchr(buf1, 10, 12);
printf("%d\n", *ret); // 输出10
注意:
1. 还是要注意,指定的字节数不能超过dst的空间字节数。