目录
一、前言
二、内存操作函数
memcpy
memmove
memset函数
memcmp
三、共勉
在大家初学C语言的时候肯定会碰到对内存的了解,但是估计大家会和我一样,觉得这一部分不是很重要,所以草草就跳过去了,其实这里的内存函数是最重要的,特别是在大家以后找工作的时候这里也是面试官最喜欢问的知识点。为了搞清楚这里的东西,专门花了一早上的时间去总结,希望对大家有用!!!!
知识点1:
memcpy()函数的头文件 :#include
memcpy()函数的声明:
其中 void * destination 表示目标函数 const void *source 表示原函数
size_num 表示字节数
memcpy()函数的功能:可以对任何类型的数组进行任意字节的拷贝
代码演示:
#include
#include int main() { int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 }; int arr2[20] = { 0 }; memcpy(arr2, arr1, 20);//注意第3个参数的单位是字节 // 结果 arr2 : 1 2 3 4 5 return 0; } 图解:
我们发现正如我们所料,向arr2数组传送了 20个字节,5个数据。
知识点2:
大家是否会考虑,对于strcpy()函数再拷贝字符串时,如果遇到 '\0' 他会停止拷贝,那么思考memcpy()函数在拷贝字符串时遇到 '\0' 是否会停止。
代码演示:
#include
#include int main() { char arr1[] = "abc\0def"; char arr2[20] = { 0 }; memcpy(arr2, arr1, 6); printf("%s\n", arr2); return 0; } 进行图解演示:
结果发现:memcpy在拷贝数据时与strcpy和strncpy不同的是memcpy遇到 '\0' 是不会停止拷贝到。
知识点 3:
注意: C语言标准规定memcpy()函数只拷贝不重叠的数据。
知识点4:
memcpy()函数的模拟:#include
#include #include #include void* my_memcpy(void* dst, const void* src, size_t count) { void* ret = dst; assert(dst); //不为空指针 assert(src); /* * copy from lower addresses to higher addresses */ while (count--) // 传出count次字节 { *(char*)dst = *(char*)src; // 因为每次只传递一个字节 需要将指针类型变为(char *) dst = (char*)dst + 1; src = (char*)src + 1; } return(ret); } int main() { int a[] = {1,2,3,4,5,6,7,8,9,10}; int a1[10] = { 0 }; my_memcpy(a1, a, 20); for (int i = 0; i < 10; i++) { printf("%d ", a1[i]); } return 0; }
知识点1:
memmove()函数的头文件: #include
memmove()函数的声明:
其中 void * destination 表示目标函数 const void *source 表示原函数
size_num 表示字节数
memmove()函数的功能:可以对任何类型的数组进行任意字节的拷贝。
注意:此时的memmmove 可以进行重叠拷贝
代码演示:
#include
#include int main() { int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 }; memcpy(arr1 + 2, arr1, 20); // 拷贝5个字符过去,从数组的下标3开始 return 0; } 图解:
从上图可以看见,memmove 实现了自己拷贝自己
知识点2:
memmove()函数的模拟实现
#include
#include #include #include void* my_memmove(void* dst, const void* src, size_t count) { void* ret = dst; assert(dst); //不为空指针 assert(src); /* * copy from lower addresses to higher addresses */ if (dst < src) // 区域1 从前向后拷贝 { while (count--) // 传出count次字节 { *(char*)dst = *(char*)src; // 因为每次只传递一个字节 需要将指针类型变为(char *) dst = (char*)dst + 1; src = (char*)src + 1; } } else //区域二 从后向前拷贝 { while (count--) { *((char*)dst + count) = *((char*)src + count); } } return(ret); } int main() { int a[] = { 1,2,3,4,5,6,7,8,9,10 }; int a1[10] = { 0 }; my_memmove(a1, a, 20); for (int i = 0; i < 10; i++) { printf("%d ", a1[i]); } return 0; }
知识点1:
memset()函数的头文件:#include
memset()函数的声明:
memset()函数的作用:
将数组的元素,统一设置成一个元素。
代码演示:
#include
#include int main() { int arr[10] = { 0 }; memset(arr, 1, 20); return 0; } 大家估计此时会想到结果因该给前5个数据赋值了 1 。我们看看图解
我们发现此时出现了很大的数据,发现了错误,我们正确的应该怎么写呢?
#include
#include int main() { int arr[10] = { 0 }; int i = 0; for (i = 0; i < 10; i++) { memset(&arr[i], 1, 1); } return 0; } 图解:
此时正确了。
知识点1:
memcmp()函数的头文件:#include
memcmp()函数的声明:
memcmp函数的应用:这个函数非常类似于 strcmp()函数,只不过是按字节去比较
返回值:
代码演示:
#include
#include #include #include int main() { int a[] = { 1,2,3,4,5 }; // 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 int b[] = { 1,2,3,0,0 }; // 01 00 00 00 02 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 int ret=memcmp(a, b, 12); // 比较前3个数 int rat = memcmp(a, b, 16); // 比较前4个数 printf("%d\n", ret); // 0 相同就为0 printf("%d\n", rat); // 1 数组 a 大于 数组 b 就输出 1 否则就输出 -1 return 0; }
以下就是我对C语言内存函数的理解,如果有不懂和发现问题的小伙伴,请在评论区说出来哦,同时我还会继续更新对qsort()函数的理解,请持续关注我哦!!!!!