1.strlen函数
int mystrlen1(char *str) //递归
{
if(*str=='\0')
return 0;
return 1+mystrlen1(str+1);
}
int mystrlen2(char *str) //迭代
{
int cnt=0;
while(*str)
{
++cnt;
++str;
}
return cnt;
}
2.strcmp函数
int mystrcmp(const char * str1,const char *str2)
{
while(*str1 && *str1==*str2) //把前面相同的去掉
{
++str1;
++str2;
}
if(*(unsigned char*)str1 ==*(unsigned char*)str2)
{
return 0;
}
else if(*(unsigned char*)str1 >*(unsigned char*)str2)
{
return 1;
}
else
return -1;
}
int mystrcmp2(const char *str1,const char *str2)
{
int ret=0;
while(!(ret=*(unsigned char*)str1-*(unsigned char*)str2) && *str1) //判断两个字符的差是否为0
{
++str1;
++str2;
}
if(ret<0)
{
return -1;
}
else if(ret>0)
return 1;
else return 0;
}
使用*(unsigned char*)str1而不是用*str1。这是因为传入的参数为有符号数,有符号字符值的范围是-128~127,无符号字符值的范围是0~255,而字符串的ASCII没有负值,若不转化为无符号数这回在减法实现时出现错误。
例如 str1的值为1,str2的值为255。
作为无符号数计算时ret = -254,结果为负值,正确
作为有符号数计算时ret = 2,结果为正值,错误
参考:strcmp函数实现及分析
3.strcat函数
char* mystrcat(char* dest,const char* src)
{
if(dest==nullptr || src==nullptr)
{
return dest;
}
char* temp=dest;
while(*dest)
{
++dest;
}
while(*src)
{
*dest=*src;
++src;
++dest;
}
*dest='\0';
return temp;
}
4.strcpy函数
char *mystrcpy(char * dest,const char *src)
{
if(dest==nullptr)
{
cout<<"err"<<endl;
return dest;
}
char * temp=dest;
while(*src)
{
*temp=*src;
++src;
++temp;
}
*temp='\0';
return dest;
}
5.strncpy函数
char *strncpy(char *strDest , const char *strSrc , int n)
{
assert((strDest != NULL) && (strSrc != NULL));
char *address = strDest;
while(n-- > 0)
*strDest++ = *strSrc++;
return address;
}
6.strstr函数
7.memmove函数
void* memcpy(void *dst,const void *src,size_t size)
{
if(dst == NULL || src == NULL){
return NULL;
}
char *pdst = (char*)dst;
char *psrc = (char*)src;
//有重叠,从高地址开始复制
if(pdst > psrc && pdst < psrc + size){
pdst = pdst + size - 1;
psrc = psrc + size - 1;
while(size--){
*pdst-- == *psrc--;
}
}
//没有重叠,从低地址开始复制
else{
while(size--){
*pdst++ = *psrc++;
}
}
return dst;
}
8.memcpy函数:
void* memcpy(void *dest , const void* src , size_t count)
{
assert( (dest != NULL) && (src != NULL)); //安全检查
assert(count > 0);
char* psrc = (char *)src;
char* pdest = (char *)dest;
while(count--)
{
*pdest++ = *psrc++;
}
return dest;
}
strcpy和memcpy的区别:
1.复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
2.用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy
3.复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
strncpy和memcpy的区别:
两者对于内存重叠都是未定义行为,所以内存重叠时应该使用 memmove,而不是 memcpy。
首先我们忽略参数的类型差别(前者明确要求 char*,后者无要求),因为这个差别非常的无关紧要。答案就是:当拷贝的字节数小于等于字符串长度时,两者的结果是等效的。但当拷贝的字节数大于字符串长度时,strncpy 是用 0 去补齐字节数,而不是取自于 source。而 memcpy 呢,显然是完全不 care 它拷贝是什么内容的。