文章目录
字符串拷贝strcpy
原型
char * strcpy(char* dst, const char* src)
注意的细节
- 判断地址是否为空,利用
assert()函数
,在头文件assert.h
中 - 源字符串不可被修改
- 遇到c字符串结尾时(
'\0'
)终止 - 未处理dest和src有重叠时的情况
- 返回目标地址:是为了支持链式表达式,eg
int len=strlen(strcpy(strA,strB));
- 传指针参数时,在函数内部,改变指针(地址)和改变指针的内容不一样,改变指针(地址)不会在函数外起作用,改变指针指向的内容,会在函数外部起作用,*dst++会改变指针(地址),但不会影响函数外的dst指针(地址)
实现
#include <assert.h>
#include <stdio.h>
char* strcpy(char* dst, const char* src)
{
assert((dst!=NULL) && (src!=NULL));
char *tmp = dst; //函数内部,记录dst的首地址
//*dst++相当于先*dst,再*dst = *(dst+1)
while((*dst++ = *src++) != '\0')
;
return tmp;
}
假如考虑dst和src内存重叠的情况,my_strcpy该怎么实现
参考memcpy、memmove的实现
eg:
char s[10]="hello";
strcpy(s, s+1); //返回ello,此时目标地址小于源地址,拷贝时未发生覆盖,不会有错误
//strcpy(s+1, s); //此时目标地址大于源地址,拷贝时发生覆盖,内存访问错误
所谓重叠,就是src未处理的部分已经被dst给覆盖了,只有一种情况:src<=dst<=src+strlen(src)
my_strcpy实现
char my_strcpy(char * dst, const char * src)
{
assert(dst != nullptr && src != nullptr);
char *d = dst;
int srcLen = strlen(src) + 1;//加上'\0'
my_memcpy(dst, src, srcLen + 1) ;
return d;
}
char* my_memcpy(char* dst, const char* src, int cnt){
assert(dst != nullptr && src != nullptr);
char* res = dst;
if(dst >= src && dst <= src + cnt - 1){
dst = dst + cnt - 1;
//src指向内容不可以改变,但是指针可以改变
src = src + cnt - 1;
while(cnt--)
*dst-- = *src--;
}
else{
while(cnt--)
*dst++ = *src++;
}
return res;
}
字符串长度strlen
原型
size_t strlen(const char *s)
注意的细节
- 检查空字符串
- 终止条件
- 终止符
\0
不计入长度
实现
size_t strlem(const char * str)
{
assert(str != nullptr);
int len = 0;
while (*str++ != '\0')
{
len++;
}
return len;
}
字符串连接strcat
原型
char* strcat(char* des, char* src)
注意
- 尽量不在
while()
使用++,--
,容易出错 - 注意字符串终止符号
\0
实现
char * strcat(char * dest, const char * src)
{
assert(dest != nullptr && src != nullptr);
char *d = dest;
while (*d != '\0')//移动字符串到末尾
d++;
while (*src != '\0')
{
*d++ = *src++;
}
return d;
}
字符串比较strcmp(不是长度大小)
原型
int strcmp ( const char * str1, const char * str2 );
str1 > str2
,返回正数str1 < str2
,返回负数str1 = str2
,返回零
实现细节
- 两个字符串自左向右逐个字符相比
- 利用
ASCII
值比较 - 终止条件:遇上空字符或者不等
实现
int strcmp(const char * str1, const char * str2)
{
assert(str1 != nullptr && str2 != nullptr);
while (*str1 == *str2)//不等或者遇到'\0'时返回结果
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
return *str1 - *str2;
}