目录
前言
在我们C语言的学习中,免不了和C语言的内存操作函数打交道,因此,在此让我带领各位友人回顾一下C语言内存操作函数!
提示:以下是本篇文章正文内容,下面案例可供参考
一、memcpy函数
1.1函数的描述
C 库函数 void* memcpy(void *str1, const void *str2, size_t n) 是从存储区 str2 复制 n 个字节到存储区 str1,同时应该注意的是memcpy不可以复制两块重叠的内存空间(虽然有些编译器上可以复制,但不是所有的,因此尽量不要用memcpy复制两重叠的内存空间)。
1.2函数的应用
由于memcpy是内存操作函数,因此memcpy可以拷贝任意类型数据,包括自定义类型,或者c语言的基本数据类型。一下是拷贝字符串和整形数组的示例,别的数据拷贝方法也类似。
#include <stdio.h>
#include <string.h>
int main ()
{
const char src[10] = "abcdef";
char dest[10];
//拷贝字符串
memcpy(dest, src, strlen(src)+1);
printf("dest = %s\n", dest);
return 0;
}
#include <stdio.h>
#include <string.h>
int main ()
{
int arr[10] = {0,1,2,3,4}
int brr[10] = {0};
//拷贝整形数组
memcpy(brr, arr, 5*sizeof(int);
return 0;
}
1.3函数的模拟实现
模拟实现代码如下:
#include<stdio.h>
#include<assert.h>
//memcpy的模拟实现
void* my_memcpy(void* destination, const void* source, int num)
{
void* ret = destination;
assert(destination && source);
while (num--)
{
*((char*)destination)++ = *((char*)source)++;
}
return ret;
}
二、memmove函数
2.1函数的描述
C 库函数 void *memmove(void *str1, const void *str2, size_t n) 从 str2 复制 n 个字符到 str1,但是在重叠内存块这方面,memmove() 是比 memcpy() 更安全的方法。如果目标区域和源区域有重叠的话,memmove() 能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,复制后源区域的内容会被更改。如果目标区域与源区域没有重叠,则和 memcpy() 函数功能相同。
2.1函数的应用
memmove函数在应用方面和memcpy基本一样,只是memmove可以复制重叠的内存空间,因此在这里小编只演示复制重叠内存空间的方法和效果
#include<stdio.h>
#include<string.h>
int main()
{
int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
//将arr数组中3-7的元素复制放到0-4上
memmove(arr, arr + 3, 5 * sizeof(int));
for (int i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
输出结果:
2.3函数的模拟实现
由于memmove函数要实现对重叠内存的拷贝,这必然会涉及到覆盖,因此memmove函数模拟实现的重难点在于:如何解决重叠部分内存不被覆盖,且正确的拷贝到正确的位置。
对于重叠部分的内存,有如下两种情况:
第一种:
这种情况下,我们需要从前向后依次拷贝src中的元素到dest中,即依次将4,5,6,7,8位置的元素拷贝放到1,2,3,4,5地位置才能确保元素不被覆盖
第二种:
这种情况下,我们需要从后向前依次拷贝src中的元素到dest中,即依次将1,2,3,4,5位置的元素拷贝放到4,5,6,7,8地位置才能确保元素不被覆盖才能确保元素不被覆盖
而对于没有重叠部分的内存的复制,从后向前或者从前向后均可以。因此我们在模拟实现的时候要根据情况进行正确方向的拷贝
模拟实现代码如下:
//memmove的模拟实现
void* my_memmove(void* destination, const void* source, int num)
{
void* ret = destination;
assert(destination && source);
if (destination<source || destination>(char*)source + num)
{
//从前往后copy内存
while (num--)
{
*((char*)destination)++ = *((char*)source)++;
}
return ret;
}
else
{
//从后往前copy内存
(char*)source += num - 1;
(char*)destination += num - 1;
while (num--)
{
*((char*)destination)-- = *((char*)source)--;
}
return ret;
}
}
三、memset函数
3.1函数的描述
函数原型为:
# include <string.h>
void *memset(void *s, int c, unsigned long n);
函数的功能是:将指针变量 s 所指向的前 n 字节的内存单元用一个“整数” c 替换,因为这是针对内存进行的修改,所以它可以为任何类型的数据进行修改。但因为memset函数是按照字节对内存块进行修改,所以在用它对内存初始化时一般都是初始化为全1或者全0。
3.2函数的使用
memset可以对任意类型的数据的内存进行修改,在这里小编演示一下修改字符串的内存。
源码:
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "***********************";
memset (str,'-',6);
puts (str);
return 0;
}
输出结果:
四、memcmp函数
4.1函数的描述
memcmp函数的原型为 int memcmp(const void *str1, const void *str2, size_t n);其功能是把存储区 str1 和存储区 str2 的前 n 个字节进行比较。该函数是按字节比较的。即函数内部会从str1和str2开始对每一个字节进行分别比较,只有当这个字节的内容完全相同时函数才会返回0。
4.2函数的使用
#include<stdio.h>
#include<string.h>
int main()
{
char arr[] = "abcdef";
char brr[] = "abdefg";
int n = memcmp(arr, brr, strlen(arr));
if (n > 0)
{
printf("%s > %s", arr, brr);
}
else if (n < 0)
{
printf("%s < %s", arr, brr);
}
else
{
printf("%s = %s", arr, brr);
}
return 0;
}
输出结果:
总结
这次内存操作函数的分享到这里就结束了,制作不易,望各位道友可以点赞关注加评论,后续会持续更新高质量博客。谢谢!!!