C语言中常见的内存函数有四种,分别是:
memcpy——内存拷贝(不可重叠)
memmove——内存拷贝(可重叠)
memset——内存设置
memcmp——内存比较
1.memcpy——内存拷贝(不可重叠)
函数参数:void * memcpy ( void * destination, const void * source, size_t num );
#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);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
运行结果:
模拟实现memcpy,代码示例:
#define _CRT_SECURE_NO_WARNINGS 1
//模拟实现memcpy
void* my_memcpy(void* dest, const void* src, size_t num)
{
void* ret = dest;//因为dest在循环体中不断发生变化,所以将dest的地址存放在指针变量ret中,此后ret就随着dest进行变化,但dest不会随着ret进行变化,最后函数返回ret的值
while (num--)
{
*(char*)dest = *(char*)src;//dest是void*类型,不能解引用所以得强制转换成char*类型的
++(char*)dest;//void*类型不能进行++操作,所以要进行强制类型转化,如果是后置++,那么强制类型转化先对dest进行,所以要进行前置++,也可以写成dest = (char *)dest + 1,下同
++(char*)src;
}
return(ret);
}
#include <stdio.h>
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
my_memcpy(arr2, arr1, 20);
for (int i = 0; i < 10; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
2.memmove——内存拷贝(可重叠)
函数参数:void * memmove ( void * destination, const void * source, size_t num );
#include <stdio.h>
#include <string.h>
int main()
{
int arr1[] = { 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]);
}
return 0;
}
运行结果:
模拟实现memmove,代码示例:
#define _CRT_SECURE_NO_WARNINGS 1
//模拟实现memmove
#include <stdio.h>
#include <assert.h>
void* my_memmove(void* dest, void* src, size_t count)
{
assert(dest && src);
void* ret = dest;
if (dest < src)
{
while (count--)
{
//前->后
*(char*)dest = *(char*)src;
++(char*)dest;
++(char*)src;
}
}
else
{
while (count--)
{
//后->前
*((char*)dest + count) = *((char*)src + count);//起始位置+count=最后的位置
}
}
return ret;
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
my_memmove(arr1+2, arr1, 20);
int i = 0;
for(i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
原理:
如果dest的位置在src的起始位置的前面的话,我们就从前往后进行拷贝,依次覆盖,这样就不会造成内存重复的情况。
如果dest的位置在src的其实位置的后方的话,我们就从前向后进行拷贝,依次覆盖,这样就不会造成内存重复的情况。
PS:有些小伙伴可能在测试的时候会发现,在VS2022的环境下测试memmcpy的时候会发现他的作用和memmove一样不会造成内存重复的情况。但是要注意的是,这只是编译环境的特性,不代表所有的编译器都适用。如果在面试的时候有这样的题,那么用memmcpy可以拿60分,而memmove可以拿100分。一定要严格按照C语言的语法规定来!!!一定要严格按照C语言的语法规定来!!!一定要严格按照C语言的语法规定来!!!(重要的事强调三遍!!!)
3.memset——内存比较
函数参数:void * memset ( void * ptr, int value, size_t num );
memset是⽤来设置内存的,将内存中的值以字节为单位设置成想要的内容。
代码示例:
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "hello world";
memset (str,'x',6);
printf(str);
return 0;
}
运行结果:
模拟实现memset,代码示例:
#define _CRT_SECURE_NO_WARNINGS 1
//模拟实现memset
#include <stdio.h>
#include <assert.h>//assert函数的头文件
int my_memset(void* ptr, int val, size_t num)
{
assert(ptr);//断言,确保不是空指针
void* ret = ptr;
while (num--)
{
*(char*)ptr = val;
++(char*)ptr;
}
return ret;
}
int main()
{
char str[] = "hello world";
my_memset(str, 'x', 5);
printf("%s", str);
return 0;
}
运行结果:
4.memcmp——内存比较
函数参数:int memcmp ( const void * ptr1, const void * ptr2, size_t num );
ptr1 < ptr2 时返回 < 0 的值;
ptr1 = ptr2 时返回 = 0 的值;
代码示例:
#include <stdio.h>
#include <string.h>
int main()
{
char buffer1[] = "DWgaOtP12df0";
char buffer2[] = "DWGAOTP12DF0";
int n;
n = memcmp(buffer1, buffer2, sizeof(buffer1));
if (n > 0)
printf("'%s' is greater than '%s'.\n", buffer1, buffer2);
else if (n < 0)
printf("'%s' is less than '%s'.\n", buffer1, buffer2);
else
printf("'%s' is the same as '%s'.\n", buffer1, buffer2);
return 0;
}
运行结果:
模拟实现memcpm,代码示例:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>//assert函数的头文件
int my_memcmp(const void* ptr1, const void* ptr2, size_t num)
{
assert(ptr1 && ptr2);//断言,确保不是空指针
while ((--num) && (*(char*)ptr1 == *(char*)ptr2))
{
ptr1 = (char*)ptr1 + 1;
ptr2 = (char*)ptr2 + 1;
}
if (*(char*)ptr1 > *(char*)ptr2)
{
return 1;
}
else if (*(char*)ptr1 == *(char*)ptr2)
{
return 0;
}
else
{
return -1;
}
}
int main()
{
char buffer1[] = "DWgaOtP12df0";
char buffer2[] = "DWGAOTP12DF0";
int n;
n = my_memcmp(buffer1, buffer2, sizeof(buffer1));
if (n > 0)
printf("'%s' is greater than '%s'.\n", buffer1, buffer2);
else if (n < 0)
printf("'%s' is less than '%s'.\n", buffer1, buffer2);
else
printf("'%s' is the same as '%s'.\n", buffer1, buffer2);
return 0;
}
运行结果:
PS:如有不足或补充,欢迎指出评论,喜欢就请一键三连吧~😆😆😆