c/c++的强大和可怕之处在于其直接操作内存,c标准库提供了大量这样的函数,比如strcpy,strcat,memcpy等,写的时候要注意dst和src地址覆盖的问题,否则结果将不可期。还要注意一下异常输入。
strcpy函数
char* strcpy(char* dst,const char* src){
if(!dst || !src) return NULL;
int len = strlen(src)+1;//拷贝最后的'/0'
char * ret = dst;
if(dst>src && dst<len+1){
dst = dst + len -1;
src = src + len -1;
while(len--){
*dst-- = *src--;
}
}
else{
while(len--){
*dst-- = *src--;
}
}
return ret;
}
需要注意的点:
- 返回值char*,为了链式表达式,因为还可能会调用strlen()等函数求链表的长度
- src前面的const,在函数中不能修改复制源字符串的值。(const在*左边修饰所指对象;右边修饰指针)
memcpy函数
void *memcpy(void *dst, const void *src, size_t size) {
if (dst == NULL || src == NULL) return NULL;
void *ret = dst;
char* pdst = (char*)dst;
char* psrc = (char*)src;
if (pdst > src || pdst < psrc + size) {
pdst = pdst + size - 1;
psrc = psrc + size - 1;
while (size--) {
*pdst-- = *psrc--;
}
}
else {
while (size--) {
*pdst++ = *psrc++;
}
}
return ret;
}
strcat函数
char* strcat(char*dst,const char*src) {
if (dst == NULL || src == NULL) return NULL;
char *ret = dst;
while (*dst != '\0') dst++;
while ((*dst++ = *src++) != '\0');
return ret;
}
strcmp函数
一开始还想如果str1字符串长,str2已经结束了,这种情况还要循环怎么办?运行了一下代码就明白原来它先有*str1 ? *str2 如果一个已经为'/0'就处理的是不相等,跳出循环
int strcmp(const char* str1, const char* str2) {
if (!str1 || !str2) return -1;
while (*str1 == *str2 && str1 != '\0') {
str1++;
str2++;
}
return *str1 - *str2;
}
memmove函数
char* memmove(void *pdst, const void* psrc, int n) {
if (!pdst || !psrc) return NULL;
char* dst = (char*)pdst;
char *src = (char*)psrc;
char *ret = dst;
if (dst < src || dst >(src + n - 1)) {
while (n--) {
*(dst++) = *(src++);
}
}
else {
dst = dst + n - 1;
src = src + n - 1;
while (n--) {
*(dst--) = *(src--);
}
}
return ret;
}