在网上翻阅一些博客,感觉其中很多文章的代码都不能通过编译和正确运行,同时很多面试类书籍上的代码也是有问题的。
下面给出三个函数的代码实现,保证了健壮性,给出了注释,并做了测试通过。
memcpy()
/******************************************
@健壮的内存拷贝函数以及测试
@xiaolewen_bupt
@ 2016-4-3
*******************************************/
#include <iostream>
#include <stdlib.h>
#include <assert.h>
using namespace std;
void* memcpy_(void* dst,const void* src,int count) //还是那句话,在传入变量时用const
{
assert(dst!=NULL && src!=NULL); //首先不能传入空指针
unsigned char* dst_tmp = (unsigned char *)dst; //这句很重要,首先做一次类型强转,因为void* 类型的指针无法进行算数运算
unsigned char* src_tmp = (unsigned char *)src; //编译器直接报错:error: arithmetic on a pointer to void
assert(!(dst_tmp<=src_tmp && dst_tmp+count>src_tmp)); //地址不能有重叠,分两种情况进行考虑
assert(!(dst_tmp>=src_tmp && src_tmp+count>dst_tmp));
while(count--)
{
*dst_tmp = *src_tmp;
dst_tmp++;
src_tmp++;
}
return dst;
}
typedef struct A
{
int a;
char b;
}A;
int main(int argc, char const *argv[])
{
A instance_of_A;
instance_of_A.a=0;
instance_of_A.b='h';
A* ptr1=&instance_of_A;
A* ptr2=(A*)malloc(sizeof(A));
memcpy_(ptr2,ptr1,sizeof(A));
cout<<ptr2->a<<endl;
cout<<ptr1->b<<endl;
return 0;
}
strcpy()
#include <iostream>
using namespace std;
#include <assert.h>
char *strcpy_(char *dst,const char *src)
{
assert(dst!=NULL && src!=NULL);
char *dst_tmp=dst;
while((*dst++ = *src++)!='\0');
return dst_tmp;
}
int main(int argc, char const *argv[])
{
char a[10];
const char *b="abcde";
strcpy_(a,b);
cout<<a<<endl;
return 0;
}
strcat()
#include <iostream>
using namespace std;
#include <assert.h>
char* strcat_(char *dst,const char *src)
{
assert(dst!=NULL & src!=NULL);
char *dst_tmp=dst;
while(*dst!='\0')
dst++; //指针++是根据实际指向的类型长度++的
while((*dst++ = *src++) != '\0');
*dst='\0';
return dst_tmp;
}
int main(int argc, char const *argv[])
{
char a[10]="abcde";
const char *b="fgh";
strcat_(a,b);
cout<<a<<endl;
return 0;
}