模拟实现库函数:strcpy(一步步走向完美)

294 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

上一期我们强调了调试的重要性,以及说明了如何使自己写的代码更好,那么现在我们就来实战演练一下,看一下我们是如何让代码一步步走向完美的

我们的题目是模拟实现库函数: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; }