在C语言中,我们可以使用strcpy函数对数组进行复制,但这个函数需要我们在文件的开头引用头文件,如下所示
#include#includeint main(){char arr1[20] = "******************";char arr2[] = "hello world";strcpy(arr1, arr2);// 目标空间起始地址源空间的起始地址printf("%s\n", arr1);// hello worldreturn 0;}
接下来我们使用自己编写的函数来实现字符串的复制
首先编写主函数,创建两组字符串,并调用函数名为my_strcpy,参数为两个数组
注:第一个参数为目的数组的起始地址,第二个参数为需要复制的源数组的起始地址
接下来开始写my_strcpy函数,在main中传递的参数是两个,在函数中也需要定义两个变量,我们定义为char dest,char src,由于在main函数中调用时的参数是数组的起始地址,在函数中声明变量的时候,我们就使用*对数组地址进行解引用,即 char* dest,char* src。
需要注意的是,在函数中定义的变量名称应该具有意义,方便阅读,不建议使用y1,y2等简单的方式进行命名。
数组是由多个单独的元素组成,我们使用while语句进行循环,判断条件为 当循环到源数组的元素为’\0’时,退出循环。 —-(’\0’为数组的结束标志)
在while语句内部,我们使 目的地址的内容 = 源地址的内容,并对dest以及src进行自增,使用后置++。
当源地址循环到结束标志时,就退出了while循环,为了方便在使用%s对字符串进行输出,也需要将结束标志复制到目的数组中,因此需要在while语句之后再加一句 *dest = *src;
如下所示:
#includevoid my_strcpy(char* dest, char* src){while(*src != '\0'){*dest = *src;dest++;src++;}*dest = *src; }int main(){char arrr1[20] = "******************";char arr2[] = "hello world";my_strcpy(arr1, arr2);printf("%s\n", arr1);// 使用%s对字符串进行输出return 0;}
接下来开始优化
为了使程序简洁,可以将 while内的语句改写到while 的判断条件中,如下
void my_strcpy(char* dest, char* src){while(*dest++ = *src++){;// hello world 的拷贝}}
为了防止在主函数中误使用NULL进行复制,需要在while之前进行判定(断言)
使用assert()函数进行断言,需要引用库
#includevoid my_strcpy(char* dest, char* src){assert(src != NULL);// 对源数组进行判定assert(dest != NULL); // 对目的数组进行判定while(*dest++ = *src++){;}}
assert() — 括号中的内容为判定内容,判定为true会中止程序的运行,并指出错误所在行
如下:
指出错误在第9行
在源文件中即是:(在此故意将调用时的参数写为NULL,仅供演示)
还有的情况是:
在函数中将赋值的参数写反,写成了*src++ = *dest++,在这种情况下既会得不到想要的结果,也可能会因为arr1的长度大于arr2而造成程序报错。
我们可以使用const来改善此类问题,如下:
在使用const对src进行修饰后,src就不能再被赋值,写在表达式左边程序就会报错。
const 修饰变量,这个变量就成为常变量,不能被修改,且本质上仍然是变量。
需要注意:const在修饰指针变量的时候,有两种情况
1.const如果放在*的左边,修饰的是*变量名,表示的是指针指向的内容,是不可以通过指针进行改变的,但是指针变量本身是可以进行修改的。
2.const如果放在*的右边,修饰的是指针变量,表示指针变量不能被改变,但是指针的内容,可以被改变。
当*左右两边都写有const的时候,指针指向的内容和指针变量都不能被改变
如下:
int main(){int m = 10;int n = 100;// 1.const 在 * 左边的时候const int* q = &m;*q = 100;// 报错q = &n;// 正常// 2.const 在 * 右边的时候int* const p = &m;p = &n;// 报错*p = 100;// 正常// * 左右两边都写constconst int* const i = &m;i = &n;// 报错*i = 100;// 报错return 0;}
可以简单理解为:const修饰的右边的变量名字无法作为表达式的左值