目录
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。