微软自带的strcpy函数: (不完善,4分)
- char * strcpy(char * dest,const char *src)
- {
- char *tmp = dest;
- while ((*dest++ = *src++) != '\0')
- return tmp;
- }
最完善的strcpy函数: (推荐使用,10分)
- char * strcpy( char *dest, const char *src ) //将源字符串加const,表明其为输入参数不能修改
- {
- if(dest == src) //考虑到源字符串和目的字符串有重叠,也即地址相同
- {
- return dest;
- }
- assert( (dest != NULL) && (src != NULL) ); //对源地址和目的地址加非空地址断言
- char *tmp = dest; //备份目的字符串的首地址,由于后面的操作会修改dest值
- while( (*dest++ = * src++) != '\0' );
- return tmp; //为了实现链式操作,将目的地址返回,获得函数返回值;
- }
推荐的原因:(看得分点)
- //得2分
- void strcpy( char *dest, char *src )
- {
- while( (*dest++ = * src++) != '\0' );
- }
- //得4分
- void strcpy( char *dest, const char *src )
- {
- //将源字符串加const,表明其为输入参数,加2分
- while( (*dest++ = * src++) != '\0' );
- }
- //得7分
- void strcpy(char *dest, const char *src)
- {
- //对源地址和目的地址加非0断言,加3分
- assert( (dest != NULL) && (src != NULL) );
- while( (*dest++ = * src++) != '\0' );
- }
- //得9分
- //为了实现链式操作,将目的地址返回,加2分!
- char * strcpy( char *dest, const char *src )
- {
- assert( (dest != NULL) && (src != NULL) );
- char *tmp = dest;
- while( (*dest++ = * src++) != '\0' );
- return tmp;
- }
- //得10分,基本上所有的情况,都考虑到了
- //如果有考虑到源目所指区域有重叠的情况,加1分!
- char * strcpy( char *dest, const char *src )
- {
- if(dest == src) { return dest; }
- assert( (dest != NULL) && (src != NULL) );
- char *tmp = dest;
- while( (*dest++ = * src++) != '\0' );
- return tmp;
- }
两者比较说明 :
1)微软提供的字符串源码由于去掉了一些啰嗦的安全性检查,使其代码变的相当简单,提高了性能;
2)所推荐的程序,适用于我们经常做的Debug版本,涉及了一些安全性检查,提高程序的健壮性,这些都是程序员所需考虑的。
assert总结
assert"断言"的理解及使用:
a. 断言,也即做出一些假设,假设该表达式是正确的,若程序运行正确,该断言程序成立;若断言的表达式不成立,程序运行一定会出错,整个程序就会退出。多用于Debug调试,且能快速定位错误位置;
assert(表达式);
如果表达式的值为假,整个程序将退出,并输出一条错误信息。如果表达式的值为真则继续执行后面的语句。
b. assert是宏,而不是函数,使用这个宏需要添加头文件 #include <assert.h>
c. assert 与 if的区别:
if : 条件成立继续执行、条件不成立也继续执行。
assert:条件成立继续执行、 条件不成立停止执行 。
简单例子测试,对除数为0进行断言演示
补充——strcpy函数使用易错点