1. strcpy函数:'\0'也拷贝,然后结束


  
  1. //自定义
  2. #include <stdio.h>  
  3. char* strcpy(char*dest,const char *src)  
  4. {  
  5.     char* d=dest;  
  6.     while(*d++=*src++);  
  7.     return dest;  
  8. }  
  9. int main(void)  
  10. {  
  11.     char str[20]="aaaaaaaaaaaaaaa";  
  12.     char *p="worlddsfg";  
  13.     strcpy(str,p);  
  14.     printf("%s\n",str);  
  15.     return 0;  

     linux内核中的lib/string.c文件中的实现方法:


  
  1. char *strcpy(char *dest, const char *src)   
  2. {   
  3.     char *tmp = dest;   
  4.    
  5.     while ((*dest++ = *src++) != '\0')   
  6.         /* nothing */;   
  7.     return tmp;   

2. memcpy实现


  
  1. #include <stdio.h>  
  2.    
  3. void* mymemcpy(void* dest,const void* src,size_t size)  
  4. {  
  5.     if(dest==NULL || src==NULL)  
  6.         return (void*)0;  
  7. if((char*)dest==(char*)src)
  8. return dest;    
  9.     char* d=(char*)dest;  
  10.     const char* s=(char*)src;  
  11.     while(size--)  
  12.         *d++=*s++;        
  13.     return dest;  
  14. }  
  15.  
  16. int main(void)  
  17. {  
  18.     char str[20]="hello";  
  19.     char *p="";  
  20.     mymemcpy(str,p,0);  
  21.     printf("%s\n",str);  
  22.     return 0;  
  23. }  
  24. //或使用  
  25. void* mymemcpy(void* dest,const void* src,size_t size)  
  26. {  
  27.     assert((src!=NULL)&&(dest!=NULL));  
  28.     char* d=(char*)dest;  
  29.     const char* s=(char*)src;  
  30.     while(size--)  
  31.         *d++=*s++;        
  32.     return dest;  

     一般出题目让你实现memcpy,个人理解,其意图至少有以下几点:
    1.写任何程序都能反映出你的代码风格。
    2.考查你是否注意到,要拷贝的源,即const void* src,应该是用const的,避免有意或无意的修改。
    3.指针的类型转化问题,原始参数应该是void *的,你具体操作的时候,应该是转化为某种具体的类型,此处用char比较适合。
    4.注意要判断源src是否和dest重复,如果重复,直接返回或返回错误。

3. memmove实现


  
  1. #include <stdio.h>  
  2.    
  3. void* mymemmove(void* dest,const void* src,size_t size)  
  4. {     
  5.     if(size==0)  
  6.         return (void*)0;  
  7.     if(dest==NULL || src==NULL)  
  8.         return (void*)0;  
  9.     char *d=(char*)dest;  
  10.     const char *s=(char*)src;  
  11.     if(d<=s || d>=s+size)//检查是否有重叠问题  
  12.     {  
  13.         while(size--)//正向拷贝  
  14.          *d++=*s++;  
  15.     }  
  16.     else            //反向拷贝  
  17.     {  
  18.         while(--size >= 0) //此处有bug   
  19.         {  
  20.             *(d+size)=*(s+size);  
  21.             printf("*%s*%d*%u\n",src,size,size);  
  22.         }  
  23.     }  
  24.     return dest;  
  25. }  
  26.  
  27. int main(void)  
  28. {  
  29.     char str[20]="hellohui";  
  30.     char *p="worldhui";  
  31.     mymemmove(str+2,str,3);  
  32.     printf("%s\n",str);  
  33.     return 0;  
  34. }  
  35.    
  36.  
  37.  

    以上程序有bug,当反向拷贝时,执行到while(--size>=0) 处会出现无限循环,因为size为size_t类型,即typedef unsigned int size; 所以size永远是大于等于0,则while一直循环。
    错误结果为:
 

    从%u的输出可看出都为大于0,所以不会退出循环。
    修改后为:


  
  1. #include <stdio.h>  
  2.    
  3. void* mymemmove(void* dest,const void* src,size_t size)  
  4. {     
  5.     if(size==0)  
  6.         return (void*)0;  
  7.     if(dest==NULL || src==NULL)  
  8.         return (void*)0;  
  9.     char *d=(char*)dest;  
  10.     const char *s=(char*)src;  
  11.     if(d<=s || d>=s+size)//检查是否有重叠问题  
  12.     {  
  13.         while(size--)//正向拷贝  
  14.             *d++=*s++;  
  15.     }  
  16.     else            //反向拷贝  
  17.     {  
  18.         d+=size-1;  
  19.         s+=size-1;  
  20.         while(size--)  //修改后          
  21.             *d--=*s--;  
  22.     }  
  23.     return dest;  
  24. }  
  25. int main(void)  
  26. {  
  27.     char str[20]="hellohui";  
  28.     char *p="worldhui";  
  29.     mymemmove(str+2,str,3);  
  30.     printf("%s\n",str);  
  31.     return 0;