当前位置: 首页 > news >正文

贵阳市观山湖区网站建设辽宁做网站的公司

贵阳市观山湖区网站建设,辽宁做网站的公司,山东企业网站建设,手工活外发加工无押金文章目录 一、memcpy的使用和模拟实现二、memmove的使用和模拟实现三、memset的使用四、memcmp的使用 一、memcpy的使用和模拟实现 在之前我们学习了使用和模拟实现strncpy函数#xff0c;它是一个字符串函数#xff0c;用来按照给定的字节个数来拷贝字符串#xff0c;那么问… 文章目录 一、memcpy的使用和模拟实现二、memmove的使用和模拟实现三、memset的使用四、memcmp的使用 一、memcpy的使用和模拟实现 在之前我们学习了使用和模拟实现strncpy函数它是一个字符串函数用来按照给定的字节个数来拷贝字符串那么问题来了我们想拷贝的不是字符串而是整型、浮点型的数据该怎么办呢    这时候就要使用我们的内存函数memcpymem是memory的缩写它原本是记忆的意思在这里是内存的意思它的作用范围就宽泛多了因为它是对内存块的内容进行拷贝不管内存中存放的是什么数据类型都可以通过拷贝内存块来实现拷贝    但是使用函数memcpy需要包含的头文件还是string.h接下来我们来看看这个函数的原型 void * memcpy ( void * destination, const void * source, size_t num );它有三个参数可以看到它的前两个参数不再是char * 指针而是void*的指针了因为我们不再知道要拷贝的内容具体是什么数据类型所以可以使用void * 的指针而它的第三个参数是一个无符号整型代表了要拷贝的内存的字节数    它的返回类型是void * 也是由于不知道需要操作的数据类型是什么所以使用void * 那它具体返回的地址是什么呢我们可以参照字符串函数strcpy它返回的就是目标空间的首地址memcpy函数也是这样返回目标空间的首地址也就是这里的destination   接着我们可以总结出memcpy函数的特点 函数memcpy从source的位置也就是源空间的首地址开始向后复制num个字节的数据到destination指向的内存位置这个函数在遇到 ‘\0’ 的时候并不会停下来它拷贝多少数据完全看第三个参数如果source和destination有任何的重叠复制的结果都是未定义的 接下来我们来简单使用一下这个函数用它来拷贝一个整型数组如下 #include stdio.h #include string.hint main() {int arr1[20] { 0 };int arr2[] { 1,2,3,4,5,6,7,8,9,10 }; memcpy(arr1, arr2, sizeof(arr2));for (int i 0; i 10; i){printf(%d , arr1[i]);}return 0; }我们来看看运行结果    可以看到它已经帮我们把数据完全拷贝过来了它是怎么做到的呢我们来试着模拟实现一下这个函数就会发现其实并不难它会结合我们学过的qsort实现和strcpy实现的知识现在我们赶紧来实现一下吧 函数命名my_memcpy函数参数照抄memcpy的参数简化一些长的名字 void* my_memcpy ( void* dest, const void* src, size_t num )函数实现 1老规矩首先进行一次断言确保这两个指针不是空指针 2由于要返回目标空间的首地址所以要创建一个void*的指针变量start来存储用于最后的返回 3这里由于不知道是什么类型的数据所以我们不能妄自定义一个数据类型这里我们可以采用qsort里面的思想将它们转为字符指针一个字节一个字节的拷贝这样就可以确保能够完美拷贝所有数据 4所以我们创建一个while循环每进行一次循环就让num–每一次循环我们就进行一个字节的拷贝并且拷贝完后让dest和src往后走一个字节 5进行一个字节的拷贝就很简单了只需要将dest和src强制类型转换为字符指针就可以了主要是让它们往后面走一个字节不能使用(char * )dest所以我们这里可以采用最原始的操作就是给它1然后赋值给dest如下 dest (char*)dest 1;6最后一步就是返回之前存下的变量start 函数代码 #include assert.hvoid* my_memcpy(void* dest, const void* src, size_t num) {assert(dest src);void* start dest;while (num--){*(char*)dest *(char*)src;dest (char*)dest 1;src (char*)src 1;}return start; }函数测试 最后我们来探讨一个问题memcpy能否自己对自己进行拷贝呢比如有一个数组arr存放的是1到10的数字能不能将从1开始的4个整型数据拷贝到从5开始的4个整型数据如下图 能否将绿色圆圈内的数据作为源数据拷贝到蓝色圆圈的空间中使得数组中的数据变成1 2 3 4 1 2 3 4 9 10问题就在于怎么找到从5开始的地址    arr是首元素地址所以很容易想到可以使用arr4来作为目标空间地址而arr作为源地址我们来测试一下如图 可以看到它成功实现了接着我们继续思考如果在拷贝时源空间和目标空间有重叠呢如图    这个时候我们想要经过拷贝后数据变成1 2 3 4 3 4 5 6 9 10memcpy能否帮我们实现拷贝呢如图    可以看到居然失败了这是为什么呢我们可以画图求解 到经过第三个整型的拷贝时我们发现了问题原本该被拷贝的5现在已经变成了3所以在7的位置放的是3在8的位置放的是4所以最后整个数组变成了这个样子    跟我们打印出来的样子一模一样那么怎么才能实现怎么内存重叠的拷贝呢这个就要用到我们马上要学习的memmove函数了    但是在学习memmove函数之前我们先插个题外话刚刚我们一直使用的是自己实现的memcpy无法处理内存重叠的情况那库里面的那个memcpy函数本尊呢能否实现我们来看看    可以看到神奇的事情发生了库里面的memcpy居然可以处理这种内存重叠的情况那是不是我们写的memcpy太挫了呢    很明显不是是因为C语言规定了memcpy只处理没有内存重叠的情况有内存重叠的情况交给memmove函数解决这里的memcpy函数又为什么能够解决这个问题呢    这个就涉及到编译器的问题了比如C语言规定memcpy只处理没有内存重叠的情况而VS的memcpy在处理了没有内存重叠的基础上还实现了有内存重叠的情况相当于老师只要求你考60分就能及格就能到达要求而你考了100分    所以不用担心是不是我们的momcpy函数实现的有问题我们实现的momcpy已经满足C语言的规定了已经合格了没有问题 二、memmove的使用和模拟实现 memmove函数相当于时memcpy函数的进阶版它不仅可以实现C语言规定的memcpy函数的功能处理没有内存重叠的情况还能处理存在内存重叠的情况使用它也需要包含头文件string.h    我们来看看memmove的原型 void * memmove ( void * destination, const void * source, size_t num );可以看到和memcpy的原型长得一模一样它们参数的含义和返回值都相同这样就不再赘述    我们可以总结一下它们的不同 和memcpy的差别就是memmove函数处理的源内存块和⽬标内存块是可以重叠的如果源空间和⽬标空间出现重叠就得使⽤memmove函数处理 接着我们首先来测试一下memmove能否实现memcpy的功能如下图    很明显我们看到memmove成功实现了接着我们继续用memmove测试让它替我们处理内存重叠的情况如下    可以看到memmove完美替我们解决了问题我们接下来就来学习它的模拟实现 函数命名my_memmove函数参数 void* my_memmove ( void* dest, const void* src, size_t num )函数实现 1老规矩对dest和src断言确保它们不是空指针 2然后创建一个变量start用来存储dest的值用于最后的返回 3我们来想想怎么解决内存重叠的情况根据之前的尝试我们知道根据memcpy那样实现肯定不行而memcpy实现时我们采用的是从前往后拷贝我们可以来尝试一下从后往前拷贝 4我们可以画一个图试试如下 很明显看到居然成功了说明这种情况从后往前进行拷贝是可以的那么是不是所有情况都可以这样呢我们接着继续讨论 5我们将上面的源空间和目标空间交换试一试: 这里就发现问题了再想从后往前拷贝一个整型时我们发现5和6都已经被覆盖了无法得到了正确结果所以光从后往前拷贝是行不通的 6经过简单的思考我们可以发现在上图的情况下从前往后进行拷贝居然又可以了问题就在于我们如何判断什么时候从前往后拷贝什么时候从后往前拷贝 7我们可以根据dest和src的位置判断当目标空间首地址dest在源空间首地址src前时就是分析的第5点中我们从前往后拷贝当目标空间首地址dest在源空间首地址src后面时也就是分析第4点中我们从后往前拷贝 8我们之前说过数组的空间是连续的并且随着下标的增大地址也是逐渐增大的所以我们可以发现当destsrc就正常从前往后拷贝当destsrc时就从后往前拷贝 9从前往后拷贝我们之前在memcpy讲过就不再赘述了如下 if (dest src){while (num--){*(char*)dest *(char*)src;dest (char*)dest 1;src (char*)src 1;}}10主要是要解决从后往后拷贝的问题关键就在于找到dest和src空间的末尾地址方法也很巧妙我们可以根据while(num–)当第一次进入循环num就已经-1了这时我们让dest和src加上num就可以得到dest和src空间的末尾地址这时就把src指向的内容赋值给dest指向的内容然后随着下一次num–dest和src加上num就跟着改变了依次类推就可以实现从后往前拷贝如下 else{while (num--){*((char*)dest num) *((char*)src num);}函数代码 #include assert.hvoid* my_memmove(void* dest, const void* src, size_t num) {assert(dest src);void* start dest;if (dest src){while (num--){*(char*)dest *(char*)src;dest (char*)dest 1;src (char*)src 1;}}else{while (num--){*((char*)dest num) *((char*)src num);}}return start; }函数测试    可以看到确实实现memmove的功能了 三、memset的使用 顾名思义memset就是设置内存它的作用就是一次性将num个字节全部置为某个值使用它需要包含头文件string.h我们来看看它的原型 void * memset ( void * ptr, int value, size_t num );它的第一个参数就是要设置的数组的首元素地址第二个参数是要设置的值第三个参数就是要设置多少个字节    我们要注意的是第二个参数是int类型的所以一般不会用在浮点型当中可以用在整型和字符型因为字符型本质上存储的是ascll码值也相当于整型    所以当数组是整型数组和字符数组时可以通过这个函数来设置它们的值    我们首先测试一下整型数组将所有数组的元素设置为0如图    使用起来是不是特别方便呢一般会用在竞赛或者项目中需要多组输入之类的使用完一个数组需要把它的元素都置为0    接下来我们想想能不能使用这个函数将数组中的所有元素更改为1如图    可以看到失败了这是为什么呢这是因为memset设置的单位是字节而整型有4个字节每一个字节都设置为1这个数就很大了我们来看看内存窗口如图    接下来我们再来测试将字符数组全部弄成字符’x’如图    可以看到memset连带着\0和空格都改成了字符x当然如果不想\0被改掉在写最后一个参数时可以-1    到这里我们就讲完了memset至于它的模拟实现可以自行去实现因为比较简单只需要一个字节一个字节将对应的内容改成给出的数据即可这里就不再赘述 四、memcmp的使用 它跟我们学习过的strncmp有点像strncmp可以根据给出的字节数来比较字符串的大小而memcmp是根据给出的字节数来比较各种类型的数据的大小使用它需要包含头文件string.h接下来我们来看看它的原型 int memcmp ( const void * ptr1, const void * ptr2, size_t num );可以看到它和strncmp的参数一模一样第一个参数是要比较的内容的首地址第二个也是如此第三个参数用来指定要比较的字节的个数而返回值也和strncmp的规则一样前一个大就返回大于0的数后一个大返回小于0的数相等则返回0    接下来我们就用它来比较一下整型数组如下 #include stdio.h #include string.hint main() {int arr1[] { 1,2,3,4,5,6,7,8,9,10 };int arr2[] { 1,2,3,3 };int ret memcmp(arr1, arr2, 4 * sizeof(int));printf(经过4个整型的比较);if (ret 0)printf(arr1更大\n);else if (ret 0)printf(arr2更大\n);elseprintf(arr1和arr2相等\n);return 0; }运行结果    在比较时还需要注意一点就是设置的要比较的字节数要有意义比如arr2现在只有4个整型数据如果要比较5个整型数据也就是20个字节就会读取到无效数据所以最好保证字节数有意义    那么它能否比较字符串呢我们可以来测试一下    可以看到memcmp也可以比较字符串至于memcmp的模拟实现可以自行完成也是一个一个字节去比较这里就不再赘述了    我们的内存函数讲解就到这里结束了如果有什么不懂的欢迎在评论区提问
http://www.hkea.cn/news/14413548/

相关文章:

  • 软件园二期做网站的公司有哪些广东建设项目备案公示网站
  • 网站建设 牛商网技术提供2345网址导航官方网站
  • 建设网站有什么作用是什么西安网络建设公司
  • 投资建设网站首页做网站 源代码
  • 网站建设是否包含等保做国际贸易哪个网站比较好
  • 怎样架设网站win2008做的网站打不开
  • 网站哪家做得好网站左边logo图标怎么做
  • 网站为何改版江宁区住房和城乡建设局网站
  • wordpress网站运行时间代码建设网站的风险分析
  • 手机网站如何制作免费设计公司推广渠道
  • 清远做网站哪家好营销网站的优势是什么
  • 山东微商网站建设做类似淘宝的网站
  • 怎么建自己的销售网站在手机制作网站
  • 网站引导页下载石材做网站
  • 资阳网站建设资阳wordpress 维护插件
  • 找培训学校去哪个网站环保网站模板 html
  • 网站设置银联密码wordpress注册简化
  • 福田我要做网站优化比较好百度关键词推广一年多少钱
  • 义县网站建设百度搜索站长平台
  • win不用iis做网站云南网站设计方案
  • 产品单页营销型网站模板下载平面设计类的网站
  • 一个网站的建立需要什么小程序网站建设
  • 邢台手机网站建设地方wordpress淘宝客自适应模板
  • 品牌宣传网站有哪些网络推广软文是一种很好的推广方式
  • 阿里云 外贸网站ui网页设计是什么
  • 怎么建设公益网站网站备案 英文
  • 苏州做学校网站的网站设计和营销
  • 动漫电影做英语教学视频网站简述电子商务网站建设的过程
  • 手机端网站如何做排名西安好玩的地方有哪些
  • 大旺建设局网站做网站一般用什么几号字