内存函数,即对内存中的内容进行一定的操作,通过这种函数,我们并不会局限与数据的类型。下面大雄就为大家介绍一些常用的内存函数。
01
【memcpy() - 内存拷贝不重叠】
memcpy()指定头文件是:#include<string.h>
memcpy() 函数的声明方式如下:
void *memcpy(void *str1, const void *str2, size_t n)
参数讲解:
1、str1 → 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
2、str2 → 指向要复制的数据源,类型强制转换为 void* 指针。
3、n → 要被复制的字节数。size_t实际上就是和无符号差不多的。
【注意】它的参数的数据类型是无类型指针,也就是说它所有的数据类型都是可以适用的,因为它是 void * 类型。
返回值讲解:该函数返回一个指向目标存储区 str1 的指针。
这个代码是把arr1的元素赋值给arr2的元素,但是只是赋值前五个元素。可以用memcpy()内存函数来进行实现。
代码示例:
#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<string.h>int main(void){ int arr1[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int arr2[10] = { 0 }; memcpy(arr2, arr1, 20); int i = 0; for (i = 0; i < 10; i++) { printf("%d ", *(arr2 + i)); }}
运行结果:1 2 3 4 5 0 0 0 0 0
创建自定义函数实现memcpy()
【注意】在无类型指针数据类型的时候是不能直接进行解引用操作以及++--的,在这里转换成char*指针类型是最合适的,
代码示例:
#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<string.h>#include<assert.h>void *my_memcpy(void *str1, const void *str2, size_t n){ assert(str1 && str2 != NULL); void *ret = str1; while (n--) { *(char*)str1 = *(char*)str2; str1 = (char*)str1 + 1; str2 = (char*)str2 + 1; } return ret;}int main(void){ int i; int arr1[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int arr2[10] = { 0 }; int sz = sizeof(arr1) / sizeof(arr1[0]); int *ret = my_memcpy(arr2, arr1, 20); for (i = 0; i < sz; i++) { printf("%d ", *(ret + i)); } return 0;}
运行结果:1 2 3 4 5 0 0 0 0 0
那在这里假设我们想要从arr1当中第三个元素开始进行拷贝怎么办?只需要改变下memcpy()当中第二个参数就可以。
把上述代码的这段修改下即可:
int *ret = my_memcpy(arr2, arr1+2, 20);
只需要这个样子运行,结果就会从第三个元素开始,这里“+2”是下标,是从0开始的注意下这点。
运行结果:3 4 5 6 7 0 0 0 0 0
【注意】:memcpy函数应该拷贝不重叠的内存。
02
【memmove() - 内存拷贝可重叠】
memmove()指定头文件是:#include<string.h>
memmove()函数的声明方式如下:
void *memmove(void *str1, const void *str2, size_t n)
参数讲解:
1、str1 → 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
2、str2 → 指向要复制的数据源,类型强制转换为 void* 指针。
3、n → 要被复制的字节数。该函数返回一个指向目标存储区 str1 的指针。
我们可以发现是和memcpy()一样的
返回值讲解:该函数返回一个指向目标存储区 str1 的指针。
用同一个数组名进行内存拷贝。
代码示例:
#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<string.h>int main(void){ int arr1[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; memmove(arr1+2, arr1, 20); int i = 0; for (i = 0; i < 10; i++) { printf("%d ", *(arr1 + i)); }}
运行结果:1 2 1 2 3 4 5 8 9 10
【注意】:在这里如果用memcpy()函数的话是行的,这就是memcpy()函数和memmove()函数的区别所在了。
创建自定义函数实现memmove()
代码示例:
#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>#include<string.h>#include<assert.h>void *my_memmove(void *str1, const void *str2, size_t n){ void *ret = str1; assert(str1 && str2 != NULL); if (str1 < str2) { //前向后,小于。 while (n--) { *(char*)str1 = *(char*)str2; str1 = (char*)str1 + 1; str2 = (char*)str2 + 1; } } else { //后向前,大于。 while (n--) { *((char*)str1 + n) = *((char*)str2 + n); } } return ret;}int main(void){ int i = 0; int arr1[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // 1 2 1 2 3 4 5 8 9 10 my_memmove(arr1+2, arr1, 20); return 0;}
str1 > str2运行结果:
1 2 1 2 3 4 5 8 9 10
再来看看str2<str1的调试结果,把上述代码的这段修改下即可:
my_memmove(arr1, arr1+2, 20);
str2<str1运行结果:
3 4 5 6 7 6 7 8 9 10
03
【memcmp() - 内存比较】
memcmp() 指定头文件是:#include<string.h>
memcmp() 函数的声明方式如下:
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
参数讲解:
1、ptr1 → 指向内存块的指针。
2、str2 → 指向内存块的指针。
3、n → 要被比较的字节。
返回值讲解:
1、返回值 < 0,表示 ptr1 小于 ptr2。
2、返回值 > 0,表示 ptr1 大于 ptr2。
3、返回值 = 0,表示 ptr1 等于 ptr2。
代码示例:
#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>#include <string.h>int main(void){ char str1[15] = {0}; char str2[15] = {0}; int ret = 0; memcpy(str1, "ABCDEF", 6); memcpy(str2, "ABCDEF", 6); ret = memcmp(str1, str2, 1); if (ret > 0) { printf("str2 小于 str1"); } else if (ret < 0) { printf("str1 小于 str2"); } else { printf("str1 等于 str2"); } return 0;}
运行结果:str1 等于 str2
【注意】两组数组名是相同的,所对应的ASCII码值。
memcmp()源程序
代码示例:
int __cdecl memcmp ( const void * buf1, const void * buf2, size_t count ){ if (!count) return(0); #if defined (_M_X64) { __declspec(dllimport) size_t RtlCompareMemory( const void * src1, const void * src2, size_t length ); size_t length; if ( ( length = RtlCompareMemory( buf1, buf2, count ) ) == count ) { return(0); } buf1 = (char *)buf1 + length; buf2 = (char *)buf2 + length; } #else /* defined (_M_X64) */ while ( --count && *(char *)buf1 == *(char *)buf2 ) { buf1 = (char *)buf1 + 1; buf2 = (char *)buf2 + 1; } #endif /* defined (_M_X64) */ return( *((unsigned char *)buf1) - *((unsigned char *)buf2) );}
04
【memset() - 内存填充块】
memset() 指定头文件是:#include<string.h>
memset() 函数的声明方式如下:
void * memset ( void * ptr, int value, size_t num );
参数讲解:
1、ptr→指向要填充的内存块的指针。
2、value→要设置的值。该值作为int类型传递,但该函数使用该值的unsigned char转换填充内存块。实际上就是我们所要初始化的内容。
3、num→要设置为该值的字节数。Size_t是一个无符号整型类型。
返回值讲解:返回ptr。
代码示例:
#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>#include <string.h> int main(){ char str[] = " yysyyyds!"; memset(str, 'C', 1); puts(str); return 0;}
运行结果:Cyysyyyds
memset()源程序
代码示例:
void * __cdecl memset ( void *dst, int val, size_t count ){ void *start = dst; #if defined (_M_X64) { __declspec(dllimport) void RtlFillMemory( void *, size_t count, char ); RtlFillMemory( dst, count, (char)val ); } #else /* defined (_M_X64) */ while (count--) { *(char *)dst = (char)val; dst = (char *)dst + 1; }#endif /* defined (_M_X64) */ return(start);}
活动
热门
等等!还没完,新月份新气象
针对各位卷王
我们更新升级了两门专属课程
帮你开拓编程之路
限时“骨折”优惠中……
快来薅羊毛吧!
加静香QQ:1705214200了解详情
阅读原文
了解老九学堂线下高薪就业班详情