实现memmove函数时的原理:
#include <stdio.h>
#include <assert.h>void * my_memmove(void * dst,const void *src, int count)
{
assert(dst);
assert(src);
register char * d_st = (char*)dst; //第一个变量和最后一个形参差16个字节,是因为assert函数分别入栈了俩个地址,每个地址占据4个字节,所以差距16个字节。
register char * s_rc = (char*)src; // 在 ANSI 标准下 void型指针 被 其他类型指针赋值时必须要强行转化, 在vs 2013 下虽然不需要强行转化。
register char * d_st_end = d_st + count - 1; // 但是在gcc下编辑时 会报错需要类型转换。 所以 加上 强行转化 可以增加代码的通用性。
register char * s_rc_end = s_rc + count - 1; // 因为char 类型是1个字节,所以void * 指针赋给char * 指针时 指向的存储空间可以一个字节一个字节赋值.
void * ret = d_st;
if (d_st <= s_rc || s_rc + count <= d_st)
{
while (count--)
{
*d_st++ = *s_rc++; // 所以前三个情况从前拷贝
}
}
else
{
while (count--)
{
*d_st_end-- = *s_rc_end--; // 最后一个情况从后往前拷贝
}
}
return ret;
}
int main()
{
int p[] = { 1, 2, 3, 4, 5 };
int arr[10];
my_memmove(arr, p, sizeof(int)* 5);
printf("%d", arr[2]);
system("pause");
return 0;
}
最后附上 在linux下用gcc编写此程序没有强行转化显示的错误: