⭐博客主页:️CS semi主页
⭐欢迎关注:点赞收藏+留言
⭐系列专栏:C语言初阶
⭐代码仓库:C Advanced
家人们更新不易,你们的点赞和关注对我而言十分重要,友友们麻烦多多点赞+关注,你们的支持是我创作最大的动力,欢迎友友们私信提问,家人们不要忘记点赞收藏+关注哦!!!
strcpy函数其实大家并不陌生,但是每次用的时候要么就复制到字符串的地方不对,要么就出现错误,那到底该怎么用这个函数呢?接下来我将详细给大家讲解strcpy这个函数的本质和用法!
再认识这个函数之前,我先放一张图片供大家理解一下:
在MSDN中查一下这个函数,发现是从后面的数组复制一份复制到前面的数组,那当然,大家伙可能会问了,为什么有一个const被圈出来了,这个const很熟悉呀,之前见到过了,大家伙继续往后看,在文中我会跟大家详细解说一下这个const与指针配套起来的用法。
先带大家看一看运用一下strcpy的奇效。
#include
#include
int main() {
char arr1[20] = "****************";
char arr2[] = "hello";
strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
看,运用了这个函数以后感觉是在是太方便了,能把arr2中的“hello\0”全部复制到arr1[20]里面去,唉,大家可能会问了,屏幕上显示的是hello啊,没有那个’\0’,大家继续往下面看,就立马能够理解了。
先上几张图片让大家理解理解。
1.将*赋到arr1数组中。
2.将hello+’0’赋到arr2数组中。
3.进行复制的操作。
4.原理图
利用监视器看strcpy函数能够看到它的本质就是将后面数组里面的字符串+‘、0’拷贝到前面的数组中,但是为什么会有\0呢,这个很简单,arr[]={a,b,c,d}与arr[]="abc"是有本质的区别的,后者多一个\0,大家可以去看看我以后写的关于数组的区分的博客哦!
先上个代码:
代码1:这个代码很好理解,就先取数组的首地址并交换再往后加加,直到最后一个元素进行交换完退出循环。
#include
//#include
void my_strcpy(char* dest, char* src) {
while (*src != '\0'){
*dest++ = *src++;
}
*dest = *src; //拷贝\0
}
int main() {
char arr1[20] = "****************";
char arr2[] = "hello";
my_strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
代码2:这个代码可以把\0直接打印出来,不需要最后一步加上交换一次\0。
#include
//#include
void my_strcpy(char* dest, char* src) {
while (*dest++ = *src++) {
;
}
}
int main() {
char arr1[20] = "****************";
char arr2[] = "hello";
my_strcpy(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
但这代码实现的看似没什么问题,可是也隐藏着一个很大的问题,数组是我已经定义好了的,但是,如果是在主函数里面输入NULL(空指针)呢?那让我们先来看看。
输入空指针后,编译器立马就报错了,所以,这是肯定不行的!那怎么解决呢?接下来上一串代码!
子函数里加了先判断输入的两个指针元素存不存在空指针,有空指针那就不进行后续操作。
#include
//#include
void my_strcpy(char* dest, char* src) {
if (src == NULL || dest == NULL)
{
return;
}
while (*dest++ = *src++) {
;
}
}
int main() {
char arr1[20] = "****************";
char* p = NULL;
my_strcpy(arr1, p);
printf("%s\n", arr1);
return 0;
}
大家想一个问题,如果一个程序员喝了点小酒醉了,只看到了这个程序可以直接运行,很开心的到老板那里邀功,老板说,你这做的啥!为什么导致程序员犯错了呢,很简单,机器没有报错,程序员以为是对的,所以,接下来引进一个新的函数为“断言’(assert)函数。
assert中可以放一个表达式,表达式的结果如果为假,就报错,如果为真那就正常运行
实现代码:
#include
#include
//#include
void my_strcpy(char* dest, char* src) {
/*if (src == NULL || dest == NULL)
{
return;
}*/
assert(src != NULL);
assert(dest != NULL);
while (*dest++ = *src++) {
;
}
}
int main() {
char arr1[20] = "****************";
char* p = NULL;
my_strcpy(arr1, p);
printf("%s\n", arr1);
return 0;
}
很明显,这个程序报错了,而且给你标注了哪里出错了,是不是很方便快捷,当然,头文件不要漏掉。
这一阶段的完整代码如下:
#include
#include
//#include
void my_strcpy(char* dest, char* src)
{
assert(dest && src);//断言指针的有效性
while (*dest++ = *src++)
{
;
}
}
int main()
{
//strcpy - 字符串拷贝
//char arr1[20] = "xxxxxxxxxxx";
//char arr2[] = "hello";
//my_strcpy(arr1, arr2);
//printf("%s\n", arr1);
char arr3[20] = {0};
char* p = NULL;
my_strcpy(arr3, p);
return 0;
}
大家如果细心看那张strcpy的图,会发现两个小问题,这strcpy是有返回值的呀,还有那个const怎么一直没有解决呢?接下来,我们开始解决问题!
#include
#include
//#include
char* my_strcpy(char* dest, char* src)
{
assert(dest && src);
char* ret = dest;
while (*dest++ = *src++)
{
;
}
return ret;
}
int main()
{
char arr1[20] = "*************";
char arr2[] = "hello";
printf("%s\n", my_strcpy(arr1, arr2)); //链式访问
return 0;
}
这样就有返回值了!
接下来到了最激动人心的时刻,久久困扰的const该怎么做呢?下面且听我分析。
大家先来看看这张图片,生动形象的解释了const。
情况一:const 在的左边:const int p 与 int const * p 一样哦~
//const放在* 的左边,const修饰的是指针指向的内容,表示指针指向的内容,不能通过指针来改变了; 但是指针变量本身可以修改
int num = 0;
int n = 1000;
const int* p = #
*p = 20;//err
p = &n;//ok
情况二:const 在*的右边:int * const p
const放在*的右边,const修饰的指针变量本身,表示指针变量本身的内容不能被修改,但是指针指向的内容,可以通过指针来改变。
int* const p = #
*p = 20;//ok
p = &n;//err
到这里就完美解决了strcpy函数的问题。
#include
#include
//#include
char* my_strcpy(char* dest, const char* src)
{
assert(dest && src);
char* ret = dest;
while (*dest++ = *src++)
{
;
}
return ret;
}
int main()
{
char arr1[20] = "*************";
char arr2[] = "hello";
printf("%s\n", my_strcpy(arr1, arr2)); //链式访问
return 0;
}
模拟strcpy函数让我们大家深刻理解了这个函数的原理以及用法,最好的一点是让我们了解了assert和const的使用,一举三得!!!!
客官都阅读到这边了,码字不易,求个三连支持!