Chinaunix首页 | 论坛 | 博客
  • 博客访问: 153462
  • 博文数量: 31
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 903
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-11 15:05
个人简介

Never say die!

文章分类

全部博文(31)

文章存档

2014年(31)

分类: C/C++

2014-11-08 19:50:37

微软自带的strcpy函数: (不完善,4分)


点击(此处)折叠或打开

  1. char * strcpy(char * dest,const char *src)
  2. {
  3.     char *tmp = dest;

  4.     while ((*dest++ = *src++) != '\0')
  5.         
  6.     return tmp;
  7. }


最完善的strcpy函数: (推荐使用,10分)


点击(此处)折叠或打开

  1. char * strcpy( char *dest, const char *src ) //将源字符串加const,表明其为输入参数不能修改
  2. {
  3.     if(dest == src)     //考虑到源字符串和目的字符串有重叠,也即地址相同
  4.     {
  5.         return dest;
  6.     }

  7.     assert( (dest != NULL) && (src != NULL) ); //对源地址和目的地址加非空地址断言
  8.     
  9.     char *tmp = dest; //备份目的字符串的首地址,由于后面的操作会修改dest值
  10.     
  11.     while( (*dest++ = * src++) != '\0' );
  12.     
  13.     return tmp; //为了实现链式操作,将目的地址返回,获得函数返回值;

  14. }

推荐的原因:(看得分点)


点击(此处)折叠或打开

  1. //得2分
  2. void strcpy( char *dest, char *src )
  3. {
  4.     while( (*dest++ = * src++) != '\0' );
  5. }
  6.   
  7. //得4分
  8. void strcpy( char *dest, const char *src )
  9. {
  10.     //将源字符串加const,表明其为输入参数,加2分
  11.     while( (*dest++ = * src++) != '\0' );
  12. }
  13.   
  14. //得7分
  15. void strcpy(char *dest, const char *src)
  16. {
  17.     //对源地址和目的地址加非0断言,加3分
  18.     assert( (dest != NULL) && (src != NULL) );
  19.     while( (*dest++ = * src++) != '\0' );
  20. }
  21.   
  22. //得9分
  23. //为了实现链式操作,将目的地址返回,加2分!
  24. char * strcpy( char *dest, const char *src )
  25. {
  26.     assert( (dest != NULL) && (src != NULL) );
  27.     char *tmp = dest;
  28.     while( (*dest++ = * src++) != '\0' );
  29.     return tmp;
  30. }
  31.   
  32. //得10分,基本上所有的情况,都考虑到了
  33. //如果有考虑到源目所指区域有重叠的情况,加1分!
  34. char * strcpy( char *dest, const char *src )
  35. {
  36.     if(dest == src) { return dest; }
  37.     assert( (dest != NULL) && (src != NULL) );
  38.     char *tmp = dest;
  39.     while( (*dest++ = * src++) != '\0' );
  40.     return tmp;
  41. }

assert总结


assert"断言"的理解及使用:

a. 断言,也即做出一些假设,假设该表达式是正确的,若程序运行正确,该断言程序成立;若断言的表达式不成立,程序运行一定会出错,整个程序就会退出。多用于Debug调试,且能快速定位错误位置;

assert(表达式);

如果表达式的值为假,整个程序将退出,并输出一条错误信息。如果表达式的值为真则继续执行后面的语句。


b. assert是宏,而不是函数,使用这个宏需要添加头文件 #include


c. assert 与 if的区别:

if : 条件成立继续执行、条件不成立也继续执行。

assert:条件成立继续执行、 条件不成立停止执行 


补充——strcpy函数使用易错点



说明: 
可能大家按照我上面的测试,结果与上面的不一致,那我解释一下:  代码运行环境是linux系统,默认会对栈进行保护,上面所涉及的问题就不用考虑了,如果想看到上面的效果,需要去掉栈保护,也即在进行gcc编译的时候,加上-fno-stack-protector


阅读(10912) | 评论(4) | 转发(3) |
给主人留下些什么吧!~~

Super_Joki2015-02-02 14:13:08

cjs520_cu:楼主,例子2打印的结果我的和你不一样,我实验得出的结果都是123456

我在linux系统下进行测试的,linux系统默认对栈进行了保护,如果想得到我上面的结果,需要去掉栈保护,也即在编译的时候加上-fno-stack-protector

回复 | 举报

KR_201412072014-12-08 16:13:14

银行的金库里有个张三只负责搬钱,送钱来了,就拼命把钱从车里往仓库里搬。要运钱走了,就拼命把钱往车上搬。其他一概不管,日子过得无忧无虑的。直到有一天,运钞车运来的钞票里有几张假钞,也被搬到仓库里存起来了。后来这几张假钞被查出来了。领导二话不说,把张三大骂一通:你怎么就知道搬钱?你就不会先检验一下钱的真假再搬?检查到有假钞你就不用搬了呀?不检查搬进来假钞怎么办?张三心想:一个银行,不确定钱的真假就敢把钱往金库运,还要我一个搬钞的来验钞,这样的领导脑子有毛病吧。

cjs520_cu2014-11-22 17:08:42

当然你前面一部分我受益匪浅,谢谢楼主!只是我仍然有一个忧虑,就是strcpy本身无法对目标字符串的长度是否大于源字符串长度做出判断,看来这个只有放在被调的函数里面进行判断了???

cjs520_cu2014-11-22 17:06:21

楼主,例子2打印的结果我的和你不一样,我实验得出的结果都是123456