(1)字符串拷贝strcpy
特点:只能拷贝字符串,遇到\0停止拷贝
char* MyStrcpy(char* dst,const char* src)
{
assert(dst != NULL && src != NULL);
char* dstaddr = dst;//如果要返回值,必须重新定义一个指针指向目标指针,然后返回定义的这个指针,因为本来的dst已经++走到末尾了
while(*src != '\0')
{
*dst++ = *src++;
}
*dst = '\0';
//while(*dst++ = *src++);或者只用这一句while就可以
return dstaddr;
}
(2)实现memcpy拷贝
特点:对内存拷贝,可以拷贝任何内容,拷贝n个字节
void * memcpy(void *dst,,const void * src,int n)
{
assert(dst != NULL && src != NULL && n>0);
char* d = (char*)dst;//必须强转为其他类型,因为void*类型不能进行++操作
char* s = (char*)src;
while(n - -)
{
*d++ = *s++;
}
return dst;//为了实现链式操作,将目标地址返回,因为d++多次,所以不能返回d
}
memcpy与memmove都可以进行对内存的拷贝,区别是如果两个指针内存有重叠,memcpy可能不安全,memmove是安全的。
内存方面主要有三种情况:
第一种,内存不重叠,拷贝没有问题
第二种,指针dst > src+n,从src前面开始拷,此时拷贝也不会有问题
第三种:src > dst,这种情况memcpy会出现问题。因为如果从src前面开始拷贝,会自己把自己的后面覆盖掉。但是这种情况下memmove的处理方法是从后开始拷贝,所以比较安全。
(4)实现memmove拷贝
void* memmove(void* dst,void* src,int n)
{
assert(dst != NULL && src != NULL && n>=0);
char *d = (char*)dst;//必须强转为其他类型
char* s = (char*)src;
if(dst <= src || (char*)dst >= (cha*)src+n)//src在dst前面或者有重叠但不影响,正向拷
{
while(n - -)
{
*d++ = *s++;
}
}
else
{
d = d+ n -1;//d指向后面,开始拷
s = s+ n -1;
while(n - -)
{
*d - - = *s - -;
}
}
return dst;
}
(5)求字符串长度
int Strlen(const char* str)
{
assert(str != NULL);
int len = 0;//初始化不能忘
while(*str != '\0')
{
len++;
str++;
}
return len;
}
(6)字符串连接
char* Strcat(char* dst, const char*src)
{
assert(dst != NULL && src != NULL);
char * p = dst;
while(*dst != '\0')
{
dst++;
}
while(*src != '\0')
{
*dst++ = *src++;
}
*dst = '\0';//不能忘
return p;
}
(7)字符串比较
int Strcmp(const char*str1,const char*str2)
{
assert(str1 != NULL && str2 != NULL);
int tmp = 0;
while(((tmp = *str1-*str2) == 0) && *str1!='\0')
{//字母相同继续朝前走,只要遇到字母不一样,不论是否遍历完,都跳出
str1++;
str2++;
}
return tmp;
}
(8)字符串逆置
char* StrReverse(char *str)
{
char tmp;
char* s = str;
char *p = str;
while(*p != '\0')
{
p++;
}
p - -;//while循环中p走到了\0位置,但是逆置时不能把\0也逆置了
while(str < p)
{
tmp = *str;
*str = *p;
*p =tmp;
p - -;
str++;
}
return s;//为了实现链式操作,返回
}