今日份学习“内存函数”
前言:
当我们了解字符串相关函数可以对一系列的字符串进行操作,但这些函数只针对于字符串操作且太局限性了,所以为了破开这个局限性,该篇文章将介绍的函数就能解决这个问题。
我们知道字符串相关的函数肯定是对字符串的每个字符进行操作控制的,每个字符且只占一个字节,所以每次操作访问都只针对一个字节的空间进行,就能对各个字符进行操作,但如果对其它类型的数据数组进行操作的话,就能不能达到我们想要的结果,例如说整型"Int"每个整型占四个字节的空间,若只能针对一个字节的空间进行操作的话,然而该空间的其它数据就不能被操作访问,所以就达不到我们想要的结果。
以下就是各个内存函数的介绍与应用
内存函数:
1.memcpy 拷贝函数
2.memmove 拷贝函数
3.memcmp 比较函数
4.memset 设置函数
一,memcpy 拷贝函数
功能:数据拷贝
格式:void * memcpy ( void * destination, const void * source, size_t num );
解析:memcpy函数为了能对各种各样的数据类型进行操作形参void * destination
作为拷贝数据目的地址地利用void*空类型的方式接收各种实参,同样const void * source
作为拷贝数据的源也利用void*空类型的方式接收实参,这里size_t num
接收拷贝所有数据的字节数,则根据这个大小值来操作空间。
思路:①强制将void*都改成char*对地址空间操作②根据形参num的值决定操作空间的字节数,
注意:该函数不适用于相同地址的拷贝操作,确保目的地地址空间足够放下源空间的数据
运用方式:
#include<stdio.h>
#include<string.h>
int main()
{
int arr1[]={1,2,3,4,5,6,7};//创建一个字符数组
int arr2[20];//创建目的地空间的字符数组
memcpy(arr2,arr1,sizeof(arr1));//将arr1数组作为源,将arr2数组作为目的地,把arr1整个数组大小传递
for(int i=0;i<6;i++)//检验arr2数组的内容
{
printf("%d ",arr2[i]);
}
return 0;
}
成功拷贝
自主实现:
学会怎么用了,下面试着怎么造。
按照上面的思路
以数组的字节个数作为循环的核心。
#include<stdio.h>
void* my_memcpy(void* dst, const void* rst, size_t num)
{
while (num--)//总字节个数作为循环条件
{
*(char*)dst = *(char*)rst;//一个字节一个字节拷贝
((char*)dst)++;
((char*)rst)++;
}
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7 };//创建一个字符数组
int arr2[20];//创建目的地空间的字符数组
my_memcpy(arr2, arr1, sizeof(arr1));//将arr1数组作为源,将arr2数组作为目的地,把arr1整个数组大小传递
for (int i = 0; i < 6; i++)//检验arr2数组的内容
{
printf("%d ", arr2[i]);
}
return 0;
}
还是难不倒我们的。
这里提示几个容易写错的地方:
数据拷贝记得向强制类型转换后,再解引用进行赋值!!
*(char*)dst = *(char*)rst;
注意代码的优先级,该加括号的要加上括号!!
((char*)dst)++;
((char*)rst)++;
二,memmove 内存移动函数(拷贝)
功能:数据拷贝
格式:void * memmove ( void * destination, const void * source, size_t num );
解析:该函数的实现功能与“memcpy“是一样样,但是该函数主要针对在同一个地址进行拷贝数据。
举个栗子:Int arr[10]={1,2,3,4,5,6,7};
我要将arr的前四个数”1,2,3,4“从arr的第三个数的位置依次进行拷贝,达到最终结果{1,2,1,2,3,4,7};
这就是同地址空间拷贝数据。
如果直接拷贝的话,则会造成数据丢失的情况:
{1,2,3,4,5,6,7}
👉{1,2,1,4,5,6,7}
👉{1,2,1,2,5,6,7}
👉{1,2,1,2,1,6,7}
👉{1,2,1,2,1,2,7}
则达不到想要的结果{1,2,1,2,3,4,7};
则就有专门解决该问题的memmove函数
运用方式:
#include<stdio.h>
#include<string.h>
int main()
{
int arr1[]={1,2,3,4,5,6,7};//创建一个字符数组
memmove(arr1+2,arr1,sizeof(arr1));//将arr1数组作为源,将arr1+2的位置数组作为目的地,把arr1整个数组大小传递
for(int i=0;i<6;i++)//检验arr1数组的内容
{
printf("%d ",arr1[i]);
}
return 0;
}
有效解决
自主实现:
该函数的实现思路在”memcpy“的基础上,把copy的顺序改变一下即可。
1.如果源地址在目的地地址的后面(源地址大于目的地地址)由后往前copy。
将1,2,3,4从第三个位置开始拷贝{1,2,3,4,5,6,7}
{1,2,3,4,5,6,7}
👉{1,2,3,4,5,4,7}
👉{1,2,3,4,3,4,7}
👉{1,2,3,2,3,4,7}
👉{1,2,1,2,3,4,7}
2.如果源地址在目的地地址的前面(源地址小于目的地地址)由前往后copy。
将3,4,5,6从第一个位置开始拷贝{1,2,3,4,5,6,7}
{1,2,3,4,5,6,7}
👉{3,2,3,4,5,6,7}
👉{3,4,3,4,5,6,7}
👉{3,4,5,4,5,6,7}
👉{3,4,5,6,5,6,7}
#include<stdio.h>
void* my_memmove(void* dst, const void* rst, int num)
{
if (dst > rst)//如果源地址大于目的地地址执行从后往前拷贝
{
(char*)dst = (char*)dst + num;//定位到末尾的位置
(char*)rst = (char*)rst + num;//定位到末尾的位置
while (num--)//总字节个数作为循环条件
{
((char*)dst)--;//因为目前是定位到了末尾最后一个字节的位置,则需先--再赋值
((char*)rst)--;//如果先赋值再--的话,则会影响末尾数据的下一个数据
*(char*)dst = *(char*)rst;//一个字节一个字节拷贝
}
}
else
{
while (num--)//如果源地址小于目的地地址执行从前往后拷贝
{
*(char*)dst = *(char*)rst;//一个字节一个字节拷贝
((char*)dst)++;
((char*)rst)++;
}
}
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7 };//创建一个字符数组
my_memmove(arr1+2, arr1,16);//将arr1数组作为源,将arr1+2的位置数组作为目的地,把arr1整个数组大小传递
for (int i = 0; i < 7; i++)//检验arr1数组的内容
{
printf("%d ", arr1[i]);
}
return 0;
}
果然细节决定成败呢~~~
下面的两个内存函数比较简单了
三,memcmp 内存比较
功能:比较大小
格式:int memcmp ( const void * ptr1, const void * ptr2, size_t num );
解析:比较两个内存块
将 ptr1 指向的内存块的前 num 字节数与 ptr2 指向的字节数一一进行比较,如果它们都匹配,则返回零,如果不匹配,则返回一个不同于零的值,表示哪个值更大。 请注意,与 strcmp 不同,该函数在找到空字符后不会停止比较。
运用方式:
#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;
}
四,memset 内存设置
功能:比较大小
格式:void * memset ( void * ptr, int value, size_t num );
解析:
填充内存块,将 ptr 指向的内存块的第一个字节数开始的num个字节设置为指定值(value)(解释为无符号字符)。
运用方式:
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "almost every programmer should know memset!";
memset (str,'-',6);
puts (str);
return 0;
}
✨以上就是该篇文章对内存函数的介绍✨
结束:
.这世界从来没有什么救世主,你弱了,所有困难都强了,你强了,所有阻碍都弱了!