您的位置:首页 > 编程语言 > C语言/C++

C++易错点总结

2015-03-17 20:43 197 查看
1.下面这段代码考察变量的作用域问题。

[cpp] view
plaincopy

#include<iostream>  

using namespace std;  

  

void other()  

{  

    static int a = 2;  

    static int b;  

    int c = 10;  

    a += 2;  

    c += 5;  

    cout<<"----other-----"<<endl;  

    cout<<a<<" "<<b<<" "<<c<<endl;  

    b = a;  

}  

  

int main()  

{  

    static int a;  

    int b= -10, c= 0;  

  

    cout<<"----main-----"<<endl;  

    cout<<a<<" "<<b<<" "<<c<<endl;  

    c += 8;  

    other();  

    cout<<"----main-----"<<endl;  

    cout<<a<<" "<<b<<" "<<c<<endl;  

    other();  

    return 0;  

}  

答案如下:

----main-----

0 -10 0

----other-----

4 0 15

----main-----

0 -10 8

----other-----

6 4 15

考察点:

局部作用域中静态变量的特点是,它并不会随着每次函数调用而产生一个副本,也不会随着函数返回而失效。也就是说,当一个函数返回后,下一次再调用时,该变量还会保持上一回的值,即使发生了递归调用,也不会为该变量建立新的副本,该变量会在每次调用见共享。

解析:

第一次a=0,b=-10,c=0,之后调用other函数,因为a和b为静态局部变量,所以在other函数就有保持值的特点,这时,根据就近原则,a=4,b=0,c=15.

然后继续执行,发现a,b的改变都是在other中,而对main中的a,b没有影响,所以a,b值不变,c由于自加8,所以c=8.然后又进入other,因为a,b为局部静态变量,不会再每次进入相同函数时产生副本,所以进入时a=4,自加2,等于6,上次函数结束时b=a,所以b=4,这次再进入时b还是保持4不变,而c是动态局部变量,每次进入函数都要重新初始化,所以c=10,自加5等于15.所以a=6,b=4,c=15.

2.说明Arr类中,element元素返回一个引用对象的原因。

[cpp] view
plaincopy

#include<iostream>  

#include<cstdio>  

#include<cassert>  

using namespace std;  

  

class Point  

{  

private:  

    int x, y;  

public:  

    Point():x(0), y(0)  

    {  

        cout<<"default called"<<endl;  

    }  

    Point(int x, int y):x(x), y(y)  

    {  

        cout<<"not default called"<<endl;  

    }  

    ~Point(){cout<<"destructor called"<<endl;}  

    int getx()const{return x;}  

    int gety()const{return y;}  

    void move(int newx, int newy)  

    {  

        x = newx;  

        y = newy;  

    }  

  

};  

  

class Arr  

{  

private:  

    Point *p;  

    int size;  

  

public:  

    Arr(int size):size(size)  

    {  

        p = new Point[size];  

    }  

    ~Arr()  

    {  

        cout<<"deleting"<<endl;  

        delete []p;  

    }  

  

    Point &element(int index)  

    {  

        assert(index >= 0 && index < size);  

        return p[index];  

    }  

};  

  

int main()  

{  

    int count;  

    cin>>count;  

    Arr points(count);  

    points.element(0).move(5, 0);  

    points.element(1).move(5, 2);  

    return 0;  

}  

答案:

因为我们创建的points对象是一个在类内部由动态数组实现的对象,而我们对数组的操作无非就是取元素,改变元素,如果element不返回一个引用时,那么我们可以认为这个元素是只读的,我们无法通过赋值等途径改变这个元素(其实是一个对象)的值,而我们返回一个引用的话,就相当于取出元素本身,就可以对它进行正常的读写操作。这样才符合数组的性质。

3.浅复制和深复制

[cpp] view
plaincopy

#include<iostream>  

using namespace std;  

  

class A  

{  

private:  

    int len;  

    char *str;  

public:  

    A(int length, char *s)  

    {  

        len = length;  

        str = new char[length];  

        strcpy(str, s);  

    }  

    A(const A &p) //浅复制就是注释掉自定义复制拷贝函数(试试看?)  

    {  

        len = p.len;  

        str = new char[p.len]; //深复制  

        strcpy(str, p.str);  

    }  

    ~A()  

    {  

        delete str;  

    }  

    void show()  

    {  

        cout<<str<<endl;  

    }  

};  

  

int main()  

{  

    A a(10, "hello");  

    A b = a;  

    b.show();  

    return 0;  

}  

4.看看下面这个代码怎么错了?

[cpp] view
plaincopy

#include<iostream>  

using namespace std;  

  

#define MAX 255  

int main()  

{  

    char p[MAX+1];  

    unsigned char ch;  

    for(ch=0;ch<=255;++ch)  

    {  

        p[ch]=ch;  

        cout<<ch<<"";  

    }  

    p[255]='\0';  

    cout<<ch<<endl;  

}  

错误在于ch<=255,这个条件。因为ch是unsigned char类型的,占据一个字节,所以最大值为255.当ch循环到255时候+1之后溢出,就变成0了。这样,就陷入了死循环。正确该法是ch<255.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: