C++易错点总结

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.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值