电商网站平台有哪些,广州短视频运营培训,网站开发费税率是多少,装修设计案例网站前言#xff1a;小伙伴们又见面啦。
本篇文章#xff0c;我们将讲解C语言中比较重要且常用的内存函数#xff0c;并尝试模拟实现它们的功能。
让我们一起来学习叭。 目录
一.什么是内存函数
二.内存函数有哪些
1.memcpy
#xff08;1#xff09;库函数memcpy
…前言小伙伴们又见面啦。
本篇文章我们将讲解C语言中比较重要且常用的内存函数并尝试模拟实现它们的功能。
让我们一起来学习叭。 目录
一.什么是内存函数
二.内存函数有哪些
1.memcpy
1库函数memcpy
2模拟实现memcpy
2.memmove
1库函数memmove
2模拟实现memmove
3.memset
4.memcmp
四.总结 一.什么是内存函数
我们从这个名字不难看出这将会是一个函数还是一个对内存进行操作的函数。
而事实上这其实也是一种对数据进行操作的函数。
我们之前学习过strcmp、strcpy、strlen等等它们都是对字符进行操作的函数统称为字符串函数。但是这些字符串函数却有着弊端那就是它们仅仅只能操作字符串而像整型这些其他类型的数据却无法操作。
因此我们引出了内存函数帮助我们对各种各样类型的数据进行操作。 二.内存函数有哪些
memcpymemmove memsetmemcmp
和字符串操作函数类似内存函数也是由内存的英文memory和后边的操作方式的英文拼接而成同时使用它们都需要头文件#includestring.h。
下面我们来逐个讲解这四个内存函数的具体用法。 1.memcpy
和strcpy类似memcpy也是数据拷贝将一个数组里的数据拷贝到另一个数组中去。
先来认识一下memcpy的函数头 这个函数有三个参数 destination 代表着目的地 source 代表着源头 num 约束着我们要操作的数据数目 有没有小伙伴们知道为什么数组指针参数的返回值以及函数的返回值都要是void*类型呢
我们已经知道memcpy是用来拷贝各种各样的数据类型的函数那么它的参数就不能是单一的char*或者int*而void*则充当一个中转站他可以接收任意类型的数据也可以在函数内部通过强制类型转换成各种各样的数据类型。
size_t是无符号整型因为我们拷贝字符串不可能说拷贝负数个或者小数个所以用它来接收。
而我们的源头source我们是不希望它有任何变化或者被修改的所以要用一个const来修饰。
事实上我们这篇文章讲到的所有内存函数的参数都是如此。 1库函数memcpy
下面我们来看一下memory的具体用法
#includestdio.h
#includestring.h
int main()
{int arr1[10] { 0 };int arr2[5] { 1,2,3,4,5 };memcpy(arr1, arr2, 20);for (int i 0; i 10; i){printf(%d , arr1[i]);}return 0;} 来看这样一个简单的代码及其结果我们用memcpy成功的实现了整型数据的拷贝。
这时候有小伙伴们会说你这个代码不对吧你memcpy里的数据数目为啥是20啊
事实上memcpy的数据数目代表的是字节数而5个整型的字节数刚好是20。
那为什么是字节数而不是元素的个数呢
下面我们就通过模拟实现一个memcpy函数来看看它的具体内部构造
2模拟实现memcpy
自主实现memcpy我们完全可以使用它本身的函数头也就是 void* My_memcpy(void* destination, const void* source, size_t num) 下面我们来分析怎么构造函数体
我们知道任何类型的数据都有它的大小字节数基本都不相同但是它们都有最小的单位那就是一个字节的char类型。
因此我们将形参强制类型转换为char*类型一个字节一个字节的拷贝是不是就能实现啦。
这时候我们就悟出来了为什么数据数目是字节数了。
下面来看具体函数体实现
#includestdio.h
#includestring.h
void* My_memcpy(void* destination, const void* source, size_t num)
{char* p destination;while(num--){*(char*)destination *(char*)source;destination (char*)destination 1;source (char*)source 1;}return p;
}
int main()
{int arr1[10] { 0 };int arr2[5] { 1,2,3,4,5 };My_memcpy(arr1, arr2, 20);for (int i 0; i 10; i){printf(%d , arr1[i]);}return 0;
}
按我们前边分析的将destination和source都转化为char*指针再用while循环实现一个字节一个字节的拷贝这样我们便能够实现对一组整型数据的拷贝了。来看结果 这时候请小伙伴们思考一个问题我们上边实现的是将一个数组的数据拷贝到另一组数组中
那我们能不能在一个数组的内部进行拷贝呢
比如说我现在有一个数组 int arr[10] { 1,2,3,4,5,6,7,8,9,10 }; 我现在要将1,2,3,4,5拷贝到3,4,5,6,7的位置去得到1,2,1,2,3,4,5,8,9,10能否实现
事实上是不行的
当我们第一步把1拷贝到3的位置时3的值已经被替换成1整个数据变成了1,2,1,4,5,6,7,8,9,10。
会导致我们得到1,2,1,2,1,2,1,8,9,10 这样一个结果。
这时候我们的memcpy就无法实现我们想要的结果了于是我们引出了memmove函数。
这里要补充一点不同的编译器memcpy的功能不完全相同比如博主所使用的VS2019的memcpy就可以实现同一个数组元素的拷贝有的却不行 2.memmove
memmove的函数头和memcpy一模一样只是函数体有些许不同。 下面我们先来看作为库函数的memmove的使用。
1库函数memmove
#includestdio.h
#includestring.h
int main()
{int arr[10] { 1,2,3,4,5,6,7,8,9,10 };memmove(arr 2, arr, 20);for (int i 0; i 10; i){printf(%d , arr[i]);}return 0;
}
值得注意的一点是我们知道数组名在一般情况下代表的是数组的首元素地址因此我们向函数传递时分别传递我们要进行操作的两个数列的首元素的地址便可。
例如我们上述就是将数组的1-5位拷贝到3-7位所以就将第一位和第三位的地址作为参数传过去。
得到结果为 那到底怎么才能实现同一个数组内数据的相互拷贝呢 先来分析一下既然我们从前往后会造成值被修改那我们从后往前可不可以呢 例如我们还是将1,2,3,4,5拷贝到3,4,5,6,7上去先将5拷贝到7再将4拷贝到6这样下去确实能够完成。 下面我们来模拟实现一下memmove的具体内部构造。 2模拟实现memmove
#includestdio.h
#includestring.h
void* My_memmove(void* destination, const void* source, size_t num)
{char* p destination;while (num--){*((char*)destination num) *((char*)source num);}return p;
}
int main()
{int arr[10] { 1,2,3,4,5,6,7,8,9,10 };My_memmove(arr 2, arr, 20);for (int i 0; i 10; i){printf(%d , arr[i]);}return 0;
}
要注意的是既然是从后往前一个字节一个字节的拷贝那么我的destination和source指针都需要指向末位所以在解引用之前要先加上num。
这样我们便实现了数组内部的拷贝。 但是这时候问题又来了如果我想将3,4,5,6,7拷贝到1,2,3,4,5上去从后往前还管用吗 显然又出现被覆盖的情况看来我们上边的代码还有缺陷没有完全实现memmove的功能。
那该怎么解决呢
这时候我们思考一下将前边的数据拷贝到后边要从后往前相对的将后边的数据拷贝到前边是不是要从前往后那我们将这两者整合在一起不就好了。
只需要一个判断条件判断是将前边的数据拷贝到后边还是将后边的数据拷贝到前边不就行啦。
现在我们只需要解决一个问题怎么判断呢
其实这个很简单如果是将前边的数据拷贝到后边那么源头的地址就会比目的地小反之将后边的数据拷贝到前边那么源头的地址就会比目的地小。 这时候我们只需要比较一下源头和目的地的地址就好啦。
来看具体实现
#includestdio.h
#includestring.h
void* My_memmove(void* destination, const void* source, size_t num)
{char* p 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 p;
}
int main()
{int arr[10] { 1,2,3,4,5,6,7,8,9,10 };My_memmove(arr, arr 2, 20);for (int i 0; i 10; i){printf(%d , arr[i]);}return 0;
}
这样我们便实现memmove的完整功能啦。 看到这里小伙伴们是不是都感觉非常的累其实博主我讲到这里也是非常的累。
事实上对于上边的两个函数我们更需要掌握他们的内部构造而接下来要讲的剩下的两个函数就比较简单了我们只需要知道怎么用它们就可以啦。 3.memset
这个函数叫做内存设置函数其作用是修改内存中的若干个数据。 ptr 是我们要修改的数据起始位置 value 是我们要改为的数据 num 是我们要修改的数据数量 来看实操
#includestdio.h
#includestring.h
int main()
{char arr[] hello world;memset(arr, *, 5);printf(%s, arr);return 0;
}
我们要将hello五个字符全改为*便将数组首地址*5作为参数传入得到结果如下 值得注意的是这个函数也是只能一个字节一个字节的操作。
#includestdio.h
#includestring.h
int main()
{int arr[5] {0};memset(arr, 1, 20);return 0;
} 假如我要把这个整型数组的五个元素都改为1一个字节一个字节的改要改20个所以我们传入20但是我们来看结果和内存 这并不是我们想要的结果一个字节8个bite位所以我们实际上得到的是二进制序列
00000001 00000001 00000001 00000001也就是十进制的16843009。
所以这个函数可以说是只能跟char型的数据挂钩啦不要轻易用在其他类型哦。 4.memcmp
既然是cmp结尾肯定也是一个比较函数是一个内存比较函数。 但是这个比较函数有点特殊它可以让你指定要比较的位置和数量可以说是strcmp pro max。
这里值得注意的是这个函数的返回值类型是int当前者 后者时返回 1反之返回 -1相等则返回0。
来看具体使用
#includestdio.h
#includestring.h
int main()
{int arr1[] { 1,2,3,4,5,6,7,8,9,10 };int arr2[] { 1,2,3,4,5 };int ret memcmp(arr1 1, arr2, 20);printf(%d, ret);return 0;
} (arr1 1)便跑到了2的位置2 1自然会返回1。 使用这个函数值得注意的一点是它只会比较第一组遇见的不相同的数据而不会比较整体的数据和的大小。
#includestdio.h
#includestring.h
int main()
{int arr1[] { 1,2,3,4,5,6,7,8,9,10 };int arr2[] { 1,2,4,1,1 };int ret memcmp(arr1, arr2, 20);printf(%d, ret);return 0;
}
例如上述代码1 2 3 4 5 明显大于1 2 4 1 1但是只因为3 4就返回了 - 1。 四.总结
终于终于内存函数的讲解到这里就结束啦
感谢各位小伙伴能够耐心的看到最后希望博主的讲解能够帮助到你们。
本篇创作实属不易不要忘记支持努力的博主呀记得一键三连哦
我们下期再见啦
文章转载自: http://www.morning.lsyk.cn.gov.cn.lsyk.cn http://www.morning.kvzvoew.cn.gov.cn.kvzvoew.cn http://www.morning.fwrr.cn.gov.cn.fwrr.cn http://www.morning.hwprz.cn.gov.cn.hwprz.cn http://www.morning.nlrxh.cn.gov.cn.nlrxh.cn http://www.morning.tpnxr.cn.gov.cn.tpnxr.cn http://www.morning.brhxd.cn.gov.cn.brhxd.cn http://www.morning.nqrlz.cn.gov.cn.nqrlz.cn http://www.morning.xwrhk.cn.gov.cn.xwrhk.cn http://www.morning.jcbmm.cn.gov.cn.jcbmm.cn http://www.morning.fbjqq.cn.gov.cn.fbjqq.cn http://www.morning.rgnq.cn.gov.cn.rgnq.cn http://www.morning.kydrb.cn.gov.cn.kydrb.cn http://www.morning.ccsdx.cn.gov.cn.ccsdx.cn http://www.morning.fjlsfs.com.gov.cn.fjlsfs.com http://www.morning.jnkng.cn.gov.cn.jnkng.cn http://www.morning.xdxpq.cn.gov.cn.xdxpq.cn http://www.morning.nqlcj.cn.gov.cn.nqlcj.cn http://www.morning.trffl.cn.gov.cn.trffl.cn http://www.morning.mwwnz.cn.gov.cn.mwwnz.cn http://www.morning.sjjq.cn.gov.cn.sjjq.cn http://www.morning.kkysz.cn.gov.cn.kkysz.cn http://www.morning.frcxx.cn.gov.cn.frcxx.cn http://www.morning.hrtct.cn.gov.cn.hrtct.cn http://www.morning.lfqnk.cn.gov.cn.lfqnk.cn http://www.morning.frpb.cn.gov.cn.frpb.cn http://www.morning.plzgt.cn.gov.cn.plzgt.cn http://www.morning.jxzfg.cn.gov.cn.jxzfg.cn http://www.morning.pyxwn.cn.gov.cn.pyxwn.cn http://www.morning.zzfqn.cn.gov.cn.zzfqn.cn http://www.morning.gcfg.cn.gov.cn.gcfg.cn http://www.morning.bhmnp.cn.gov.cn.bhmnp.cn http://www.morning.rxfgh.cn.gov.cn.rxfgh.cn http://www.morning.qbtj.cn.gov.cn.qbtj.cn http://www.morning.xbtlt.cn.gov.cn.xbtlt.cn http://www.morning.xlndf.cn.gov.cn.xlndf.cn http://www.morning.wwwghs.com.gov.cn.wwwghs.com http://www.morning.qlpq.cn.gov.cn.qlpq.cn http://www.morning.pcgmw.cn.gov.cn.pcgmw.cn http://www.morning.jrhcp.cn.gov.cn.jrhcp.cn http://www.morning.tdzxy.cn.gov.cn.tdzxy.cn http://www.morning.xdfkrd.cn.gov.cn.xdfkrd.cn http://www.morning.fbtgp.cn.gov.cn.fbtgp.cn http://www.morning.jqkrt.cn.gov.cn.jqkrt.cn http://www.morning.vibwp.cn.gov.cn.vibwp.cn http://www.morning.gsrh.cn.gov.cn.gsrh.cn http://www.morning.sbqrm.cn.gov.cn.sbqrm.cn http://www.morning.zrhhb.cn.gov.cn.zrhhb.cn http://www.morning.mbpzw.cn.gov.cn.mbpzw.cn http://www.morning.kxbdm.cn.gov.cn.kxbdm.cn http://www.morning.jmlgk.cn.gov.cn.jmlgk.cn http://www.morning.gltmz.cn.gov.cn.gltmz.cn http://www.morning.ppghc.cn.gov.cn.ppghc.cn http://www.morning.xtrnx.cn.gov.cn.xtrnx.cn http://www.morning.nfbkz.cn.gov.cn.nfbkz.cn http://www.morning.zgqysw.cn.gov.cn.zgqysw.cn http://www.morning.ljdhj.cn.gov.cn.ljdhj.cn http://www.morning.xnwjt.cn.gov.cn.xnwjt.cn http://www.morning.sgqw.cn.gov.cn.sgqw.cn http://www.morning.btlmb.cn.gov.cn.btlmb.cn http://www.morning.wskn.cn.gov.cn.wskn.cn http://www.morning.qcnk.cn.gov.cn.qcnk.cn http://www.morning.xwlmg.cn.gov.cn.xwlmg.cn http://www.morning.lnbcg.cn.gov.cn.lnbcg.cn http://www.morning.thpns.cn.gov.cn.thpns.cn http://www.morning.bnkcl.cn.gov.cn.bnkcl.cn http://www.morning.zcfsq.cn.gov.cn.zcfsq.cn http://www.morning.etsaf.com.gov.cn.etsaf.com http://www.morning.dglszn.com.gov.cn.dglszn.com http://www.morning.bpmfr.cn.gov.cn.bpmfr.cn http://www.morning.pbzlh.cn.gov.cn.pbzlh.cn http://www.morning.hmnhp.cn.gov.cn.hmnhp.cn http://www.morning.wbrf.cn.gov.cn.wbrf.cn http://www.morning.dnls.cn.gov.cn.dnls.cn http://www.morning.xmbhc.cn.gov.cn.xmbhc.cn http://www.morning.qfmcm.cn.gov.cn.qfmcm.cn http://www.morning.xckdn.cn.gov.cn.xckdn.cn http://www.morning.ljbm.cn.gov.cn.ljbm.cn http://www.morning.diuchai.com.gov.cn.diuchai.com http://www.morning.ctpfq.cn.gov.cn.ctpfq.cn