本篇文章将介绍C语言中的内存函数的用法以及模拟实现,大家快搬好小板凳来听讲啦~
要介绍的内存操作函数有以下四种:
- memcpymemmovememsetmemcmp
1、memcpy
· 这个函数的功能是在缓存区之间复制字符(此字符不仅局限于char型的数据),怎么来理解呢?
· 通俗地讲,就是将缓存区的一部分数据复制到另一块地方去,跟字符串函数strcpy很想,只不过,memcpy的功能更加强大,可以对不同类型的数据进行操作。
· 话不多说,上操作!
#include#include //#include //想要使用memcpy需要包含以上两个头文件的至少一个 int main() { //使用内存函数 int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int arr2[] = {12, 23, 34, 45, 56}; memcpy(arr1, arr2, 20);//将arr2里面前20个字节的内容复制到arr1中 //打印数组arr1 int i = 0; int sz = sizeof(arr1) / sizeof(arr1[0]); for (i = 0; i < sz; i++) { printf("%d ", arr1[i]); } return 0; }
以上是使用内存函数的实例代码,运行结果如下图
· 先解释一下memcpy的使用,
void *memcpy( void *dest, const void *src, size_t count );//memcpy的定义
· 传入两个数组的地址,定义的是void*类型,这就是为什么memcpy可以处理多种类型数据的原因,只要在函数内部进行强制转换就ok,count是要进行操作的字节数,因为int是4个字节,所有20就是操作5个int元素。
· 知道了函数的使用和实现的功能,接下来咱就来自己模拟一下
#include#include void* my_memcpy(void* dest, void* src, size_t count) { assert(dest && src);//断言dest和src不是空指针,因为空指针解引用是非法的 void* ret = dest;//函数返回的是目标数组的首元素地址,因为接下来dest会发生变化,所有提前定义变量存储dest的地址 while (count--) { *((char*)dest) = *((char*)src);//强制转换为char*类型数据,进行一个字节一个字节的修改 dest = (char*)dest + 1; src = (char*)src + 1; } return ret; } int main() { int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int arr2[] = { 12, 23, 34, 45, 56 }; my_memcpy(arr1, arr2, 20); int i = 0; int sz = sizeof(arr1) / sizeof(arr1[0]); for (i = 0; i < sz; i++) { printf("%d ", arr1[i]); } return 0; }
·模拟的想法是很简单的,只要进行一个字节一个字节的访问,然后依次赋值就好啦~
2、memmove
· memmove函数实际上是对memcpy函数的进一步优化,使得函数操作的对象可以是同一个数组
上操作!
#include#include //使用memmove需要引用的头文件 int main() { int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; memmove(arr + 3, arr, 20); int i = 0; int sz = sizeof(arr) / sizeof(arr[0]); for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } return 0; }
· 以上是使用内存函数的实例代码,运行结果如下图
· memmove的参数设置和memcpy相同,只是内部函数实现有所不同
· 接下来我们自己上手实现以下,来发现memmove与memcpy有什么不一样~
#include#include void* my_memmove(void* dest, void* src, size_t count) { assert(dest && src); void* ret = dest; if (dest < src)//如果dest的地址低于src,数组从前往后进行赋值不会造成数据的提前覆盖 { while (count--) { *((char*)dest) = *((char*)src); dest = (char*)dest + 1; src = (char*)src + 1; } } else { while (count--)//如果dest的地址高于src,数组从后往前进行赋值不会造成数据的提前覆盖,用count来控制数组从最后往前一次赋值,dest和src就不用进行变化了 { *((char*)dest + count) = *((char*)src + count); } } return ret; } //思想依然是一个字节一个字节的访问,只不过对dest和src的地址高低进行了判断 int main() { int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; my_memmove(arr + 3, arr, 20); int i = 0; int sz = sizeof(arr) / sizeof(arr[0]); for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } return 0; }
3、memset
·这个函数的功能是将缓冲区的数据设定为指定字符
· 干巴巴的文字说明看着头痛,直接上操作!
#include#include int main() { char buffer[] = "This is a test of the memset function"; printf("Before: %sn", buffer); memset(buffer, '*', 4); printf("After: %sn", buffer); return 0; }
· 以上是使用内存函数的实例代码,运行结果如下图
·解释一下函数的使用
void *memset( void *dest, int c, size_t count );
· 传入要修改的数组的首地址,要修改成的数据(传入char的话就是传入它的ANSII码),操作的字节数,还是很好理解的
· 接下来,咱就继续上手模拟
#include#include void* my_memset(void* dest, int c, size_t count) { assert(dest); void* ret = dest; while (count--) { *((char*)dest) = c; dest = (char*)dest + 1; } return ret; } int main() { char buffer[] = "This is a test of the memset function"; printf("Before: %sn", buffer); my_memset(buffer, '*', 4); printf("After: %sn", buffer); return 0; }
· 这个函数的模拟相较于上两个函数更加简单~
4、memcmp
· 这个函数跟strcmp就非常相似了,不过比较的数据类型范围更广
· 上操作~
#include#include int main() { int arr1[10] = { 1,2,3,4,5,5,6,7,8,9 }; int arr2[10] = { 1,2,3,4,5,6,7,8,9,10 }; int ret = memcmp(arr1, arr2, 40); if (ret > 0) { printf("arr1数组里的数大于arr2数组里的数n"); } else if(ret==0) { printf("arr1数组里的数等于arr2数组里的数n"); } else { printf("arr1数组里的数小于arr2数组里的数n"); } return 0; }
· 以上是使用内存函数的实例代码,运行结果如下图
· 此函数的定义为
int memcmp( const void *buf1, const void *buf2, size_t count );
· 传入两个相比较数组的首元素地址,再传入要比较的字节数,然后返回一个int类型的数据
· 模拟走起!
#include#include int my_memcmp(const void* buf1, const void* buf2, size_t count) { assert(buf1 && buf2); while ((*(char*)buf1 == *(char*)buf2) && count) { count--; buf1 = (char*)buf1 + 1; buf2 = (char*)buf2 + 1; } return (*(char*)buf1 - *(char*)buf2); } int main() { int arr1[10] = { 1,2,3,4,5,5,6,7,8,9 }; int arr2[10] = { 1,2,3,4,5,6,7,8,9,10 }; int ret = my_memcmp(arr1, arr2, 40); if (ret > 0) { printf("arr1数组里的数大于arr2数组里的数n"); } else if (ret == 0) { printf("arr1数组里的数等于arr2数组里的数n"); } else { printf("arr1数组里的数小于arr2数组里的数n"); } return 0; }
· 4个内存函数的介绍与模拟就结束了,就我个人总结来讲,内存操作函数都是进行一个字节一个字节的访问,只要掌握了字节访问的方法问题就不大了~
· 欢迎各位uu的指正和建议~



