企业网站seo推广技巧,互联网基础知识入门,设计师网络接单,cdn网站加速目录
一. C语言内存操作函数
1. memcpy的使用和模拟实现
2. memmove函数
3. memset函数
4. memcmp函数 一. C语言内存操作函数
随着知识的不断积累#xff0c;我们所想要实现的目标程序就会更加复杂#xff0c;今天我们来学习一个新的知识叫做C语言内存操作函数#x…目录
一. C语言内存操作函数
1. memcpy的使用和模拟实现
2. memmove函数
3. memset函数
4. memcmp函数 一. C语言内存操作函数
随着知识的不断积累我们所想要实现的目标程序就会更加复杂今天我们来学习一个新的知识叫做C语言内存操作函数它是C语言标准库中提供的一系列对内存进行操作的函数。比如对于内存的复制内存的设置以及内存的比较这些函数都是针对内存块来处理的为程序员提供了更加安全高效和灵活的方式让程序员能够对内存进行各种常见的操作和处理下面就让我们来详细了解一下吧。
1. memcpy的使用和模拟实现
首先我们来认识memcpy函数它的原型是void* memcpy(void* destination, const void* soure,size_t num)作用就是内容的复制从soure的位置开始向后复制num个字节(注意单位是字节)的数据到destination指向的内存位置。这个函数遇到/0的时候并不会停下来。并且destination和soure有任何的重叠复制的结果都是未定义的。下面给出大家实际的例子
#include stdio.h
#include string.h
int main()
{int arr1[] { 1,2,3,4,5,6,7,8,9,10 };int arr2[10] { 0 };memcpy(arr2, arr1, 20);int i 0;for (i 0; i 10; i){printf(%d , arr2[i]);}return 0;
} 对于运行结果来说我们也可以看出来如果num小于实际输出的数量那么后面都是用0来补的大家下去可以自己多尝试进行练习。
如何模拟实现memecpy函数呢
#include assert.h
void* my_memcpy(void* str1, const void* str2, size_t num)
{void* ret str1;assert(str1);assert(str2);/** copy from lower addresses to higher addresses*/while (num--) {*(char*)str1 *(char*)str2;str1 (char*)str1 1;str2 (char*)str2 1;}return(ret);
}
int main()
{int arr1[10] { 1,2,3,4,5,6,7,8,9,10 };int arr2[10] { 0 };my_memcpy(arr2, arr1, 40);int i 0;for (i 0; i 10; i){printf(%d , arr2[i]);}return 0;
}
在我们模拟实现的过程中在开始的时候我们要注意两个指针不能是空指针需要assert进行断言我们为什么要进行强制类型转换成char*呢首先我们要明确memcpy函数传入第三个参数size_t num是字节的个数所以当我们强制类型转换的时候会更加方便去计算另外就是我们的指针是void*类型的是不能直接进行加减运算的最终返回一个void*的指针。
2. memmove函数
接下来认识memmove函数它的原型是void* memmove(void* destination,const void* scoure,size_t num)原型与memcpy函数是一模一样的所以说其实memmove函数与memcpy函数的区别就是memmove函数可以处理重叠部分。也就是说如果源空间也目标空间出现重叠的话我们就使用memmove函数来处理。给大家举一个例子说明
#include stdio.h
#include string.h
int main()
{int arr1[] { 1,2,3,4,5,6,7,8,9,10 };memmove(arr1 2, arr1, 20);int i 0;for (i 0; i 10; i){printf(%d , arr1[i]);}return 0;
} 其实对于我们memmove函数的实现其实是更复杂的那么我们究竟要如何实现它呢大家看下面面的四种情况
sour代表的是源空间des代表的是目标函数大家认真看第一个如果我们将sour里面的内容复制到des中我们可以直接按顺序将34567依次放入12345中最终我们的打印结果就是3 4 5 6 7 6 7 8 9 10但是我们来看第三种如果我们将34567按顺序放在56789中我们会发现当我们放完3和4之后原本的5和6就会变成3和4那么原来应该把5和6放在7和8位置上的计划就不能实现所以这样放是不对的但我们换一种方法我们先将7放入9再将6放入8也就是从后面往前面放置对于第四种来说从前往后和从后往前都是一样的。所以我给出大家一张图来更好的说明我们的数组有高低地址之分也就是说当我们的des小于sour的时候我们选择从前往后除此之外我们选择从前往后所以了解了底层的逻辑下面我们就开始设计我们的代码
#include stdio.h
#include string.h
#include assert.h
void* my_memmove(void* dest, const void* sour, size_t num)
{assert(dest sour);void* ret dest;if (dest sour)//从前往后{while (num--){*(char*)dest *(char*)sour;dest (char*)dest 1;sour (char*)sour 1;}}else//从后往前{while (num--){*((char*)dest num) *((char*)sour num);}}return ret;};int main()
{int arr1[] { 1,2,3,4,5,6,7,8,9,10 };my_memmove(arr1 2, arr1, 20);int i 0;for (i 0; i 10; i){printf(%d , arr1[i]);}return 0;
}
但是可能细心的同学会发现我们就算使用memcpy函数也能够实现重叠部分的程序运算但是我们在C语言中更推荐规范使用如果有重叠部分的就使用memmove函数虽然我们在VS的编译器上用memcpy来处理重叠部分可以成功但是在其他编译器上却不一定所以我们尽量的规范使用。
3. memset函数
memset函数是用来设置内存的将内存中的值以字节为单位设置成想要的内容。它的原型是void* memset(void* ptr,int value,size_t num);ptr就指向要被填充的内存块指针value要设置的内容num就表示要设置成多少个字节。
#include stdio.h
#include string.h
int main ()
{char str[] hello world;memset (str,x,6);printf(str);return 0; 4. memcmp函数
memcmp函数是用来比较两个指针大小的它的原型是int memcmp(const void* ptr1,const void* ptr2,size_t num)就是对内存块ptr1和ptr2进行比较比较从ptr1和ptr2指针指向的位置开始向后的num个字节注意也是以字节为单位当ptr1ptr2的时候返回大于0的值当两个相等的时候返回0当ptr1ptr2的时候返回小于0的值。
#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);elseprintf(%s is the same as %s.\n, buffer1, buffer2);return 0;