本节了解四个内存相关的函数
memcpy、memmove、memcmp、memset
。
void* memcpy(void* destination, const void* source, size_t num);
**头文件是 **<string.h>
作用:把指针
souce
指向的num
个字节复制到指针destination
指向的空间。 返回指向目标空间起始地址的指针destination
。 与字符串函数strcpy()
不同的是,memcpy
适用于任何类型的数据;memcpy
不对'\0'
进行判断,是否已经复制了num
个字节是memcpy
所关心的。memcpy()
函数只要能够实现源空间与目标空间非完全重叠区域的拷贝进行就可以了。如果源空间与目标空间存在重叠区域那么使用memcpy()
可能不能正确完成拷贝,从而无法得到正确的结果。因为这是另一个函数memmove()
将要完成的功能。
从源空间和目标空间的起始位置开始,以字节为单位依次向后复制,直到复制完成。
…
//把整型数组arr1中的前20个字节的内容复制到另一个数组arr2中
#include <stdio.h>
#include <string.h>
int main(){
int arr1[] = { 1,2,3,4,5,6,7,8,9,0 };
int arr2[20] = { 0 };
memcpy(arr2, arr1, 20);
int i = 0;
for (i = 0; i < 20; i++) {
printf("%d ", arr2[i]);
}
return 0;
}
运行结果:
//把数组arr1中的前20个字节的内容复制到数组arr1从arr1+2开始的空间中,出现了问题,这是函数实现方法造成的。
#include <stdio.h>
#include <string.h>
int main(){
int arr1[] = { 1,2,3,4,5,6,7,8,9,0 };
int arr2[20] = { 0 };
memcpy(arr1+2, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++) {
printf("%d ", arr2[i]);
}
return 0;
}
#include <stdio.h>
#include <assert.h>
void* my_memcpy(void* destination, const void* source, size_t num) {
//断言指针不为空
assert(destination != NULL && source != NULL);
//记录目标空间起始地址
void* start = destination;
//从前向后依次复制
while (num--) {
*(char*)destination = *(char*)source;
destination = (char*)destination + 1;
source = (char*)source + 1;
}
return start;
}
int main(){
int arr1[] = { 1,2,3,4,5,6,7,8,9,0 };
int arr2[20] = { 0 };
my_memcpy(arr1+2, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++) {
printf("%d ", arr1[i]);
}
return 0;
}
void* memmove(void* destination, const void* source, size_t num);
头文件是<string.h>
作用:把指向源空间的
num
个字节拷贝到目标空间。 是强化版的memcpy()
函数,解决了源空间与目标空间出现部分重叠时拷贝失败的问题。
考虑了拷贝时的重叠问题。
#include <stdio.h>
#include <string.h>
int main() {
int arr1[] = { 1,2,3,4,5,6,7,8,9,0 };
memmove(arr1 + 2, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++) {
printf("%d ", arr1[i]);
}
return 0;
}
运行结果:
#include <stdio.h>
#include <assert.h>
void* my_memmove(void* destination, const void* source, size_t num) {
//断言
assert(destination != NULL && source != NULL);
void* start = destination;
if (destination <= source) {
//前->后
while (num--) {
*(char*)destination = *(char*)source;
destination = (char*)destination + 1;
source = (char*)source + 1;
}
}
else {
//后->前
while (num--) {
*((char*)destination + num) = *((char*)source + num);
}
}
return start;
}
int main() {
int arr1[] = { 1,2,3,4,5,6,7,8,9,0 };
my_memmove(arr1 + 2, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++) {
printf("%d ", arr1[i]);
}
return 0;
}
int memcmp(const void* ptr1, const void* ptr2, size_t num);
头文件<string.h>
作用:比较指针
ptr1
与ptr2
指向的空间的前num
个数据的大小,是以字节为单位比较的。适用于所有的数据类型。 不关注'\0'
返回一个整数 >0 在两个内存块中不匹配的第一个字节在ptr1中的值低于ptr2中的值 =0 两个内存块的内容相等 <0 在两个内存块中不匹配的第一个字节在ptr1中的值高于ptr2中的值
#include <stdio.h>
#include <string.h>
int main() {
int arr1[] = { 1,2,3,4,5,6,7,8,9,0 };
int arr2[] = { 2,3,4,5,6 };
int ret = memcmp(arr1, arr2, 10);
if (ret > 0) {
printf("arr1 > arr2\n");
}
else if (ret == 0) {
printf("arr1 == arr2\n");
}
else {
printf("arr1 < arr2\n");
}
return 0;
}
运行结果:
#include <stdio.h>
#include <assert.h>
int my_memcmp(const void* ptr1, const void* ptr2, size_t num) {
//断言
assert(ptr1 != NULL && ptr2 != NULL);
while (num-- && *(char*)ptr1 == *(char*)ptr2) {
ptr1 = (char*)ptr1 + 1;
ptr2 = (char*)ptr2 + 1;
}
return *(char*)ptr1 - *(char*)ptr2;
}
int main() {
int arr1[] = { 1,2,3,4,5,6,7,8,9,0 };
int arr2[] = { 2,3,4,5,6 };
int ret = my_memcmp(arr1, arr2, 10);
if (ret > 0) {
printf("arr1 > arr2\n");
}
else if (ret == 0) {
printf("arr1 == arr2\n");
}
else {
printf("arr1 < arr2\n");
}
return 0;
}
void* memset(void* ptr, int value, size_t num);
头文件为<string.h>
作用:将ptr所指向的内存块的前
num
个字节赋值为value
。value
作为int
传递,但函数使用该值的unsigned char
转换填充内存块。 返回指针ptr
。
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "hell0 world!";
memset(str + 3, '@', 5);
puts(str);
return 0;
}
#include <stdio.h>
#include <string.h>
int main() {
int arr[20] = { 0 };
memset(arr , 5, 20);
return 0;
}
运行结果:
#include <stdio.h>
#include <assert.h>
void* my_memset(void* ptr, int value, size_t num) {
//断言
assert(ptr != NULL);
while (num--) {
*((char*)ptr + num) = value;
}
return ptr;
}
int main() {
int arr[20] = { 0 };
my_memset(arr , 5, 20);
return 0;
}
这篇主要介绍了内存函数的相关概念,并进行了模拟实现。可以较为深入的理解这些函数,并提高熟练程度。
END