网站集群建设解决方案,上海工作,河北响应式网站建设,网站建设集约化目录
memcpy
memcpy的使用
memcpy的模拟实现
NO1.
NO2.
memcpy可否实现重叠空间的拷贝
my_memcpy
memcpy
memmove
memmove
memmove
分析
代码
memset
memset的使用
memcmp
memcmp的使用
0
0
0 今天我们继续介绍几个重要的内存操作函数。0
0
0 今天我们继续介绍几个重要的内存操作函数。
在前面一章我们学过strcpy,strcmp等字符串函数那这里我们来学习与它们功能类似的内存函数。
还是从参数返回值头文件模拟实现等方面来讲解
memcpy
memcpy - C Reference memcpy与strcpy是类似的但是strcpy仅仅用在字符串拷贝上内存中的数据不仅仅是字 符还有整型浮点型等等这里就要用到我们的memcpy
void * memcpy ( void * destination, const void * source, size_t num );
memcpy是库函数从source的位置开始向后拷贝num个字节的数据到desitination的内存位置 C语言标准值规定memcpy来实现不重叠的内存的拷贝。memcpy达到60分可以实现功能 在我们VS2022这个环境中memcpy也可以实现重叠内存的拷贝。此时memcpy达到100分头文件#includestring.h参数size_t num是拷贝的字节个数参数const void * source 是拷贝的字节的起始位置const防止source修改,void*类型参数void * destination 是拷贝到的空间的起始位置void*类型返回类型void *void*类型表示可以接收任何类型的数据但是不能 解引用 哦这个函数在遇到 \0 的时候并不会停下来。如果source和destination有任何的重叠复制的结果都是未定义的 memcpy的模拟实现
memcpy的使用
#includestdio.h
int main()
{int a[] { 0 };int b[] { 6,7,8,9,10 };//5✖4void* p memcpy(a, b, 20);int i 0;for (i 0; i 5 ;i){printf(%d , a[i]);}return 0;
} 这下无论是什么类型的数据都可以从一个空间拷贝到另外一个空间里去。
memcpy的模拟实现
#includestdio.h
#includeassert.h
void* my_memcpy(void* destination, const void* source, size_t num)//记住num是字节的个数
{assert(dest src);void* ret destination;while (num--){*((char*)destination) *((char*)source);(char*)destination (char*)destination 1;(char*)source (char*)source 1;}return ret;
}
int main()
{int a[20] { 0 };int b[] { 1,2,3,4,5 };//5✖4void* p my_memcpy(a, b, 20);int i 0;for (i 0; i 5 ;i){printf(%d , a[i]);}return 0;
} NO1.
有同学说可以直接一个整型一个整型的拷贝过去但是问题在于编写库函数的程序员并不会知道我们需要拷贝怎样的类型数据所以这里我们又可以用到回调函数当时使用的一个方法
回调函数-------
C语言之指针进阶篇3_唐棣棣的博客-CSDN博客 NO2.
*((char*)destination) *((char*)source);
(char*)destination;
(char*)source; 那有同学这样写可以吗 答当然是不可以的啦。其实关于前置和后置我们都尽量少去使用。 因为副作用很多。我们也不清楚它的能使用的情况是怎样一回事所以尽量少用。这里不能使用的原因是destination和source强制转化后再去强制转化已经失效了时destination和source已经变成void*类型的啦 (char*)destination;
(char*)source; 虽然以上写法可能可以但是会存在无法编译的问题。 还有同学问就不能直接 答当然不行。回调函数我们那篇博文我们已经讲解过 void*类型的指针变量不能解引用和 计算 --等等。 memcpy可否实现重叠空间的拷贝
当我们学习了上面memcpy的知识了有人就动了动自己的小脑袋。
memcpy真的不能实现重叠内存的拷贝吗
my_memcpy
#includestdio.h
void* my_memcpy(void* destination, const void* source, size_t num)//记住num是字节的个数
{void* ret destination;while (num--){*((char*)destination) *((char*)source);destination (char*)destination 1;source (char*)source 1;}return ret;
}
int main()
{int b[] { 1,2,3,4,5 };//把1 2 3拷贝到3 4 5void* p my_memcpy(b2, b, 12);int i 0;for (i 0; i 5 ;i){printf(%d , b[i]);}return 0;
} 那问题到底出现在那里呢 memcpy
int main()
{int b[] { 1,2,3,4,5 };//把1 2 3拷贝到3 4 5void* p memcpy(b2, b, 12);int i 0;for (i 0; i 5 ;i){printf(%d , b[i]);}return 0;
} 综上所述事实证明只是我们my_memcpy不可以。 C语言标准值规定memcpy来实现不重叠的内存的拷贝。memcpy达到60分可以实现功能 在我们VS2022这个环境中memcpy也可以实现重叠内存的拷贝。此时memcpy达到100分 C语言标准值规定memmove来实现重叠的内存拷贝。 memmove
使用memmove是否可以实现
//当然可以
int main()
{int b[] { 1,2,3,4,5 };//把1 2 3拷贝到3 4 5void* p memmove(b2, b, 12);int i 0;for (i 0; i 5 ;i){printf(%d , b[i]);}return 0;
} memmove
memmove - C Reference (cplusplus.com) void * memmove ( void * destination, const void * source, size_t num ); C语言标准值规定memcpy来实现不重叠的内存的拷贝。memcpy达到60分可以实现功能 在我们VS2022这个环境中memcpy也可以实现重叠内存的拷贝。此时memcpy达到100分 C语言标准值规定memmove来实现重叠的内存拷贝。memmove也是是库函数类似memcpy基本一致所不在详细介绍。和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。如果源空间和目标空间出现重叠就得使用memmove函数处理。memmove的模拟实现
memmove
分析 代码
memset
memset - C Reference (cplusplus.com) void * memset ( void * ptr, int value, size_t num );
memset是库函数是设置内存的是以字节为单位设置内存的头文件#includestring.h参数size_t num是设置的字节个数参数int value 是设置的字节参数void * ptr是设置的空间的起始位置void*类型返回类型void * void*类型表示可以接收任何类型的数据但是不能 解引用 哦和计算--等准确来说memset更加适合char类型的变量但是可以把整型设置全设为1注意char可以放到int里int不能放到char里
memset的使用
#includestdio.h
#includestring.h
int main()
{char arr[] tsqxgd.haha;memset(arr6, x, 3);//再次强调是3个字节printf(%s\n, arr);
} memcmp
memcmp - C Reference (cplusplus.com) int memcmp ( const void * ptr1,const void * ptr2,size_t num );
memcmp是库函数是比较内存的是以字节为单位比较内存的比较从ptr1和ptr2指针开始的num个字节头文件#includestring.h参数size_t num是设置的字节个数参数const void * ptr1 是比较的字节的起始位置const防止source修改,void*类型参数const void * ptr2 是比较的空间的起始位置void*类型 void*类型表示可以接收任何类型的数据但是不能 解引用 哦和计算--等返回类型int 返回值如下图 memcmp的使用
0
#includestdio.h
#includestring.h
int main()
{int arr1[] { 1,2,3,4,5 };int arr2[] { 1,2,3,4,6 };int ret memcmp(arr1, arr2, 20);printf(%d\n, ret);
} 0
#includestdio.h
#includestring.h
int main()
{int arr1[] { 1,2,3,4,5 };int arr2[] { 1,2,3,4,6 };int ret memcmp(arr1, arr2, 16);printf(%s\n, ret);
} 0
#includestdio.h
#includestring.h
int main()
{int arr1[] { 1,2,3,4,7 };int arr2[] { 1,2,3,4,6 };int ret memcmp(arr1, arr2,20 );printf(%d\n, ret);
}特别提醒 只是在vs2022编译器下才是01-1这样的数值 在其他编译器下可能就不是但是肯定是0 0 0这样的范围的。 ✔✔✔✔✔最后感谢大家的阅读若有错误和不足欢迎指正
我知青山不复在也知绿水难长流。
下篇博文我们总结各种函数的模拟实现。走的每一步都是算数的。
代码------→【gitee:唐棣棣 (TSQXG) - Gitee.com】
联系------→【邮箱2784139418qq.com】