2018《程序设计实习》错误集锦

      由于本人在学习算法时理论基础与编程能力过于不匹配(理论基础差,编程能力——没有),经常会犯各种各样脑残的错误,写出各种各样丑陋的代码(比我还丑),故开此长更博客,希望能帮到自己,也希望提醒大家不要犯类似错误,否则智商就会变成我这种水平。

        最后更新:04月05日

       1:C++ 变量名不能以数字开头    报错关键词:expecting unqualified … (此映射非单射,即还有其他原因也会这样报错)

       2:凡是出现不给定保留位数的浮点数输出要求,一律用cout,慢点就慢点。(%g的功能听说不只是舍去无用0那么简单)

       3:苹果

Apple Fun(const Apple & a) {
    	a.PrintTotal();
    	return a;//第二个数是5而不是6是因为此处返回时会二进制复制创建一个对象之后析构,不调用构造函数
    }

Apple(){cout<<"construct"<
construct
construct
construct
construct
4
destruct
construct
construct
5
destruct
destruct
destruct
destruct
1
destruct
destruct


4:Big and Base

Big(int n): b(n),v(n) {}
Big(const Big &a): b(a.b.k),v(a.v) {} //一个类的对象作为另一个的成员变量,务必使用列表式初始化

5:奇怪的构造函数

int main()
    {
        Sample a(5);//转换
    //cout<

6:MyString

MyString(const MyString &a){//务必深拷贝,否则会出现神秘的内存泄漏
	if(a.p){
		p = new char[strlen(a.p)+1];
		strcpy(p,a.p);
	}else
		p = NULL;
}
MyString &operator = (const MyString &a){//这里也是,务必深拷贝
        if(p) delete [] p;
        if(a.p == NULL) p = NULL;
        else{
            p = new char[strlen(a.p) + 1];
            strcpy(p,a.p);
        }
 }//总而言之,出现了指针,迅速写好深拷贝的复制构造函数以及等号的重载,别自己到草纸上猜指针都指到哪里。我替你猜了,它们指向了远方。
friend ostream &operator << (ostream &s, const MyString &a){
        s<

7:神秘的输出

    #include 
    using namespace std;
    class A {
    public:
    	int val;

    	A(int a) {this->val = a;}
	A &GetObj(){
		return *this;
	}
	A(){this->val = 123;}
    };
    int main()
    {
    	int m,n;
    	A a;
    	cout << a.val << endl;
    	while(cin >> m >> n) {
    		a.GetObj() = m;
    		cout << a.val << endl;
    		a.GetObj() = A(n);//总结:凡是出现神秘的给一个函数赋值,通常都是返回了一个引用。(神秘啊)
    		cout << a.val<< endl;
    	}
    	return 0;
    }

8:重载加号
include  
    using namespace std;
    class MyInt 
    { 
    	int nVal; 
    	public: 
    	MyInt( int n) { cout<<"num_construct"<nVal = source.nVal;}
	operator int() const{ return nVal; }
	MyInt &operator - (const int &a){
		nVal -= a;
		return *this;
	}
    }; 
    int Inc(int n) {
    	return n + 1;
    }
    int main () { 
    	int n;
    	while(cin >>n) {
    		MyInt objInt(n); 
    		objInt-2-1-3; 
    		cout << Inc(objInt);
    		cout <<","; 
    		objInt-2-1; 
    		cout << Inc(objInt) << endl;
    	}
    	return 0;
    }//重载运算符,如果想修改调用它的函数,同时还想连加连减,就务必返回个引用。我把源码改了改,就能更好地看出连加连减时的工作细节。20
-----------------------------这是加了引用的输出---------------------------
num_construct
15,12
-----------------------------这是没加引用的输出---------------------------
20
num_construct
copy_construct
copy_construct
copy_construct
19,copy_construct
copy_construct
17


9:BigInt

    #include  
    #include  
    #include  
    #include  
    using namespace std;
    const int MAX = 110; 
    class CHugeInt {
	public:
		int len;
		char *p;
		CHugeInt(){p=NULL;}
		CHugeInt(const char* s){
			this->len = strlen(s);
			p = new char[this->len];
			for(int i=0; ilen; i++){
				*(p+i) = *(s+len-i-1);
			}
			*(p+len) = '\0';//可要注意类型转换构造函数里已经完成了翻转
		}
		CHugeInt(const int &n){
			char tmp[100];
			sprintf(tmp,"%d",n);
			this->len = strlen(tmp);
			p = new char[this->len];
			for(int i=0; ilen; i++){
				*(p+i) = tmp[len-i-1];
			}
			*(p+len) = '\0';//可要注意类型转换构造函数里已经完成了翻转
		}
		CHugeInt(const CHugeInt &a){
			this->len = a.len;
			p = new char[this->len];
			for(int i=0; ilen; i++){
				*(p+i) = *(a.p+i);
			}
			*(p+len) = '\0';
		} 
		~CHugeInt(){
			delete []p;
			p = NULL;
		}
		int min(const CHugeInt &b){
			if(this->len < b.len) return this->len;
			else return b.len;
		}
		int max(const CHugeInt &b){
			if(this->len > b.len) return this->len;
			else return b.len;
		}
		CHugeInt operator + (const CHugeInt &a){
			int tmp[220];
			char temp[220];
			int tmpl;
			memset(tmp,0,sizeof(tmp));
			for(int i=0; ip[i]) + a.p[i] - 2 * '0'); 
				tmp[i+1] += tmp[i] / 10;
				tmp[i] = tmp[i] % 10;
			}
			if(min(a)==this->len){
				for(int i=this->len; ilen; i++){
					tmp[i] += (int)(this->p[i] - '0');
					tmp[i+1] = tmp[i] / 10;
					tmp[i] = tmp[i] % 10;
				}
			}
			if(tmp[max(a)] == 0) tmpl = max(a);
			else tmpl = max(a) + 1;
			for(int i=0; ip) delete []this->p;
			this->len = a.len;
			p = new char[a.len];
			for(int i=0;ilen;i++) this->p[i] = a.p[i];
			*(p+len) = '\0';
			return *this;
		}
		friend ostream &operator << (ostream &s, CHugeInt a){
			char tmp[220];
			for(int i=0;i> s >> n) {
    		CHugeInt a(s);
    		CHugeInt b(n);
    		cout << a + b << endl;
		cout << n + a << endl;
		cout << a + n << endl;
		b += n;
		cout  << ++ b << endl;
		cout << b++ << endl;
		cout << b << endl;
    	}
    	return 0;
    }//有一个要点:想给指针做一些变动的话,一定要注意是不是需要先清空原先指向的东西。
    //牢记指针四部曲:delete掉原来的空间,指向NULL,申请新空间,指向新空间。要注意指针被Delete之后还会指向被释放的空间,这种指针叫野指针,在析构的时候会发生段错误(Segment Fault)
    //所以在delete空间之后一定要指针一定要纪律性指向NULL,不管之后要不要赋值,这是个好习惯。还有,这题的加号重载有点多,其实只要重载好对象+对象,剩下的套用一下就好了。注意一下构造函数的细节。



3月23日

手写string类:有了前一次大整数的基础,这次就顺利很多了。

    #include 
    #include 
    using namespace std;
    int strlen(const char * s)
    {	int i = 0;
    	for(; s[i]; ++i);
    	return i;
    }
    void strcpy(char * d,const char * s)
    {
    	int i = 0;
    	for( i = 0; s[i]; ++i)
    		d[i] = s[i];
    	d[i] = 0;

    }
    int strcmp(const char * s1,const char * s2)
    {
    	for(int i = 0; s1[i] && s2[i] ; ++i) {
    		if( s1[i] < s2[i] )
    			return -1;
    		else if( s1[i] > s2[i])
    			return 1;
    	}
    	return 0;
    }
    void strcat(char * d,const char * s)
    {
    	int len = strlen(d);
    	strcpy(d+len,s);
    }
    class MyString
   {
    private:
    	char *p;
    	int l;
    public:
    	char *sub;
    	int lsub;
    	void init(){
    		if(l!=0) delete []p;//如果之前没手动让p指向什么乱七八糟的东西,就不要调用这个函数。如果简单地问p是否指向空指针,在第一次使用p时会报错。
    		p = NULL;
    		l = 0;
    	}
    	MyString(){
    		p = NULL;
    		sub = NULL;
    		l = 0;
    		lsub = 0;
    	}
    	MyString(const char *s){
    		p = NULL;
    		sub = NULL;
    		l = 0;
    		lsub = 0;
    		this->l = strlen(s);
    		if(this->l!=0){
    			this->p = new char(this->l+1);
    			for(int i=0;il;i++) *(this->p+i) = *(s+i);
    			*(this->p+l) = '\0'; //very important
    		}
    	}
    	MyString(const MyString &a){
    		p = NULL;
    		sub = NULL;
    		l = 0;
    		lsub = 0;
    		this->l = a.l;
    		if(this->l!=0){
    			this->p = new char(this->l+1);
    			for(int i=0;il;i++) *(this->p+i) = *(a.p+i);
    			*(this->p+l) = '\0';
    		}
    	}
    	~MyString(){
    		init();
    	}
    	MyString &operator = (const MyString &a){//必须有返回值。等号的显式表达尚待探讨
    		init();
    		this->l = a.l;
    		if(this->l!=0){
    			this->p = new char(this->l+1);
    			for(int i=0;il;i++) *(this->p+i) = *(a.p+i);
    			*(this->p+l) = '\0';
    		}
    		return *this;
    	}
    	friend ostream &operator << (ostream &s, MyString &tmp){
    		if(tmp.p==NULL) s<<"";//非常重要,否则流会间断
    		else s<p+idx);
    	}
    	MyString &operator += (const MyString &a){
    		*(this) = *(this) + a;
    		return *(this);
    	}
    	friend MyString operator + (const char *s, const MyString &a){
    		MyString ret(s);
    		ret = ret + a;
    		return ret;
    	}
    	friend MyString operator + (const MyString &a, const char *s){
    		MyString ret(s);
    	    ret = a + ret;
    		return ret;
    	}
    	friend bool operator == (const MyString &a, const MyString &b){
    		int tmp = strcmp(a.p, b.p);
    		if(tmp==0) return true;
    		else return false;
    	}
    	friend bool operator < (const MyString &a, const MyString &b){
    		int tmp = strcmp(a.p, b.p);
    		if(tmp==-1) return true;
    		else return false;
    	}
    	friend bool operator > (const MyString &a, const MyString &b){
    		int tmp = strcmp(a.p, b.p);
    		if(tmp==1) return true;
    		else return false;
    	}
    	char *operator () (const int s_idx, const int s_len){//传整数的过程是什么样的呢
    		if(lsub!=0){
    			lsub = 0;
    			sub = NULL;
    		}
    		lsub = s_len;
    		sub = new char(lsub+1);
    		for(int i=0;i *s2 )
    	return 1;
    }
    int main()
    {
    	MyString s1("abcd-"),s2,s3("efgh-"),s4(s1);
    	MyString SArray[4] = {"big","me","about","take"};
    	cout << "1. " << s1 << s2 << s3<< s4<< endl;
    	s4 = s3;
        s3 = s1 + s3;
    	cout << "2. " << s1 << endl;
    	cout << "3. " << s2 << endl;
    	cout << "4. " << s3 << endl;
    	cout << "5. " << s4 << endl;
    	cout << "6. " << s1[2] << endl;
    	s2 = s1;
    	s1 = "ijkl-";
    	s1[2] = 'A' ;
    	cout << "7. " << s2 << endl;
    	cout << "8. " << s1 << endl;
    	s1 += "mnop";
    	cout << "9. " << s1 << endl;
    	s4 = "qrst-" + s2;
    	cout << "10. " << s4 << endl;
    	s1 = s2 + s4 + " uvw " + "xyz";
    	cout << "11. " << s1 << endl;
    	qsort(SArray,4,sizeof(MyString),CompareString);
    	for( int i = 0;i < 4;i ++ )
    	cout << SArray[i] << endl;
    	//s1的从下标0开始长度为4的子串
    	cout << s1(0,4) << endl;
    	//s1的从下标5开始长度为10的子串
    	cout << s1(5,10) << endl;
    	return 0;
    }

4月5日

在清明的早晨的03:22,我终于肝完了魔兽……作为War3这么多年的老玩家,我第一次感觉到玩够了……

没啥说的,请移步我的独立博文

你可能感兴趣的:(原创)