【C++笔试强训】第十三天 àì夳堔傛蜴生んèń 2024-04-20 06:14 80阅读 0赞 > **?C++笔试强训** > > -------------------- > > * **博客主页:**[一起去看日落吗][Link 1] > * **分享博主的C++刷题日常,大家一起学习** > * **`博主的能力有限,出现错误希望大家不吝赐教`** > * **分享给大家一句我很喜欢的话:夜色难免微凉,前方必有曙光** ?。 > > -------------------- > > ![在这里插入图片描述][047d8ad26e314dc7bc7aa19a6ce9ccb0.jpeg_pic_center] ?? -------------------- ## 选择题 ## ### ?第一题 ### 下面叙述不正确的是() A 派生类一般都用公有派生 B 对基类成员的访问必须是无二义性的 C 赋值兼容规则也适用于多重继承的组合 D 父类的公有成员在派生类中仍然是公有的 A 大部分都是公有派生,私有和保护也可以 B 如果出现二义性则会编译不通过 C 赋值兼容规则指的是,1.把子类对象直接赋值给父类,2. 把子类对象的地址赋给父 类的指针,3.可以把子类对象的引用对父类初始化,也适用于多重继承的组合 D 如果在继承的过程当中如果继承方式变私有则不行 > **`这道题的答案是D`** -------------------- ### ?第二题 ### 下面 C++ 程序的运行结果是() #include <iostream> using namespace std; class parent { int i; protected: int x; public: parent() { x = 0; i = 0; } void change() { x++; i++; } void display(); }; class son :public parent { public: void modify(); }; void parent::display() { cout << "x=" << x << endl; } void son::modify() { x++; } int main() { son A; parent B; A.display(); A.change(); A.modify(); A.display(); B.change(); B.display(); return 0; } A x=1 x=0 x=2 B x=2 x=0 x=1 C x=0 x=2 x=1 D x=0 x=1 x=2 A.display() // 打印x的值,构造函数初始化x=0; A.change()// 调动完之后x,i都为1 A.modify()//调动之后++为2 A.display()//打印x的值为2 //B是一个新的空间 B.change();//初始化只后++变1 B.display()//x的值为1 > **`这道题的答案是C`** -------------------- ### ?第三题 ### 关于虚函数的描述正确的是() A 派生类的虚函数与基类的虚函数具有不同的参数个数和类型 B 内联函数不能是虚函数 C 派生类必须重新定义基类的虚函数 D 虚函数可以是一个static型的函数 A 如果两个虚函数没有什么联系则不同,如果派生类的虚函数重写父类的虚函数,则需要具有相同的参数类型和参数个数 B 内联函数不能声明成虚函数,在真正寻址的时候内联函数会被展开的,最后不会存在 C 派生类不一定需要重新定义基类的虚函数 D 静态函数没有this指针,虚函数需要靠this指针调用 > **`这道题的答案是B`** -------------------- ### ?第四题 ### 当一个类对象的生命周期结束后,关于调用析构函数的描述正确的是() A 如果派生类没有定义析构函数,则只调用基类的析构函数 B 如果基类没有定义析构函数,则只调用派生类的析构函数 C 先调用派生类的析构函数,后调用基类的析构函数 D 先调用基类的析构函数,后调用派生类的析构函数 子类对象如果继承了父类,则会先构造父类再构造子类,而析构则是相反的 先调用派生类的析构函数,后调用基类的析构函数,跟是否定义没有关系 > **`这道题的答案是C`** -------------------- ### ?第五题 ### 以下关于纯虚函数的说法,正确的是() A 声明纯虚函数的类不能实例化 B 声明纯虚函数的类成虚基类 C 子类必须实现基类的 D 纯虚函数必须是空函数 纯虚函数是一种特殊的虚函数,在许多情况下,在基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现留给该基类的派生类去做。这就是纯虚函数的作用。 A 纯虚函数不可以实例化 B 虚基类和抽象类是两个概念,纯虚函数是抽象类,虚基类是菱形继承 ![请添加图片描述][3667882c0173489dab883389618c477d.png]这样最后D里面会有两个\_a,代码会冗余,则需要BC虚拟继承A,A这就是虚基类 C 如果不想实现多态可以不实现 D 纯虚函数不一定只能是空函数,也可以是有实现的函数 > **`这道题的答案是A`** -------------------- ### ?第六题 ### 下列描述,正确的一共有多少个() 1)const char *p,这是一个常量指针,p的值不可修改 2)在64位机上,char *p= “abcdefghijk”; sizeof(p)大小为12 3)inline会检查函数参数,所以调用开销显著大于宏 4)重载是编译时确定的,虚函数是运行时绑定的 A 1 B 2 C 3 D 4 const char \*p,这是一个常量,p可修改,p所指的值不可以修改 在64位机上,指针是8个字节 内联函数和宏都会展开,开销差不多 虚函数式动态编译,只有4正确 > **`这道题的答案是A`** -------------------- ### ?第七题 ### C++将父类的析构函数定义为虚函数,下列正确的是哪个() A 释放父类指针时能正确释放子类对象 B 释放子类指针时能正确释放父类对象 C 这样做是错误的 D 以上全错 这道题需要知道C++将父类的析构函数定义为虚函数有什么用?? 析构函数定义为虚函数时:基类指针可以指向派生类的对象(多态性),如果删除该指针delete \[\]p;就会调用该指针指向的派生类析构函数,而派生类的析构函数又自动调用基类的析构函数,这样整个派生类的对象完全被释放。 > **`这道题的答案是A`** -------------------- ### ?第八题 ### 下列关于多态性说法不正确的是( ) A 多态性是指同名函数对应多种不同的实现 B 重载方式仅有函数重载 C 重载方式包含函数重载和运算符重载 D 多态性表现为静态和动态两种方式 A 多态性是指同名函数对应多种不同的实现,多种形态,用相同代码实现不同作用 B 还有运算符重载 C 重载方式包含函数重载和运算符重载 D 多态性表现为静态和动态两种方式,可以动态实现 > **`这道题的答案是B`** -------------------- ### ?第九题 ### 分析一下这段程序的输出 #include<iostream> using namespace std; class B { public: B() { cout << "default constructor" << " "; } ~B() { cout << "destructed" << " "; } B(int i): data(i) { cout << "constructed by parameter" << data << " "; } private: int data; }; B Play( B b) { return b; } int main(int argc, char *argv[]) { B temp = Play(5); return 0; } A constructed by parameter5 destructed destructed B constructed by parameter5 destructed C default constructor" constructed by parameter5 destructed D default constructor" constructed by parameter5 destructed destructed Play(5); 这是个临时无名对象 调用 的是: B(int i) : data(i) \{ cout<< “constructed by parameter” << data <<endl; \} 然后调用默认operator=(没有,编译器自动生成一个),将临时无名对象拷贝到temp,拷贝完,要析构。所以其实构造了两个对象,函数结束要析构temp,所以调用两次析构函数。 > **`这道题的答案是A`** -------------------- ### ?第十题 ### 求输出结果 求输出结果 #include <iostream> using namespace std; class A { public: virtual void print() { cout << "A::print()" << "\n"; } }; class B: public A { public: virtual void print() { cout << "B::print()" << "\n"; } }; class C: public A { public: virtual void print() { cout << "C::print()" << "\n"; } }; void print(A a) { a.print(); } int main() { A a, *aa, *ab, *ac; B b; C c; aa = &a; ab = &b; ac = &c; a.print(); b.print(); c.print(); aa->print(); ab->print(); ac->print(); print(a); print(b); print(c); } A C::print() B::print() A::print() A::print() B::print() C::print() A::print() A::print() A::print() B A::print() B::print() C::print() A::print() B::print() C::print() A::print() A::print() A::print() C A::print() B::print() C::print() A::print() B::print() C::print() B::print() B::print() B::print() D C::print() B::print() A::print() A::print() B::print() C::print() C::print() C::print() C::print() A 虚函数打印,B 继承A,重写虚函数打印,C 继承A,重写虚函数 abc.printf 是静态绑定,直接访问,打印ABC aa,ab,ac-> 是多态,调用的是子类对象,所以也是打印ABC printf(abc)可以接受父类,通过父类调用父类对象,拥有是父类,无法调用子类,所以打印AAA > **`这道题的答案是B`** -------------------- ## 编程题 ## ### ?第一题 ### 链接:[参数解析][Link 2] ![请添加图片描述][70b7851156f74206b8f1d7848665f95e.png]\- 解题思路 本题通过以空格和双引号为间隔,统计参数个数。对于双引号,通过添加flag,保证双引号中的空格被输出。 * 代码演示 #include <iostream> #include <string> #include <vector> using namespace std; void cmdLineParse(const string &str) { string tmp = ""; vector<string> svec; bool flag = false; //判断是否处于字符串状态 for(int i = 0;i < str.size();++i) { if(str[i] == '"')//判断是否是字符串的起始或结束 { flag = !flag;//说明处于字符串状态 } else if(str[i] == ' ' && !flag)//判断参数的分隔或者是否为字符串内容 { svec.push_back(tmp); tmp = ""; } else//正常的参数内容 { tmp += str[i]; } } svec.push_back(tmp);//最后可能没有空格,需要追加 cout << svec.size() << endl; for(int i = 0;i < svec.size();++i) { cout << svec[i] << endl; } } int main() { string str; while(getline(cin,str)) { cmdLineParse(str); } return 0; } -------------------- ### ?第二题 ### 链接:[跳石板][Link 3] ![请添加图片描述][05005bc7b3db43dab2f039adaee663a1.png] * 题目解析 题目的意思是从N开始,最少需要累加几步可以变成指定的数字M,每次累加的值为当前值的一个约数。 * 解题思路 将1 - M个石板看做一个结果数组stepNum,每个stepNum\[i\]储存着从起点到这一步最小的步数,其中0为不能到达。 从起点开始对stepNum进行遍历,先求i的所有约数(即从stepNum\[i\]能走的步数),然后更新那几个能到达的位置的最小步数。如果不能到达则更新为此时位置的最小步数 + 1,如果是能到达的就更新为min(已记录的最小步数,此处的最小步数 + 1)),遍历一遍后得到结果。 * 代码演示 #include <iostream> #include <vector> #include <limits.h> #include <cmath> using namespace std; void get_div_num(int v,vector<int> &a) { for(int i = 2;i <= sqrt(v);++i) { if(v%i==0) { a.push_back(i); if(v/i != i) a.push_back(v/i); } } } int Jump(int n,int m) { vector<int> step(m+1,INT_MAX);//INT_MAX表示不可达到 step[n] = 0;//当前位置初始化 for(int i = n;i < m;++i) { if(step[i] == INT_MAX) continue; vector<int> a; //获取i的约数并保存 get_div_num(i,a); for(int j = 0;j < a.size();++j) { if(a[j]+i <= m && step[a[j]+i] != INT_MAX)//需要挑选一个最小值 { //需要挑选一个最小值 step[a[j]+i] = min(step[a[j]+i],step[i]+1); } else if(a[j]+i <= m) { step[a[j]+i] = step[i]+1; } } } return step[m] == INT_MAX?-1:step[m]; } int main() { int n,m,min_step; while(cin >> n >> m) { min_step = Jump(n,m); cout << min_step << endl; } return 0; } -------------------- [Link 1]: https://blog.csdn.net/m0_60338933?type=blog [047d8ad26e314dc7bc7aa19a6ce9ccb0.jpeg_pic_center]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/20/20bba99f8e034fe2bcc75fc58c2c76e0.jpeg [3667882c0173489dab883389618c477d.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/20/131d7ca7c6954765b20bf4041c359539.png [Link 2]: https://www.nowcoder.com/practice/668603dc307e4ef4bb07bcd0615ea677?tpId=37&&tqId=21297&rp=1&ru=/activity/oj&qru=/ta/huawei/question-ranking [70b7851156f74206b8f1d7848665f95e.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/20/b039e4b68a10426c87348e68bc94f38f.png [Link 3]: https://www.nowcoder.com/practice/4284c8f466814870bae7799a07d49ec8?tpId=85&&tqId=29852&rp=1&ru=/activity/oj&qru=/ta/2017test/question-ranking [05005bc7b3db43dab2f039adaee663a1.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/04/20/50de06e6e9bb4925b5fe8ee98316b07c.png
还没有评论,来说两句吧...