多种方式实现strcpy
普通写法
#include<stdio.h>void new_strcpy(char *arr1,char *arr2){while (*(arr2 - 1) != '\0'){*arr1 = *arr2; arr1++; arr2++;}//或者while (*arr2 != '\0'){*arr1 = *arr2; arr1++; arr2++;}*arr1 = *arr2;}int main(){char arr1[20] = "ppppppppppp";char arr2[] = "hello world";new_strcpy(arr1, arr2);printf("%s", arr1);return 0;}
既然是后置++,那么我们可以直接将它与上面的代码合并。
void new_strcpy(char *arr1,char *arr2){while (*arr2 != '\0'){*arr1++ = *arr2++;//后置++的优先级虽比*高,但因会先使用后++,所以可以这样写。}}
更厉害的写法是下面这种
void new_strcpy(char *arr1,char *arr2){while (*arr1++ = *arr2++)//非0即为真,当arr2为‘\0’时while循环也就停止了{;}}
但上面的写法都有点缺陷,假设主函数不是直接传址,而是传的指针呢,且由于粗心未将地址赋给指针,直接以空指针的形式来传过去就会崩溃
比如
int main(){char arr1[20] = "ppppppppppp";char arr2[] = "hello world";char* p=NULL;new_strcpy(arr1, p);printf("%s", arr1);return 0;}
为避免上述情况,可以在new_strcpy中加入断言
assert() :当括号中表达式为真,什么都不会发生,程序正常运行,当表达式为假就会报错。(使用assert需要引头文件assert.h)
void new_strcpy(char *arr1,char *arr2){assert(arr1 != NULL);assert(arr2 != NULL);while (*arr1++ = *arr2++){;}}
在MSDN中可以看到strcpy其实是有返回值的
Return Value
Each of these functions returns the destination string. No return value is reserved to indicate an error.
其返回值是目标字符串的首地址
最后再拓展一下
int a=0;int b=0;int * p = &a;若const在*的左面(const int * p = &a或int const * p = &a), 则const修饰的是指针指向的内容,不能通过指针改变,但指针变量可以更改 (即以指针的形式无法修改a的值,但可以更改p的值)。 若const在*的右面(int * const p=&a),则const修饰的是指针本身, 指针变量本身不能修改,指针指向的内容,可以通过指针改变, (即以指针的形式可以修改a的值,但无法更改p的值)。
那么终版的strcpy就是下面的啦!!!
#include<stdio.h>#include<assert.h>char* new_strcpy(char *arr1,const char *arr2)//为防止在while循环那里arr1和arr2顺序写反,将arr设为const,即无法改变的常变量{char* ret = arr1;assert(arr1 != NULL);assert(arr2 != NULL);while (*arr1++ = *arr2++){;}return ret;}int main(){char arr1[20] = "ppppppppppp";char arr2[] = "hello world";char *p=arr2;printf("%s\n", new_strcpy(arr1, p));//通过利用strcpy的返回值是arr1的首地址进行链式访问return 0;}
目标数组空间必须给足,否则会造成越界访问