553C++笔试笔记2019

目录

1.读程题

1

2.

3.

4.

5.全局对象,静态局部对象等调用和析构问题。

6.还是作用域问题:

7基类与派生类的调用顺序问题。

8.

2.程序填空

3.程序改错

4.编程

1.鞍点

2.函数模板二分查找

3.最长的公共单词:


1.读程题

1

int main() {
	int a = 4, c = 0, b = 1;
	for (int i = 0; i < 5; ++i) {
		switch ((--a) > 0) {
		case 0:switch (c++) {
			case 0:cout << "%";
			case 1:cout << "#";
		}break;
			case 1:switch (b) {
			case 0:cout << "*"; --b; break;
			case 1:cout << "@"; --b; break;
			}
			default:cout << "&";
		}
		cout << "!" << endl;
	}
	return 0;
}
@&!  
*&!
&!
%#!
#!        //注意break的位置

2.

void fun(int a) {
	cout << a << endl;
}
int main() {
	int i = 0, k = 2;
	for (int i = 1; i <= 3 ; i++) {
		fun(i * k);
	}
	cout << i << " " << endl;
	return 0;
}

考察作用域,循环里的i是块作用域,生命仅限于{}内。结果是:

2

4

6

0

3.

void swap2(int* t1,int* t2){
	int *tmp;
	tmp=a;
	a=b;
	b=tmp;
}
int main(){
int a=5;
int b=6;
int* pa=&a;
int* pb=&b;
swap2(pa,pb);
}

类似于上面的swap2()函数,传入的是两个指针的值,相当于新建了指针t1和t2,分别指向a和b,交换了两个指针的值(即a和b的地址),这样t1就指向了b而t2指向了a,并没有交换pa和pb的值。

 正确代码应如是:

void swap2(int* a, int* b) {
	int tmp;
	tmp = *a;
	*a = *b;
	*b = tmp;
}

直接修改这两个指针的值

如果不用指针交换还可以使用引用:

void swap2(int& a,int& b){
	int tmp;
	tmp=a;
	a=b;
	b=tmp;
}

这里的引用不可少,不然交换的形参生命仅存在于函数内,出去就死克。

4.

统计字符串在\0之前数字的个数:

int main() {
	int n = 0;
	char s[] = "012wtr\0wer09";
	for (int i = 0; s[i] != 0; ++i) {
		if (s[i] >= '0' && s[i] <= '9') {
			++n;
		}
	}
	cout << "n=" << n << endl;
	return 0;
}

5.全局对象,静态局部对象等调用和析构问题。

class A {
public:
	A(int x) :xx(x) {
		cout << "A()" << xx << endl;
	}
	~A() {
		cout << "`A()" << xx << endl;
	}
private:
	int xx;
};
A a(1);
int main() {
	A b(2);
			A c(3);
	return 0;
}

明显是依次调用a,b,c的构造函数,在依次调用c,b,a的析构函数。

总结如下:

全局对象的构造函数在main函数之前调用,析构函数在main函数之后调用。

全局静态对象和全局对象一样。

局部栈对象在定义的时候调用构造函数,出了可见范围的时候调用析构函数。

堆对象在new的时候调用构造函数,delete的时候调用析构。

局部静态对象在定义的时候调用构造,main函数之后调用析构。

6.还是作用域问题:

#include<iostream>
using namespace std;
class cc {
private:
	int xx;
	int yy;

public:
	cc(int x, int y):xx(x),yy(y) {

	}
	friend cc operator ++(cc c) {  //	friend cc operator ++(cc &c) {
		++c.xx;
		++c.yy;
		return c;
	}
	void print() {
		cout << xx << " " << yy;
	}
};
int main() {
	cc a(10, 20);
	a.print();
	for (int i = 0; i < 5; i++) {
		++a;
		a.print();
	}
	a.print();
	return 0;
}

形参应该引用,否则没有意义。

7基类与派生类的调用顺序问题。

class base {
public:
	base() {
		cout << "base()"<<endl;
	}
	~base() {
		cout << "~base()"<<endl;
	}
};
class derived :public base {
public:
	derived() {
		cout << "derived()"<<endl;
	}
	~derived() {
		cout << "~derived()"<<endl;
	}
};
int main() {
	base b;
	derived c;
}
base()
base()
derived()
~derived()
~base()
~base()

再看看指针情况:

int main() {
	base* d = new base();
	delete d;
	cout << endl;
	base* e = new derived();
	delete e;
	cout << endl;
	derived* f = new derived();
	delete f;

}
base()
~base()

base()
derived()
~base()

base()
derived()
~derived()
~base()

总结: 

当 new Derived() 时,会先运行基类的构造函数,然后再运行派生类的构造函数;

而当 delete pointer 时,编译器只考虑 pointer 指针本身的类型而不关心 pointer 实际指向的类

即:

若 pointer 为基类指针,则只调用基类的析构函数(不管 pointer 实际指向的是基类还是派生类);

若 pointer 是派生类指针,则先调用派生类的析构函数,再调用基类的析构函数,调用顺序调用构造函数的顺序相反。

8.

class base {
public:
	base() {
		cout << "base()"<<endl;
	}
	virtual void print() const {
		cout << "I AM A" << endl;
	}
	~base() {
		cout << "~base()"<<endl;
	}
};
class derived :public base {
public:
	derived() {
		cout << "derived()"<<endl;
	}
	void print() const {
		cout << "I AM B" << endl;
	}
	~derived() {
		cout << "~derived()"<<endl;
	}
};

int main() {
	base* pa = new derived();
	pa->print();
	delete pa;
	return 0;
}
base()
derived()
I AM B
~base()

和第七题差不多,当存在指针时,构造看后面,析构看前面,遵循“基1派2”。

2.程序填空

注意第二个空,i从1开始。

int main() {
	int i, j, k, num;
	num = 0;//第一个空
	for( i=0; i <= 9;i++)//分号前第一个空
		for (j = 0; j <= 9; j ++) {//第二个分号前第二个空
			if (i != j) {//第三个空
				for (k = 0; k <= 9; k++)
					if(k!=i&&k!=j)//第四个空
						num++;//第五个空
			}
		}
	cout << num;
	return 0;
}

3.程序改错

class Acc {
	char ch = ' ';

public:
	char& rise() {
		return ++ch;
	}
	Acc(char c) :ch(c) {}

	void print() {
	cout << ch;
	}
};
int main() {
	Acc a('w');
	a.rise();
	a.print();
	return 0;
}

这题我挺迷惑的,打印函数是我自己加的。错的几个地方:rise()写在外面了,默认是私有。char类型应该用‘ ’来初始化,而非" "。

关于引用返回值的一些补充:C++ 把引用作为返回值 | 菜鸟教程

4.编程

1.鞍点

#include<iostream>
using namespace std;

void judge(int a[3][4]) {
	int ansi, ansj;
	bool find = false;
	for (int j = 0; j < 4; j++) {
		 ansj = j, ansi = 0;
		for (int i = 0; i < 3; i++) {
			if (a[i][j] < a[ansi][j])
				ansi = i;
		}
		find = true;
		for (int j = 0; j < 4; j++) {
			if (a[ansi][j] > a[ansi][ansj])
				find= false;
		}
		if (find)
			break;
	}
	if (find) {
		cout << "鞍点:num[" << ansi << "][" << ansj << "]=" << a[ansi][ansj] << endl;
	}
	else
		cout << "无鞍点" << endl;
}

int main() {
	int a[3][4];
	srand((unsigned)time(NULL));
	for (int j = 0; j < 4; j++)
		for (int i = 0; i < 3; i++)
			a[i][j] = rand() % 9 + 1;
	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 4; j++) {
			cout << a[i][j] << " ";
		}
		cout << endl;
	}
	judge(a);
}

//找到列上最小的点,默认其为鞍点(置true),再检查行上是否最大,不行就退出这层循环,继续下一列。

2.函数模板二分查找

#include<iostream>
using namespace std;

template<class T>
void Find(T a[], int i, int j, T b) {
	if (b<a[i] || b>a[j]) {
		cout << "dont exit";
		exit(EXIT_FAILURE);
	}
	int mid = (i + j) / 2;
	if (b == a[mid]) {
		cout << "a[" << mid << "]=" << b << endl;
		exit(EXIT_SUCCESS);
	}
	if (a[mid] < b)
		Find(a, mid+1, j, b);
	else
		Find(a, i, mid - 1, b);
}
int main() {
	int a[5] = { 1,2,3,4,5 };
	Find(a, 0, 4, 4);

}

3.最长的公共单词:

#include<iostream>
#include<fstream>
#include<string>

using namespace std;
#define MaxSize 100
string a;
class selfSttring {
private:
	string str[MaxSize];
	int length;
public:
	selfSttring() {
		int i = 0;
		ifstream is("D:/word.txt");
		if (!is) {
			cout << "file cannot be opened!";
				exit(EXIT_FAILURE);
		}
		while (is>>a) {
			str[i] = a;
			i++;
		}
		length = i;
	}
	~selfSttring() {
		//delete[] str;
		//cout << "~selfString";
	}
	void print() const{
		for (int i = 0; i < length; i++)
			cout<<str[i]<<" ";
		cout << length<<endl;
	}
	void find(string a[],int le) {
		string max="";
		for(int i=0;i<le;i++)
			for (int j = 0; j < length; j++) {
				if (a[i] == str[j]&&a[i].length()>=max.length())
					max = a[i];
			}
		cout <<"最长的公共单词:"<< max;
	};
};

int main() {
	selfSttring s;
	s.print();
	string a[] = { "love","is","beautiful","forever"};
	s.find(a, 4);
	return 0;
}

没太理解题目的意思,哪来的两个字符串呢,我理解的是:类的自己的成员是一个,find的参数算另一个,以键入的方式io。

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值