如何不调用库函数自己手动实现字符串的拷贝呢?我们一起来看看吧~
首先我们回忆一下字符串的特征,看看下面哪些是字符串呢?
int main() //字符串:用""描述的字符集合,一定有'\0'结尾 只有以'\0'结尾的字符集合才能称为字符串
{
char arr[10] = {'a','b','c','d'}; //是字符串
char brr[] = {'a','b','c','d'}; //不是字符串
char crr[10]; //不是字符串
字符数组特有的写法
char drr[10] = {"abcd"}; //是
char err[10] = "abcd"; //是
char grr[] = "abcd"; //是
char *frr = "abcd"; //字符指针,不是字符数组
return 0;
}
回到主题,是不是也有刚学c的小伙伴有这样的疑惑呢:不能用“=”直接赋值吗?emmm....“=”是用来给c中的内置类型相互赋值的,而字符串不是内置类型,编译器不能进行赋值操作,就会报错。
所以还是乖乖的一个一个字符拷贝吧,给整个字符串直接赋值这种操作不存在的,别想偷懒了(是不是觉得库函数真好用)。OK,开始写,最开始写了以下代码:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
void Mystrcpy(char *des, char *src)
{
assert(des != NULL && src != NULL);
if (des == NULL || src == NULL)
{
return;
}
while (*src != '\0')
{
*des = *src;
des++;
src++;
}
*des = '\0';
}
int main()
{
char str1[] = "abcde";
char str2[10];
char str3[] = "xyz";
Mystrcpy(str2, str1);
printf("str2=%s\n", str2);
return 0;
}
然后,优化之路开始,进阶一,把des和src当数组看,使用下标:
void Mystrcpy1(char *des,char *src)
{
int i = 0;
while (src[i] != '\0')
{
des[i] = src[i];
++i;
}
des[i] = '\0';
}
int main()
{
//char str1[] = "abc";
char str2[10];
char str3[] = "mmmmm";
Mystrcpy1(str2, str3);
printf("str2=%s\n", str2);
return 0;
}
再接着,进阶二,省去下标,利用src[i]=*(src+i):
void Mystrcpy2(char *des, char *src)
{
int i = 0;
while(*(src+i) != '\0')
{
*(des + i) = *(src + i);
i++;
}
*(des + i) = '\0';
}
int main()
{
char str2[10];
char str3[] = "1234";
Mystrcpy2(str2, str3);
printf("str2=%s\n", str2);
return 0;
}
进阶三,利用符号优先级,*和++的优先级相同,且高于赋值。优先级相同时看结合性,*和++结合性自右向左,所以先++后解引用,但是后置++会先使用当前值再自加:
void Mystrcpy3(char *des,char *src)
{
while(*src != '\0')
{
*des++ = *src++;
}
*des = '\0';
}
int main()
{
char str2[10];
char str3[] = "888888";
Mystrcpy3(str2, str3);
printf("str2=%s\n", str2);
return 0;
}
进阶四,终极版,利用字符串末尾带'/0'的特性:
void Mystrcpy4(char *des,char *src)
{
while(*des++ = *src++);
}
int main()
{
char str2[10];
char str3[] = "abcd";
Mystrcpy4(str2, str3);
printf("str2=%s\n", str2);
return 0;
}
字符串拷贝写完了,下次我们来写字符串的连接、比较大小and与数字的转换~