如何不調用庫函數自己手動實現字符串的拷貝呢?我們一起來看看吧~
首先我們回憶一下字符串的特徵,看看下面哪些是字符串呢?
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與數字的轉換~