|
各大公司尤其百度、腾讯等一线公司都喜欢问这个题,我想了想,可能这个题特别能看出一个人的逻辑思维能力、反应能力、考虑问题是否周到、写代码是否规范优雅,所以,这个题大家好好看看。不要觉得这个很简单,一问你,你就知道,其实你学的还不行。里面涉及到问题很多的。
字符串拷贝函数strcpy写法
// CppReference.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
using namespace std;/*
* 说明:字符串拷贝版本1
* 参数:dest目标地址,src源地址
* 返回:返回拷贝好的地址;如果出错或者有重叠,无定义
* 异常:可能出现字符串溢出,即dest所占空间不如src所占空间大。
*/
char *strcpy_v1(char *dest , const char *src)
{
//调试时,使用断言,入口检测
assert( (dest!=NULL) && (src!=NULL) );
//注意这里的内存指向参数dest所在的内存,不是栈内存,因而可以在函数中返回
char *to = dest;
//主要操作在while条件中完成
while( (*dest++ = *src++)!='\0')
{
NULL;
}
//返回拷贝字符串首地址,方便连缀,比如strlen(strcpy(dest,"hello"))
return to;
}/*
* 说明:字符串拷贝版本2
* 参数:dest目标地址,src源地址
* 返回:返回拷贝好的地址;如果出错,无定义
* 异常:可能出现字符串溢出,及dest所占空间不如src所占空间大。
*/
char *strcpy_v2(char *dest , const char *src)
{
char *d = dest;
char c;
while((c=*src++) != '\0')
{
*(dest++)=c;
}
*dest='\0';
return d;
}/*
* 说明:字符串拷贝版本2(你能找出错误的原因吗)
* 参数:dest目标地址,src源地址
* 返回:返回拷贝好的地址;如果出错,无定义
* 异常:可能出现字符串溢出,及dest所占空间不如src所占空间大。
*/
char *strcpy_v2_error(char *dest , const char *src)
{
char *d = dest;
char c;
while((c=*src++) != '\0')
{
*(d++)=c;
}
*d='\0';
return d;
}
/*
* 说明:字符串拷贝版本3
* 参数:dest目标地址,src源地址
* 返回:返回拷贝好的地址;如果出错,无定义
* 异常:可能出现字符串溢出,及dest所占空间不如src所占空间大。
*/
char *strcpy_v3(char *dest , const char *src)
{
char *d = dest;
char c;
while(*src)
*dest++ = *src++;
*dest='\0';
return d;
}/*
* 说明:字符串拷贝版本4
* 参数:dest目标地址,src源地址
* 返回:返回拷贝好的地址;如果出错,无定义
* 异常:可能出现字符串溢出,及dest所占空间不如src所占空间大。
*/
char *strcpy_v4(char *dest , const char *src)
{
char *d = dest;
char c;
while( (*dest = *src)!='\0')
{
src++;
dest++;
}
*dest='\0';
return d;
}/*
* 说明:字符串拷贝版本5
* 参数:dest目标地址,src源地址
* 返回:返回拷贝好的地址;如果出错,无定义
* 异常:可能出现字符串溢出,及dest所占空间不如src所占空间大。restrict关键字限定字符串不能重叠。
*/
char *strcpy_v5(char* _restrict dest , const char* _restrict src)
{
char *d = dest;
char c;
while( (*dest = *src)!='\0')
{
src++;
dest++;
}
*dest='\0';
return d;
}/*
* 说明:字符串拷贝版本6
* 参数:dest目标地址,src源地址
* 返回:返回拷贝好的地址;如果出错,无定义
* 异常:可能出现字符串溢出,及dest所占空间不如src所占空间大。restrict关键字限定字符串不能重叠。
*/
char *strcpy_v6(char* _restrict dest , const char* _restrict src)
{
char *d = dest;
char c;
while(*dest++=*src++);
return d;
}int _tmain(int argc, _TCHAR* argv[])
{
char buf[512];
char *buf2 = (char *)calloc(50,sizeof(char));
char *buf3 = (char *)malloc(50*sizeof(char));
char *buf5 = (char *)malloc(50*sizeof(char));
char *buf6 = (char *)malloc(50*sizeof(char));
printf("using strcpy_v1,the string 'Hello,World'\'s length is : %d\n",strlen(strcpy_v1(buf,"Hello,World")));
printf("using strcpy_v2,the string 'This is the best age'\'s length is : %d\n",strlen(strcpy_v2(buf2,"This is the best age")));
printf("using strcpy_v2,the string 'This is the best age'\'s length is : %d\n",strlen(strcpy_v2_error(buf2,"This is the best age")));
printf("using strcpy_v3,the string 'This is the best age'\'s length is : %d\n",strlen(strcpy_v3(buf3,"This is the best age")));
printf("using strcpy_v5,the string 'This is the best age'\'s length is : %d\n",strlen(strcpy_v5(buf5,"This is the best age")));
printf("using strcpy_v6,the string 'This is the best age'\'s length is : %d\n",strlen(strcpy_v6(buf6,"This is the best age")));
system("pause");
return 0;
}
请问下面这个strcpy 函数的功能是把字符串t 复制到串s中
strcpy(char *s,char *t)
{ while(*s++ = *t++);
}
是对的,while(*s++=*t++);里面的语句是先执行*t=*t,再s++,t++,当达到'\0'时候,也复制进去了,所以是对的
这种写法不但正确而且非常高效!
(1)while(condition){//循环体}当condition为非零时,就进入循环体,此例循环体是一句空语句,即什么都不做;
(2)我们知道字符串结束符为'\0'其ASCII值为0,我们来检查一下condition语句:
*s++ = *t++;
// 分解一下:
1)首先*s = *t (把指针t所指内存赋值到s所指内存,由于指针类型为char,则系统每次会取出sizeof(char)个字节大小的内存进行赋值操作,s所指原内存被覆盖掉,而t所指内容保持不变;
2)condition语句最后的值为指针s所指的内存内容;
3)while(condition)//while开始判断condition的值,若为零则循环结束,否则进入循环体;
4)然后s++,t++指针移动sizeof(char)个字节,同时指向下一个内存单元;
显然:只有当condition(即指针s所指内容)为零时循环结束,我们可以看到只有当字符串指针t指向字符串结束符'\0'时(其ASCII码为0),通过赋值语句赋给指针s所指内存时,s的所指内容为'\0'(编译器看到condition就是0),循环结束!而此时,字符串复制工作也正好结束。非常完美!
通过分析strcpy的实现,那么在使用中需要注意的是:
strcpy函数把源字符串包含字符串结束符'\0'都一个不漏地拷贝到目标内存中了,那么分配给目标内存的大小除了包含有效字符串长度时,还要多加一个sizeof(char)的内存大小来存放字符串结束符'\0',见如下的示例:
char* t = {"Hello World"};
char* s = new char[strlen(t) + 1]; // strlen(t)返回有效字符串长度
strcpy(s, t);
// 使用s
delete s;
另外个人认为,这个函数应该是这样的参数才最为合理:
strcpy(char* s, const char* t); // 即源字符串指针所指内容应该为只读
(*s++ = *t++);
这个是赋值不是 (*s++ == *t++);
当赋值语句的返回值是 *t,若 *t返回为0,则退出循环?
最简单的写法:
char *strcpy(char *s1,char *s2)
{
while(*s2++ = *s1++);
return s2;
}
复制代码
字符串拷贝函数.docx (17.43 KB, 下载次数: 0, 售价: 1 下载豆) |
|