1.下面这段代码考察变量的作用域问题。
- #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元素返回一个引用对象的原因。
- #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.浅复制和深复制
- #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.看看下面这个代码怎么错了?
- #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.