手写代码的能力要锻炼啊,面试被问到这样的问题了,总结一下:
#include<stdio.h>
#include<string.h>
char s[123]={"1233232"},str[123];
char* strcpy(char *to,char *from){
if(NULL==to||NULL==from) //不检查指针的有效性,说明答题者不注重代码的健壮性。
throw "point error"; //应该以抛出异常来代替返回值,这样可以减轻调用者的负担、使错误不会被忽略、增强程序的可维护性。
int i;
for(i=0;from[i]!='\0';++i){//直接使用字面常量(如本例中的0)会减少程序的可维护性
to[i]=from[i];
}
return to;//return 0;,说明答题者没有掌握异常机制。调用者有可能忘记检查返回值,调用者还可能无法检查返回值
}
int main(){
printf("%s\n",s);
strcpy(str,s);
printf("%s\n",str);
}
【增加】一个看起来很不错的代码,不过我不是非常懂,博主写的分析和注意事项放在这里提醒自己
<pre name="code" class="cpp">#include <assert.h>
#include <stdio.h>
char* strcpy(char* des, const char* src)
{
assert((des!=NULL) && (src!=NULL));
char *address = des;
while((*des++ = *src++) != '\0')
;
return address;
}
要知道 strcpy 会拷贝’\0’,还有要注意:
-
源指针所指的字符串内容是不能修改的,因此应该声明为 const 类型。
-
要判断源指针和目的指针为空的情况,思维要严谨,这里使用
assert
(见文末)。 -
要用一个临时变量保存目的串的首地址,最后返回这个首地址。
-
函数返回 char* 的目的是为了支持链式表达式,即strcpy可以作为其他函数的实参。
2、字符串长度strlen
函数strlen
的原型是size_t strlen(const char *s)
,其中 size_t 就是 unsigned int。
1 2 3 4 5 6 7 8 9 10 11 | #include <assert.h> #include <stdio.h> int strlen(const char* str) { assert(str != NULL); int len = 0; while((*str++) != '\0') ++len; return len; } |
strlen 与 sizeof 的区别:
-
sizeof是运算符,strlen是库函数。
-
sizeof可以用类型、变量做参数,而strlen只能用 char* 变量做参数,且必须以
\0
结尾。 -
sizeof是在编译的时候计算类型或变量所占内存的大小,而strlen的结果要在运行的时候才能计算出来,用来计算字符串的长度。
-
数组做sizeof的参数不退化,传递给strlen就退化为指针了。
3、字符串连接strcat
函数strcat
的原型是char* strcat(char* des, char* src)
,des 和 src 所指内存区域不可以重叠且 des 必须有足够的空间来容纳 src 的字符串。
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <assert.h> #include <stdio.h> char* strcat(char* des, const char* src) // const表明为输入参数 { assert((des!=NULL) && (src!=NULL)); char* address = des; while(*des != '\0') // 移动到字符串末尾 ++des; while(*des++ = *src++) ; return address; } |
4、字符串比较strcmp
函数strcmp
的原型是int strcmp(const char *s1,const char *s2)
。
- 若s1==s2,返回零;
- 若s1>s2,返回正数;
- 若s1<s2,返回负数。
即:两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇\0
为止。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <assert.h> #include <stdio.h> int strcmp(const char *s1,const char *s2) { assert((s1!=NULL) && (s2!=NULL)); while(*s1 == *s2) { if(*s1 == '\0') return 0; ++s1; ++s2; } return *s1 - *s2; } |