C语言基本语法-必备的内存函数
本文介绍了四种常用的内存操作函数:memcpy、memmove、memset和memcmp。memcpy实现内存块拷贝,不关心数据类型;memmove在内存重叠时更安全;memset用于内存块初始化;memcmp比较内存内容。文章详细说明了各函数的参数、返回值及使用场景,并提供了memcpy和memmove的模拟实现代码。这些函数都使用void*指针实现泛型编程,适用于不同数据类型的内存操作。示例代码演示了如何正确使用这些函数进行内存操作和比较。这些函数的使用都要包含string.h的头文件。
1.内存函数:memcpy
1.1memcpy
strcpy和strncpy作用是拷贝字符串,但是有局限性,比如拷贝一个整形数组或结构体数组就没办法了。所以memcpy是对内存中的任意数据进行拷贝。

memcpy函数的作用是内存块拷贝,不关注内存中存放什么类型的数据,从source所指地址开始向后拷贝num个字节的数据存放到destination所指地址中。
参数destination指向拷贝的目标空间的起始地址,拷贝后的数据放到这里,source指向拷贝的原始空间的起始地址,要拷贝的数据存放在此,num表示要拷贝多少字节的数据。
函数返回值是目标空间的起始地址。
注意:destination和source参数的类型都是void*,以及返回值的类型也是void*,由于不知道内存中要拷贝的数据是什么类型的,所以都用void*以表示任意类型的数据,实现泛型编程。
示例代码:
#include<string.h>
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[20] = { 0 };
/*把arr1中的10个整数拷贝到arr2中*/
memcpy(arr2, arr1, 40);
return 0;
}
1.2memcpy函数的模拟实现
#include<assert.h>
#include<stdio.h>
void* my_memcpy(void* destination, const void* source, size_t num)
{
assert(destination && source);
char* dest = (char*)destination;
char* src = (char*)source;
while (num--)
{
*dest = *src;
dest++;
src++;
}
return destination;
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[20] = { 0 };
/*把arr1中的10个整数拷贝到arr2中*/
my_memcpy(arr2, arr1, 40);
for (int i = 0; i < sizeof(arr2) / sizeof(arr2[0]); i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
注意:当目标数据空间和原始数据空间重叠时(下图场景),memcpy的结果是未定义的,应该使用memmove函数。
2.内存函数:memmove
2.1memmove

memmove函数的作用也是是内存块拷贝,不关注内存中存放什么类型的数据,从source所指地址开始向后拷贝num个字节的数据存放到destination所指地址中。和memcpy的区别是memmove函数处理的原内存空间和目标内存空间是可以重叠的。
参数destination指向拷贝的目标空间的起始地址,拷贝后的数据放到这里,source指向拷贝的原始空间的起始地址,要拷贝的数据存放在此,num表示要拷贝多少字节的数据。
函数返回值是目标空间的起始地址。
示例代码:和上方注意代码中的区别:

2.2memmove函数的模拟实现
分析:



代码实现:
#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memmove(void* destination, const void* source, size_t num)
{
assert(destination && source);
void* p = destination;
if (source <= destination)
{
while (num--)
{
*((char*)destination + num) = *((char*)source + num);
}
}
else
{
while (num--)
{
*((char*)destination) = *((char*)source);
destination = (char*)destination + 1;
source = (char*)source + 1;
}
}
return p;
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
/*把arr中的12345拷贝到34567的位置上*/
my_memmove(arr + 2, arr, 20);
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%d ", arr[i]);
}
return 0;
}
3.内存函数:memset

memset函数的作用是内存设置,用来设置内存块中的内容,将ptr所指向的内存中的num个字节的空间设置为特定内容value。
参数ptr指向要设置的内存空间的起始地址。参数value表示要设置的值,函数memset会把value的值转换为unsigned char类型的数据设置到相应的内存空间中,并且以字节为单位设置内存。参数num表示设置的内存长度单位是字节。也就是说这个函数会逐个字节的将内存中的值改为value对应的unsigned char类型的数据。
返回值是ptr,即要设置内存空间的起始地址。
示例代码①:

示例代码②:

4.内存函数:memcmp

memset函数的作用是对指定两块内存空间的内容进行比较,内存空间是从ptr1,ptr2指向的位置开始向后的num个字节,逐个字节的进行比较。
参数ptr1指向第一块需要比较的内存块的起始地址。参数ptr2指向第二块需要比较的内存块的起始地址。参数num指定需要进行比较的长度,单位是字节。
函数的返回值:

示例代码:
#include<string.h>
#include<stdio.h>
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[] = { 1,2,3,4,8 };
int ret = memcmp(arr1, arr2, 20);
if (ret > 0) printf("arr1 > arr2\n");
else if (ret < 0) printf("arr1 < arr2\n");
else printf("arr1 = arr2\n");
return 0;
}更多推荐



所有评论(0)