美文网首页
C++学习笔记

C++学习笔记

作者: 兔子真的不吃草 | 来源:发表于2017-02-17 17:04 被阅读0次

    字符串问题

    字符串

    在定义字符串数组时,C有两种定义方法:

    
    char* str1 = "0123456789";
    
    char string[10];
    
    

    在第一种定义中,虽然只有10个字符,但是使用了11个字节来保存。最后一个字节为`\0`

    当进行strcpy的时候,strcpy(string,str1) 这样就会导致数组越界。

    在进行字符串拷贝时:

    
    void test2()
    
    {
    
    char string[10], str1[10];
    
    int i;
    
    for(i=0; i < 10; i++)
    
    {
    
    str1  = 'a';
    
    }
    
    strcpy( string, str1 );
    
    }
    
    

    使用库函数strcpy进行拷贝操作,strcpy会从原地址一直往后拷贝,直到遇见'\0'为止。所以拷贝的长度是不定的。如果一直没有遇到'\0'导致越界访问非法内存,程序就崩溃了。


    strcpy的实现

    如果编写一个标准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;
    
    }
    
    

    第五题

    检查下面代码有什么问题

    
    void GetMemory( char *p )
    
    {
    
    p = (char *) malloc( 100 );
    
    }
    
    void Test( void )
    
    {
    
    char *str = NULL;
    
    GetMemory( str );
    
    strcpy( str, "hello world" );
    
    printf( str );
    
    }
    
    

    GetMemory(char *p)函数中的形参为字符串指针,函数内部修改形参的值并不能真正的改变传入的参数值。在取得地址后并没有返回,所以str指针仍然是NULL。


    第六题

    下面代码会出什么问题

    
    char *GetMemory( void )
    
    {
    
    char p[] = "hello world";
    
    return p;
    
    }
    
    void Test( void )
    
    {
    
    char *str = NULL;
    
    str = GetMemory();
    
    printf( str );
    
    }
    
    

    p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期。


    第七题

    下面代码会出什么问题

    
    void GetMemory( char **p, int num )
    
    {
    
    *p = (char *) malloc( num );
    
    }
    
    void Test( void )
    
    {
    
    char *str = NULL;
    
    GetMemory( &str, 100 );
    
    strcpy( str, "hello" );
    
    printf( str );
    
    }
    
    
    1. 传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句*p = (char *)malloc(num);后没有判断内存是否申请成功,应加上:
    
    if ( *p == NULL )
    
    {
    
    ...//进行申请内存失败处理
    
    }
    
    
    1. 未释放内存

    2. printf(str) 改为printf("%s",str),否则可使用格式化字符串攻击。


    第八题

    下面代码会出什么问题

    
    void Test( void )
    
    {
    
    char *str = (char *) malloc( 100 );
    
    strcpy( str, "hello" );
    
    free( str );
    
    ... //省略的其它语句
    
    }
    
    

    没有进行判断内存是否申请成功;

    在free(str)后没有把str置为空,可能会成为一个野指针。应当加上str=NULL;


    第九题

    下面代码会出什么问题

    
    swap( int* p1,int* p2 )
    
    {
    
    int *p;
    
    *p = *p1;
    
    *p1 = *p2;
    
    *p2 = *p;
    
    }
    
    

    需要返回值

    p是一个野指针,有可能指向系统区,应该改为:

    
    void swap( int* p1,int* p2 )
    
    {
    
    int p;
    
    p = *p1;
    
    *p1 = *p2;
    
    *p2 = p;
    
    }
    
    

    如何判断flot类型变量是否为零

    const float EPSINON = 0.00001;

    if(x >= -EPSINON && x<= EPSINON)


    第11题

    以下为Windows NT下的32位C++程序,请计算sizeof的值

    
    void Func ( char str[100] )
    
    {
    
    sizeof( str ) = ?
    
    }
    
    void *p = malloc( 100 );
    
    sizeof ( p ) = ?
    
    

    sizeof( str ) = 4

    sizeof ( p ) = 4

    【剖析】

    Func ( char str[100] )函数中数组名作为函数形参时,在函数体内,数组名失去了本身的内涵,仅仅只是一个指针;在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。

    数组名的本质如下:

    (1)数组名指代一种数据结构,这种数据结构就是数组;

    例如:

    
    char str[10];
    
    cout << sizeof(str) << endl;
    
    

    输出结果为10,str指代数据结构char[10]。

    (2)数组名可以转换为指向其指代实体的指针,而且是一个指针常量,不能作自增、自减等操作,不能被修改;

    char str[10];

    str++; //编译出错,提示str不是左值

    (3)数组名作为函数形参时,沦为普通指针。

    Windows NT 32位平台下,指针的长度(占用内存的大小)为4字节,故sizeof( str ) 、sizeof ( p ) 都为4。

    相关文章

      网友评论

          本文标题:C++学习笔记

          本文链接:https://www.haomeiwen.com/subject/xijlwttx.html