拷贝函数

来源:互联网 发布:在线订单管理系统源码 编辑:程序博客网 时间:2024/05/18 03:07
拷贝函数就是实现复制粘贴过程的函数,c语言库函数中有这个函数,函数名为strcpy();只要加上头文件#include<string.h>就可以调用这个函数了。
函数原型为char *strcpy(char *des,const char *src );
des为目标字符串指针,src为源字符串指针,源指针不能被修改,加上const修饰。成功执行后返回目标数组指针des的起始地址。(返回指针是历史遗留问题,因为当时写程序以简洁为主,现在返回空就可以,因为现在以可读性为主)
注意:des和src所指向的内存区域不能重叠,且des必须有足够的空间置放src所包含的字符串,包括结束符’\0‘.
如果des的存储空间不够大,就会越界。

我们写出拷贝函数的代码,就可以知道这个函数具体是怎么样用的。以下在传src的时候要加上const,不加const可能会修改源指针,会有危险。

void mystrcpy1(char *des,const char *src)
{
 int i;
 for(i=0;src[i]!='\0';i++)
 {
  des[i]=src[i];
 }
 des[i]='\0';
}

void mystrcpy2(char *des,const char *src)
{
 int i;
 for(i=0;*(src+i)!=‘\0';i++)
 {
  *(des+i)=*(src+i);
 }
 *(des+i)='\0';
}
其实和第一种形式一样,因为arr[i]等价于*(arr+i),只是第一种的变形

void mystrcpy3(char *des,const char *src)
{
 while(*src!='\0')
 {
     *des=*src;
     src++;
     des++;
 }
 *des='\0';
}
这个含义是先对源解引用赋值给目标解引用,然后源指针和目标指针都向后走,src++,就是指针加法,向后移动一个单元格。

void Mystrcpy4(char *des,const char *src)
{
 while(*src != '\0')
 {
  *des++ = *src++;
 }
 *des= '\0';
}

*src++  :这句话是怎么解释的
首先++和* 的优先级是相同的,但是它们的结合性是自右向左的,所以*(src++);但是后置++是先赋值在加,所以要先进行*src,再++。所以从src的首地址开始,赋值给des,然后再到下一个指针。直到遇到了\0,就退出循环,再将des最后加上’\0‘

void mystrcpy5(char *des,const char *src)
{
 while(*des++=*src++) ;
}
这句话是这样判断的:while循环为真则进入,然后接着判断,为假退出,后面的分号就是说明前面是空语句,什么都不执行,然后继续进入循环,上面分析了*src++,*des++也是这样,然后就将源指针解引用的值赋值给目标指针,然后它们都往后走,赋值语句的值就是赋的值,不为0(这里是’\0‘)就执行继续执行循环,一直到’\0‘就退出循环,这里要注意的就是’\0‘在退出循环之前已经赋值给目标函数了,因为它被赋值了,所以才能判断它是’\0‘,和上面四种的思路不太一样。
这句话很简洁,一句就实现了字符串拷贝功能,但是只适用于考试题,平时编程不建议这样写,可读性太低了。

再看一下库函数中的实现方法
char * strcpy(char *des,char *src)
{
 char *p = des;
 while(*des++  = *src++) ;
 return p;
}
因为库函数返回值是一个指针,所以要返回指针,但是不能直接返回des,因为最后的des是已经走过了的des,已经不是原来首元素的地址了,所以引入一个标记,用一个新的指针在des没有走之前把它记录下来,然后返回这个指针的地址。这样做就是一个历史遗留问题了,因为当时人们写程序是力求简洁,这样在调用的时候就可以连续调用,但是现在的要求是可读性高,所以现在我们一般不要求返回指针,返回空也可以。

int main()
{
 char str1[10];
 char str2[10]="abcde";
 //mystrcpy1(str1,str2);
 //mystrcpy2(str1,str2);
 mystrcpy3(str1,str2);
 mystrcpy4(str1,str2);
 Mystrcpy(str4, Mystrcpy(str3,str2));//链式表达,历史遗留问题
 printf("%s\n",str1);
 return 0;
}

原创粉丝点击