字符串系列(三)--- 内存操作函数
前言
本文将详细介绍内存操作函数的使用及其实现方法
一、内存操作函数
1、memcpy --内存拷贝函数
首先看下C语言库函数中对于这个函数的定义,void *memcpy( void *dest, const void *src, size_t count );首先,就和字符串不同了,字符串的函数参数类型是char * ,而内存操作函数时void *,可操作的操作数更多。如果重叠则函数未定义。如何使用?看以下代码
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "hello bit";
char arr2[] = "welcome";
printf("%s", (char*)memcpy(arr1, arr2, 7));
return 0;
}
(2)自己实现
实际上对于这个函数,库函数设计的是可以接收任意字符的,那再设计函数就不能说指针往后遍历一步是4个字节或者8个字节,而是统一设计成一个字节,一个字节一个字节的进行交换
#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dest, void* src, int num)
{
assert(dest && src);
void* start = dest;
char tmp = 0;
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return start;
}
int main()
{
int arr1[] = { 1,2,3,4,5 };
int arr2[] = { 2,3,4,5,6 };
int k = 0;
scanf("%d", &k);
int *p = (int*) my_memcpy(arr1, arr2, k);
int i = 0;
for (i = 0; i < 5; i++)
{
printf("%d", *(p + i));
}
return 0;
}
2、memmove – 全能函数
首先看下C语言中对于memmove的定义,void *memmove( void *dest, const void *src, size_t count );
和memcpy是相同的,唯一不同的是,memmove可以处理重叠的区域移动和复制。
#include<string.h>
#include<stdio.h>
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[] = { 1,1,1,1,1 };
int* p = memmove(arr1, arr1+2, 20);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", *(p + i));
}
return 0;
}
(2)自己实现
这个函数是比较难的,首先dest指针和src指针指向的内存空间是不清楚的,就应该分类讨论。如果dest在src左边,看下图
如果src 和 dest 相同呢?那也是第一种方法。
但是如果src小于dest,就是目标地址在右边,源地址在左边,看下图
因为我如果还是按照上面的依次往后面复制,那么会把本来要拷贝的456覆盖了
代码如何实现呢?
#include<stdio.h>
#include<assert.h>
void* my_memmove(void* dest, void* src, int num)
{
assert(dest && src);
void* start = dest;
char tmp = 0;
if (dest <= src)
{
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else
{
for (int i = num - 1; i >= 0; i--)
{
*((char*)dest + i) = *((char*)src + i);
}
}
return start;
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[] = { 1,1,1,1,1 };
int k = 0;
scanf("%d", &k);
int* p = (int*)my_memmove(arr1 + 3, arr1, k);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", *(p - 3 + i));
}
return 0;
}
3、memcmp
首先来看下C语言库函数对于这个函数的定义
int memcmp( const void *buf1, const void *buf2, size_t count );
返回类型是int ,buf1和buf2是两个要比较的地址,count是要比较的字节数量,注意,所有的操作都是在内存中进行的比较。
#include<stdio.h>
#include<string.h>
int main()
{
int arr1[] = { 1,2,3,4,5 };
int arr2[] = { 1,2,3,5,6 };
int k = 0;
scanf("%d", &k);
printf("%d", memcmp(arr1, arr2, k));
return 0;
}
比方我比较前12个字节,也就是前三个整型,是一样的
前13个字节呢?在第13个字节是不是就不一样了,就是04小于05了,所以会输出-1
(2)自己实现
其实实现方法和strcmp是很像的,只是函数参数需要处理,看代码
#include<stdio.h>
int my_memcmp(const void* buf1, const void* buf2, int k)
{
int signel = 0;
while (k--)
{
if (*(char*)buf1 == *(char*)buf2)
{
if (*(char*)buf1 != *(char*)buf2)
{
signel = 1;
break;
}
buf1 = (char*)buf1 + 1;
buf2 = (char*)buf2 + 1;
}
else //如果第1个就不相同而的情况
{
signel = 1;
break;
}
}
if (signel == 0)
return 0;
else
{
if (*(char*)buf1 > *(char*)buf2)
return 1;
else
return -1;
}
}
int main()
{
int arr1[] = { 1,2,3,4,5 };
int arr2[] = { 1,2,3,5,6 };
int k = 0;
scanf("%d", &k);
printf("%d", my_memcmp(arr1, arr2, k));
return 0;
}
总结
字符串系列就正式完结了,如果喜欢,还请给博主点下关注和大大的赞。下一个系列是自定义类型讲解。