我是靠谱客的博主 平常蜜粉,这篇文章主要介绍内存函数的介绍,现在分享给大家,希望可以做个参考。

前言:

本博客向大家介绍四个内存函数:memcpy(内存拷贝)、memmove(内存移动)、memcmp(内存比较)、memset(内存设置)

memcpy函数的介绍及其应用:

  1. num表示要拷贝几个字节

  2. 遇到''他并不会停下来

  3. 如果destination和source有任何的重叠,复制的结果都是未定义的

  4. 不管是什么数据类型,它都能来;strcpy只能针对字符串

  5. VS2019编译器中memcpy可以实现重叠拷贝(尝试一下就可以发现),不能保证所有的memcpy都能做到VS2019里的一样可以实现重叠拷贝

  6. C语言规定:
       memcpy只需要不重叠的拷贝就ok
       memmove是需要实现重叠内存的拷贝

  7. memcpy的头文件是:#include <string.h>


memcpy的应用:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h> #include <string.h> int main() { int arr1[] = { 1,2,3,4,5,6,7,8,9,10 }; int arr2[10] = { 0 }; memcpy(arr2, arr1, 20);//拷贝5个整型进去,因为num的单位是字节,所以此时num的值是5*4=20 float str1[] = { 1.0f,2.0f,3.0f,4.0f };//如果不写f编译器会把他当成double类型的数据 float str2[5] = { 0.0 }; memcpy(str2, str1, 8); return 0; }

效果:

遇到'',并不会停止拷贝:


memcpy的模拟实现:

memcpy函数的设计:void* memcpy(void* destination, const void* source, size_t num);

思路:

格式:既然是模拟,格式应该尽量一模一样。memcpy函数可以接收任何类型的数据,所以模拟的时候要设计成void* 类型。另外,memcpy函数在C语言中是不处理重叠的数据的,因此本次模拟实现也无法处理模拟重叠的数据,即只能处理src与dest无重叠部分的情况

拷贝:因为memcpy函数是以字节为单位进行拷贝的,所以我们在对数据进行处理的时候要先将其强制类型转换成char*类型,以便以字节为单位进行操作

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <stdio.h> #include <assert.h> //因为memcpy是什么数据类型都能使用的,所以两个参数不应该弄成int或者是char或者是其他的 //应该弄成void //只有void才可以接收一切的数据类型 void* my_memcpy(void* dest, void* src, size_t num) { assert(src); void* ret = dest; while (num--)//一次拷贝一个字节,要拷贝num个字节,所以是num-- { *(char*)dest = *(char*)src; //先把dest和src都强制类型转换成char类型的指针 //一方面是因为void类型的指针不能直接拿出来使用 //一方面是为了一次只拿一个字节的内容 //error的写法: //(char*)dest++; //(char*)src++; //先使用强制类型转换 //再加加 //但是此时强制类型转换已经没有用了 //相当于白费了 //error的写法: //((char*)dest)++; //((char*)src)++; //将强制类型转换及其的使用对象括起来 //使得其对强制类型转换以后的结果进行加加 //这种写法在有的编译器里能行 //但是不是所有 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[10] = { 0 }; my_memcpy(arr2, arr1, 20); int i = 0; for (i = 0; i < 10; i++) { printf("%d ", arr2[i]); } return 0; }

效果:



memmove函数的介绍及其应用:

  1. memmove和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠。如果源空间和目标空间出现重叠,就得使用memmove函数处理
  2. memmove的头文件:#include <string.h>

memmove的应用:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
include <stdio.h> #include <string.h> int main() { int arr1[] = { 1,2,3,4,5,6,7,8,9,10 }; int arr2[10] = { 0 }; memmove(arr2, arr1, 20);//拷贝5个整型进去,因为num的单位是字节,所以此时num的值是5*4=20 float str1[] = { 1.0f,2.0f,3.0f,4.0f };//如果不写f编译器会把他当成double类型的数据 float str2[5] = { 0.0 }; memmove(str2, str1, 8); return 0; }

效果:


memmove的模拟实现:

memmove函数的设计:void* memmove( void * destination, const void * source,size_t num);

思路:memmove函数比memcpy函数多处理重叠拷贝的情况(dest和src有重叠的部分)

 画图把所有的情况分析清楚,然后结合上面memcpy函数的模拟实现来改良优化即可。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <stdio.h> #include <assert.h> void* my_memmove(void* dest, void* src, size_t num) { assert(src); void* ret = dest; if (dest < src) { while (num--)//从前向后的 { *(char*)dest = *(char*)src; dest = (char*)dest + 1; src = (char*)src + 1; } } else//后到前 { while (num--) { *((char*)dest + num) = *((char*)src + num); } } return ret; } int main() { int arr1[] = { 1,2,3,4,5,6,7,8,9,10 }; int arr2[10] = { 0 }; my_memmove(arr1+2, arr1, 20); int i = 0; for (i = 0; i < 10; i++) { printf("%d ", arr1[i]); } return 0; }

效果:


memcmp函数的介绍及其应用:

memcmp函数的设计:int memcmp(const void* ptr1, const void* ptr2, size_t num);

  1. 比较的是ptr1和ptr2指针开始的num个字节(注意num的单位是字节哦)
  2. ptr1<ptr2--->返回一个小于零的数;ptr1>ptr2--->返回一个大于零的数;ptr1==ptr2--->返回0
  3. void*又暗示着参数可以是任意类型
  4. strncmp只能比较字符串的大小;而memcmp可以比较任意类型
  5. memcmp的头文件是:#include <string.h>

memcmp的应用:

复制代码
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h> #include <string.h> int main() { int arr[] = { 1,2,3,4,5 }; int str[] = { 1,2,3,7 }; int ret = memcmp(arr, str, 16); printf("%dn", ret); return 0; }

效果:



memset函数的介绍及其应用:

memset函数的设计:void* memset(void *ptr, int value,size_t num);

  1. 内存设置:设置ptr(要设置的内存块)处的内存,将其设成value值,num个字节
  2. memset的头文件是:#include <string.h>

memset的应用:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h> int main() { int arr[] = { 1,2,3,4,5 }; memset(arr, 0, 12); //也可以通过调试来看 //调试可以更加直观地观察到改变的是字节 int i = 0; for (i = 0; i < 5; i++) { printf("%d ", arr[i]); } return 0; }

效果:



最后

以上就是平常蜜粉最近收集整理的关于内存函数的介绍的全部内容,更多相关内存函数内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(80)

评论列表共有 0 条评论

立即
投稿
返回
顶部