编写一个标准strcpy函数 等C++问题
2014-06-13 15:55
225 查看
如果编写一个标准strcpy函数
总分值为10,下面给出几个不同得分的答案:
2分 以下是引用片段:
void strcpy( char *strDest, char *strSrc )
{
while( (*strDest++ = * strSrc++) != '\0' );
}
4分 以下是引用片段:
void strcpy( char *strDest, const char *strSrc )
{
//将源字符串加const,表明其为输入参数,加2分
while( (*strDest++ = * strSrc++) != '\0');
}
7分 以下是引用片段:
void strcpy(char *strDest, const char *strSrc)
{
//对源地址和目的地址加非0断言,加3分
assert( (strDest != NULL) &&(strSrc != NULL) );
while( (*strDest++ = * strSrc++) != '\0' );
}
10分 以下是引用片段:
//为了实现链式操作,将目的地址返回,加3分!
char * strcpy( char *strDest, const char *strSrc )
{
assert( (strDest != NULL) &&(strSrc != NULL) );
char *address = strDest;
while( (*strDest++ = * strSrc++) != '\0' );
return address;
}
从2分到10分的几个答案我们可以清楚的看到,小小的strcpy竟然暗藏着这么多玄机,真不是盖的!需要多么扎实的基本功才能写一个完美的strcpy啊! (4)对strlen的掌握,它没有包括字符串末尾的'\0'。
读者看了不同分值的strcpy版本,应该也可以写出一个10分的strlen函数了,完美的版本为:
int strlen( const char *str ) //输入参数const 以下是引用片段:
{
assert( strt != NULL ); //断言字符串地址非0
int len=0; //注,一定要初始化。
while( (*str++) != '\0' )
len++;
return len;
}
试题4:以下是引用片段:
void GetMemory( char *p )
{
p = (char *) malloc( 100 );
}
void Test( void ) {
char *str = NULL;
GetMemory( str );
strcpy( str, "hello world" );
printf( str );
}
试题5: 以下是引用片段:
char *GetMemory( void ) {
char p[] = "hello world";
return p;
}
void Test( void ) {
char *str = NULL;
str = GetMemory();
printf( str );
}
试题6:以下是引用片段:
void GetMemory( char **p, int num )
{
*p = (char *) malloc( num );
}
void Test( void )
{
char *str = NULL;
GetMemory( &str, 100 );
strcpy( str, "hello" );
printf( str );
}
试题7:以下是引用片段:
void Test( void ) {
char *str = (char *) malloc( 100 );
strcpy( str, "hello" );
free( str );
... //省略的其它语句 }
解答:试题4传入中GetMemory( char *p )函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,执行完 char *str = NULL; GetMemory( str );
后的str仍然为NULL;试题5中 char p[] = "hello world"; return p;
的p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期。 试题6的GetMemory避免了试题4的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句 tiffanybracelets *p = (char *) malloc( num );
后未判断内存是否申请成功,应加上: if ( *p == NULL ) {
...//进行申请内存失败处理
}
试题7存在与试题6同样的问题,在执行 char *str = (char *) malloc(100);
后未进行内存是否申请成功的判断;另外,在free(str)后未置str为空,导致可能变成一个“野”指针,应加上: str = NULL;
试题6的Test函数中也未对malloc的内存进行释放。 剖析:
试题4~7考查面试者对内存操作的理解程度,基本功扎实的面试者一般都能正确的回答其中50~60的错误。但是要完全解答正确,却也绝非易事。
软件开发网 www.mscto.com
对内存操作的考查主要集中在:
(1)指针的理解;
(2)变量的生存期及作用范围;
(3)良好的动态内存申请和释放习惯。
再看看下面的一段程序有什么错误:
以下是引用片段:
swap( int* p1,int* p2 ) {
int *p;
*p = *p1;
*p1 = *p2;
*p2 = *p;
}
在swap函数中,p是一个“野”指针,有可能指向系统区,导致程序运行的崩溃。在VC++中DEBUG运行时提示错误“Access Violation”。该程序应该改为 以下是引用片段:
swap( int* p1,int* p2 ) { int p; p = *p1; *p1 = *p2; *p2 = p; }
总分值为10,下面给出几个不同得分的答案:
2分 以下是引用片段:
void strcpy( char *strDest, char *strSrc )
{
while( (*strDest++ = * strSrc++) != '\0' );
}
4分 以下是引用片段:
void strcpy( char *strDest, const char *strSrc )
{
//将源字符串加const,表明其为输入参数,加2分
while( (*strDest++ = * strSrc++) != '\0');
}
7分 以下是引用片段:
void strcpy(char *strDest, const char *strSrc)
{
//对源地址和目的地址加非0断言,加3分
assert( (strDest != NULL) &&(strSrc != NULL) );
while( (*strDest++ = * strSrc++) != '\0' );
}
10分 以下是引用片段:
//为了实现链式操作,将目的地址返回,加3分!
char * strcpy( char *strDest, const char *strSrc )
{
assert( (strDest != NULL) &&(strSrc != NULL) );
char *address = strDest;
while( (*strDest++ = * strSrc++) != '\0' );
return address;
}
从2分到10分的几个答案我们可以清楚的看到,小小的strcpy竟然暗藏着这么多玄机,真不是盖的!需要多么扎实的基本功才能写一个完美的strcpy啊! (4)对strlen的掌握,它没有包括字符串末尾的'\0'。
读者看了不同分值的strcpy版本,应该也可以写出一个10分的strlen函数了,完美的版本为:
int strlen( const char *str ) //输入参数const 以下是引用片段:
{
assert( strt != NULL ); //断言字符串地址非0
int len=0; //注,一定要初始化。
while( (*str++) != '\0' )
len++;
return len;
}
试题4:以下是引用片段:
void GetMemory( char *p )
{
p = (char *) malloc( 100 );
}
void Test( void ) {
char *str = NULL;
GetMemory( str );
strcpy( str, "hello world" );
printf( str );
}
试题5: 以下是引用片段:
char *GetMemory( void ) {
char p[] = "hello world";
return p;
}
void Test( void ) {
char *str = NULL;
str = GetMemory();
printf( str );
}
试题6:以下是引用片段:
void GetMemory( char **p, int num )
{
*p = (char *) malloc( num );
}
void Test( void )
{
char *str = NULL;
GetMemory( &str, 100 );
strcpy( str, "hello" );
printf( str );
}
试题7:以下是引用片段:
void Test( void ) {
char *str = (char *) malloc( 100 );
strcpy( str, "hello" );
free( str );
... //省略的其它语句 }
解答:试题4传入中GetMemory( char *p )函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,执行完 char *str = NULL; GetMemory( str );
后的str仍然为NULL;试题5中 char p[] = "hello world"; return p;
的p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期。 试题6的GetMemory避免了试题4的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句 tiffanybracelets *p = (char *) malloc( num );
后未判断内存是否申请成功,应加上: if ( *p == NULL ) {
...//进行申请内存失败处理
}
试题7存在与试题6同样的问题,在执行 char *str = (char *) malloc(100);
后未进行内存是否申请成功的判断;另外,在free(str)后未置str为空,导致可能变成一个“野”指针,应加上: str = NULL;
试题6的Test函数中也未对malloc的内存进行释放。 剖析:
试题4~7考查面试者对内存操作的理解程度,基本功扎实的面试者一般都能正确的回答其中50~60的错误。但是要完全解答正确,却也绝非易事。
软件开发网 www.mscto.com
对内存操作的考查主要集中在:
(1)指针的理解;
(2)变量的生存期及作用范围;
(3)良好的动态内存申请和释放习惯。
再看看下面的一段程序有什么错误:
以下是引用片段:
swap( int* p1,int* p2 ) {
int *p;
*p = *p1;
*p1 = *p2;
*p2 = *p;
}
在swap函数中,p是一个“野”指针,有可能指向系统区,导致程序运行的崩溃。在VC++中DEBUG运行时提示错误“Access Violation”。该程序应该改为 以下是引用片段:
swap( int* p1,int* p2 ) { int p; p = *p1; *p1 = *p2; *p2 = p; }
相关文章推荐
- C#读取C++编写的DLL时遇到的一个问题
- 从易到难编写C++程序,(8)问题:实现一个矩阵类
- 从易到难编写C++程序,(4)问题:实现一个大整数表示的BigInt类
- 编写一个标准strcpy函数
- c++新标准的一个问题
- 问题:利用 C++的各种控制语句编写一个万年历程序。 要求:显示任何年份的日历,日历以月份顺序排列,每月以星期顺序排列,类似于一 般挂历上的格式。
- 解决Visual Studio2008编写C++很纠结的一个问题
- 编写一个标准的strcpy函数
- 从易到难编写C++程序,(3)问题:实现一个复杂的猜数字游戏
- 一个C++学习者的问题
- Linux下,使用C/C++编写一个简单的消息处理程序
- 在C++的虚继承中要注意的一个传值问题
- 从易到难编写C++程序,(6)问题:利用问题(5)的随机数生成实现发牌
- 根据C++标准,如果const的引用被初始化为对一个临时变量的引用,那么它会使这个临时变量的生命期变得和它自己一样
- boiz 的C++ 备忘录(三)-- 注意strcpy函数的一个陷阱
- [初]一个C++关于string的小问题
- zz一个VS2005无法调试C++的问题
- Linux下,使用C/C++编写的一个简单的信号处理例程
- 一个C++返回值的问题
- 将标准 C++ 视为一个新语言