本文已参与「新人创作礼」活动,一起开启掘金创作之路
上一期我们强调了调试的重要性,以及说明了如何使自己写的代码更好,那么现在我们就来实战演练一下,看一下我们是如何让代码一步步走向完美的
我们的题目是模拟实现库函数:strcpy
我们先看一下strcpy函数的介绍
我们发现,它的功能是拷贝一个字符串,并且它是有返回值的
我们先来使用一下这个库函数来熟悉一下
#include<string.h> int main() { char arr1[20] = { 0 }; char arr2[] = "hello"; strcpy(arr1, arr2); printf("%s", arr1); return 0; }
如果我们想更细致地看一下拷贝的过程
我们把arr1改一下
进入调试
这是未进入strcpy函数时的arr1和arr2
这是函数作用完
我们可以发现,这个strcpy函数就是通过将arr1数组的内容改为arr2数组的内容,我们还可以发现,这个函数是能拷贝'\0' 的
好了,下面我们开始我们的模拟实现库函数 strcpy
这是我们的思路
版本1
#include<stdio.h> void my_strcpy(char* dest, char* src) { while (*src != '\0') { *dest = *src; dest++; src++; } *dest = *src;//处理'\0' }
int main() { char arr1[20] = "xxxxxxxxxxxxx"; char arr2[] = "hello"; my_strcpy(arr1, arr2); printf("%s", arr1); return 0; }
我们初步完成了,但是如果这是一道10分的题,我们这样完成可能只有5分
第一个问题:如果我们传参穿的是空指针,那么程序会出错,我们要避免这种情况
我们改进一下
版本2
#include<assert.h> void my_strcpy(char* dest, char* src) { assert(dest != NULL);//断言 assert(src != NULL);//断言 while (*src != '\0') { *dest = *src; dest++; src++; } *dest = *src;//处理'\0' } 我们要用到assert() --> 断言
它是要引头文件的
我们测试一下
运行起来
程序报错
现在我们的第二版就实现了防止指针为空的功能,我们用到了 断言
assert()
那么我们能不能在它的基础上进一步简化代码呢?
版本3
void my_strcpy(char* dest, char* src) { assert(dest && src);//断言 while (*dest++ = *src++) { ; } } 这个代码是不是非常妙呢?
一举两得,既将arr1赋值了hello \0 而且\0结束后就停止了
这样巧妙的代码,是需要深厚的功底的
另外一个问题:
我们既然要模拟实现函数,那就要跟它一样啊,但是看图片
原函数是有返回值的,返回的是目标的指针,而我们的返回类型是void,
并且这里穿的参数有const修饰
于是我们继续改进
版本4
char* my_strcpy(char* dest, char* src) { assert(dest && src);//断言 char* ret = dest; while (*dest++ = *src++) { ; } return ret; } 为什么要有返回值呢,因为这样能更加灵活
我们就能利用返回的指针完成一些操作
如:
下面看第二个差异:原函数有const
假设有一天 while (*dest++ = *src++) 括号里的内容写反了
while (*src++ = *dest++)
如果我们最开始时加了个const
程序就不能运行,会报错
我们说明一下const的有关知识:
1.const修饰变量
2.const修饰指针
const修饰指针有两种:
1). const 放在 * 左边
const int* p = &n; const修饰的是指针指向的内容 ,表示指向的内容不能通过指针来改变,但是指针变量本身是可以改变的 (*p不能改,p能改)
2).const放在 * 右边
int* const p = &n; const修饰的是指针变量本身 ,表示指针变量的内容不能被修改,但是指针变量指向的内容是可以通过这指针来改变的 (p不能改,*p能改)
我们来看一下终极版
#include<stdio.h> #include<assert.h> char* my_strcpy(char* dest, const char* src) { assert(dest && src);//断言 char* ret = dest; while (*dest++ = *src++) { ; } return ret; }
int main() { char arr1[20] = "xxxxxxxxxxxxx"; char arr2[] = "hello"; my_strcpy(arr1, arr2); printf("%s", arr1); printf("%s\n",my_strcpy(arr1, arr2)); return 0; }