之前我们讲过一些字符串函数(http://t.csdnimg.cn/ZcvCo),今天我们来讲一讲几个内存函数,那么可能有人要问了,都有字符串函数了,怎么又来个内存函数,这不是一样的么?
我们要知道之前的字符串函数只能对字符串进行一系列操作很是局限,这次的内存函数就不一样了,内存函数的范围就很广了,它可以对数组啊,或者是结构体进行操作了。
memcpy函数
它是一个内存拷贝函数,类似于字符串函数strcpy。
memcpy的头文件是<string.h>
int main() { int arr1[10] = { 0 }; int arr2[] = { 1,2,3,4,5 }; memcpy(arr1, arr2, 20 ); return 0; }
1、上面的例子就是两个数组,传的也是整形,所以就不能用strcpy,所以就体现了memcpy的重要性和通用性。
2、这个num一定要注意是字节的大小,所以上面的例子传了5个整数int,所以字节大小就是20。
那么我们该如何对他进行模拟实现呢?🤔🤔🤔
void* my_memcpy(void* dest,void* src,size_t sz) { assert(dest && src); void* ret = dest while (sz--) { *(char*)dest = *(char*)src; dest = (char*)dest+1; src = (char*)src + 1; } return ret; } int main() { int arr1[10] = { 0 }; int arr2[] = { 1,2,3,4,5 }; my_memcpy(arr1, arr2, 20 ); return 0; }
这里我们进行了一个模拟实现:
1、首先我们因为要考虑传的参数都可能不同,所以为了通用性,我们这里用void*来接受各种类型的指针。
2、其次当进行拷贝的时候,由于是一个字节一个字节进行的,所以我们只能转换成(char*)来进行交换。
3、交换完之后,我们还需要将dest和src进行后移,移动到下一个字节待交换,因为强制类型转换是临时性的,所以这里在进行移动的时候还需要进行一次强制类型转换。
4、sz是总字节大小,所以用做循环的变量,来控制循环。
memmove函数
刚刚的memcpy函数是用来进行,两个之间的拷贝,那么这个memove函数是用来进行同一个内存块的拷贝。
int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; memmove(arr+2, arr, 12 ); return 0; }
思考memmove的模拟实现
但是这个思路到底能否实现呢?🤔🤔🤔
那么只是用从后向前拷贝就可以解决所有问题么?
所以这个我们就要进行分类讨论了
可以看到上面这个图,我们可以看到,最后通过我们的分析可以知道,我们当dest<src时要进行从前向后拷贝,dest>src时要进行从后向前拷贝。
那么我们来实现一下代码:
void* my_memmove(void* dest, void* src, size_t sz) { assert(dest && src); void* ret = dest; while (sz--) { if (dest < src) { *(char*)dest = *(char*)src; dest = (char*)dest + 1; src = (char*)src + 1; } else { *((char*)dest + sz) = *((char*)src + sz); } } return ret; } int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; my_memmove(arr+2, arr, 12 ); return 0; }
我们用while循环sz为循环变量,当dest<src的时候我们就将其正常拷贝就可以了 ,否则的话我们用dest和src分别加sz就到了数组的后面,然后随着sz的递减,我们就实现了从后向前拷贝。
memset函数
这个函数可以将内存块进行指定更改,例如:
我们可以看到arr代表首元素地址,所以从数组第一个1开始,向后的12个字节,也就是3个int整形,所以我们看到内存里面的前三个被替换成了0。
另外也可以替换字符串
int main() { char arr[] = { "Hello world" }; memset(arr+6 ,'x', 3); printf("%s", arr); return 0; }
我们可以替换字符串就像这样
但是当用这个函数的时候有一个点:
int main() { int arr[] = { 1,2,3,4,5,6 }; memset(arr+1 ,1, 8); return 0; }
这个函数我们想要把2,3也都变成1,但是我们运行结果却不是
我们发现并不是更改成了1,当我们用16进制看的时候会发现:
它是将每一个字节都更改成了1,所以导致最后的值很大。
memcmp函数
可以看到,由于memcmp是按照字节比较的所以,当我们取前三个元素的字节时,arr1和arr2都是一样的,所以输出结果就是0。
但是当我改成:
07比04大所以,arr2大于arr1返回的是小于0的值。
感谢大家的观看!!!我们下次再见🌹🌹🌹