【C/C++笔试练习】多态的概念、虚函数的概念、虚表地址、派生类的虚函数、虚函数的访问、指针引用、动态多态、完全数计算、扑克牌大小

news2024/11/18 19:50:17

文章目录

  • C/C++笔试练习
  • 选择部分
    • (1)多态的概念
    • (2)虚函数的概念
    • (3)虚表地址
    • (4)派生类的虚函数
    • (5)虚函数的访问
    • (6)分析程序
    • (7)指针引用
    • (8)动态多态
    • (9)分析程序
    • (10)分析程序
  • 编程题 day16
    • 完全数计算
    • 扑克牌大小

C/C++笔试练习

选择部分

(1)多态的概念

  下列一段 C++ 代码的输出结果是()

#include <iostream>
class Base{
public:
	int Bar(char x){
		return (int)(x);
	}
	
	virtual int Bar(int x){
		return (2 * x);
	}
};

class Derived : public Base{
public:
	int Bar(char x){
		return (int)(-x);
	}
	
	int Bar(int x){
		return (x / 2);
	}
};

int main(void)
{
	Derived Obj;
	Base *pObj = &Obj;
	printf("%d,", pObj->Bar((char)(100)));
	printf("%d", pObj->Bar(100));
}

  A. 100,-100
  B. 100,50
  C. 200,-100
  D. 200,50

  答案:B

int main(void)
{
	Derived Obj;//1.首先实例化一个子类对象
	Base* pObj = &Obj;//2.让父类指针接受子类的地址,形成多态

	printf("%d,", pObj->Bar((char)(100)));//3.调用Bar函数(参数是char),直接调用父类的Bar函数
	printf("%d,", pObj->Bar(100));//4.调用Bar函数(参数是int),形成多态,调用的是子类的Bar函数
}

在这里插入图片描述

  

(2)虚函数的概念

  关于函数的描述正确的是()

  A. 虚函数是一个static型的函数
  B. 派生类的虚函数与基类的虚函数具有不同的参数个数和类型
  C. 虚函数是一个非成员函数
  D. 基类中说明了虚函数后,派生类中起对应的函数可以不必说明为虚函数

  答案:D

  A.虚函数不可以是static。因为static函数保存在静态区中,在静态区中的虚函数没有this指针,就无法找到自身的函数地址,以此来生成虚表。

  B. 派生类的虚函数和基类的虚函数应该有相同的参数个数和类型,这样才能保证多态性。 如果派生类的虚函数和基类的虚函数参数不同,那么在调用时会发生错误。

  C. 虚函数必须是类的成员函数,不能是非成员函数。同A一样,如果是非成员函数就没有this指针,也无法生成虚表,因此无法实现多态。

  D. 在C++中,如果基类中的函数被声明为虚函数,那么派生类中的相应函数默认也是虚函数,不需要显式声明。 这是C++的隐式虚函数。

  

(3)虚表地址

  代码执行后,a和b的值分别为?

class Test{
public:
	int a;
	int b;
	
	virtual void fun() {}
	
	Test(int temp1 = 0, int temp2 = 0){
		a=temp1 ;
		b=temp2 ;
	}
	
	int getA() {
		return a;
	}
	
	int getB() {
		return b;
	}
};

int main()
{
	Test obj(5, 10);
	// Changing a and b
	int* pInt = (int*)&obj;
	*(pInt+0) = 100; 
	*(pInt+1) = 200; 
	cout << "a = " << obj.getA() << endl; 
	cout << "b = " << obj.getB() << endl; 
	return 0; 
}

  A. 200 10
  B. 5 10
  C. 100 200
  D. 100 10

  答案:A

int main()
{
	Test obj(5, 10);//1.直接创建Test类型的成员obj,将a=5,b=10
	int* pInt = (int*)&obj;//2.使用int类型指针,指向obj对象
	
	*(pInt + 0) = 100;//3.因为有虚函数的生成,所以此时改变的是虚表的地址,将虚表地址赋值为100
	*(pInt + 1) = 200;//4.此时将a的值赋值为200,b不变,
	cout << "a = " << obj.getA() << endl;//5.打印a,b
	cout << "b = " << obj.getB() << endl;
	return 0;
}

在这里插入图片描述

  

(4)派生类的虚函数

  当一个类的某个函数被说明为virtual,则在该类的所有派生类中的同原型函数_____?

  A. 只有 被重新说明时才识虚函数
  B. 只有被重新说明为virtual时才是虚函数
  C. 都不是虚函数
  D. 都是虚函数

  答案:D

  当一个类的某个函数被说明为virtual时,该函数就成为该类的一个虚函数。在派生类中,如果与基类中的虚函数具有相同的函数原型(即参数个数、类型和顺序相同),则该函数也被视为虚函数,无论是否显式地声明为virtual。

  这是因为在派生类中,基类中的虚函数仍然是可访问的,并且可以通过虚函数表进行动态绑定。 因此,在该类的所有派生类中,同原型的函数都是虚函数。因此,答案为D。

  

(5)虚函数的访问

  下面有关虚函数和非虚函数的区别说法错误的是?

  A. 子类的指针访问虚函数访问的是子类的方法
  B. 子类的指针访问非虚函数访问的是子类的方法
  C. 父类的指针访问虚函数访问的是父类的方法
  D. 父类的指针访问非虚函数访问的是父类的方法

  答案:C

  父类的指针访问虚函数时(前提是构成多态的情况下),访问的是子类的方法,而不是父类的方法。这是因为虚函数使用了动态绑定机制,在运行时根据对象的实际类型来确定调用哪个函数。因此,如果父类的指针指向的是子类对象,那么访问虚函数时会调用子类的方法。

  其他选项的说法是正确的。子类的指针访问虚函数或非虚函数时,访问的都是子类的方法。父类的指针访问非虚函数时,访问的是父类的方法。 因此,答案为C。

  

(6)分析程序

  下列程序的输出结果:

#include <iostream>
using namespace std;

class A
{
public:
	void print(){
		cout << "A:print()";
	}
};

class B: private A
{
public:
	void print(){
		cout << "B:print()";
	}
};

class C: public B
{
public:
	void print(){
		A:: print();
	}
};

int main()
{
	C b;
	b.print();
}

  A. A:print()
  B. B:print()
  C. 编译出错

  答案:C

  class B: private AB私有继承A,无法访问A中的私有成员函数。

在这里插入图片描述

  

(7)指针引用

  以下关于C++的描述中哪一个是正确的()

  A. 任何指针都必须指向一个实例
  B. 子类指针不可以指向父类实例
  C. 任何引用都必须指向一个实例
  D. 引用所指向的实例不可能无效

  答案:C

  A. 在C++中,指针可以被初始化为nullptr或者未初始化, 这两种情况下指针不指向任何实例。此外,指针也可以指向已经被销毁的对象,这种情况下指针同样不指向有效的实例。

  B. 在C++中,子类指针可以指向父类实例,这是因为子类继承了父类的所有成员和函数,所以子类指针可以访问父类的所有成员和函数。但是,如果通过子类指针访问父类实例中不存在的成员或函数,会导致编译错误或运行时错误。

  C. 在C++中,引用必须在声明时被初始化,且一旦初始化后就不能再改变引用的对象。 因此,引用必须指向一个有效的实例,否则会导致编译错误。

  D. 引用所指向的实例可能会变得无效,例如,如果引用所指向的对象被销毁或者引用被重新赋值指向其他对象,那么原来的引用就变得无效了。此外,如果引用所指向的对象是局部变量或临时对象,在对象生命周期结束后,引用也会变得无效。

  

(8)动态多态

  下面关于多态性的描述,错误的是()

  A. C++语言的多态性分为编译时的多态性和运行时的多态性
  B. 编译时的多态性可通过函数重载实现
  C. 运行时的多态性可通过模板和虚函数实现
  D. 实现运行时多态性的机制称为动态绑定

  答案:C

  多态性是指用同一个函数名调用不同的对象,产生不同的结果。多态性分为两种:编译时多态性和运行时多态性。

  编译时多态性是通过函数重载(overloading)实现的。函数重载是指在同一作用域内可以定义多个同名的函数,它们具有不同的参数类型或参数个数。 编译器在编译阶段根据调用函数时使用的实参类型和数量,选择对应的函数版本进行调用。

  运行时多态性是通过虚函数(virtual functions)实现的。虚函数是基类中声明的函数,它可以在派生类中被重写。通过将基类的指针或引用指向派生类对象,并调用该指针或引用上的虚函数, 程序可以在运行时确定调用哪个类的函数版本。这种机制称为动态绑定(dynamic binding)。

  模板是一种编译时多态性,它允许我们使用一种类型不确定的方式编写代码,并在编译时根据实际类型生成对应的代码。

  A选项描述了C++中多态性的分类,是正确的。

  B选项指出编译时的多态性可以通过函数重载实现,也是正确的。

  C选项错误地声称运行时的多态性可以通过模板实现。实际上,模板是编译时多态性的特性。

  D选项描述了实现运行时多态性的机制,是正确的。

  

(9)分析程序

  写出下面程序的输出结果

class A
{
public:
	void FuncA(){
		printf( "FuncA called\n" );
	}
	
	virtual void FuncB(){
		printf( "FuncB called\n" );
	}
};

class B : public A
{
public:
	void FuncA(){
		A::FuncA();
		printf( "FuncAB called\n" );
	}
	
	virtual void FuncB(){
		printf( "FuncBB called\n" );
	}
};

void main( void )
{
	B b;
	A *pa;
	pa = &b;
	A *pa2 = new A;
	pa->FuncA(); //( 3) 
	pa->FuncB(); //( 4)
	pa2->FuncA(); //( 5)
	pa2->FuncB();
	delete pa2;
}

  A. FuncA called FuncB called FuncA called FuncB called
  B. FuncA called FuncBB called FuncA called FuncB called
  C. FuncA called FuncBB called FuncAB called FuncBB called
  D. FuncAB called FuncBB called FuncA called FuncB called

  答案:B

void main(void)
{
	B b;
	A* pa;
	pa = &b;
	pa->FuncA();  //1.pa指针指向b对象,此时调用FuncA,不构成多态,打印A
	pa->FuncB();  //2.此时父类指针指向子类,"三同"形成多态,调用子类函数,打印BB

	A* pa2 = new A;
	pa2->FuncA();  //3.父类指针调用父类函数,打印A
	pa2->FuncB();  //4.同3,打印B
	delete pa2;
}

在这里插入图片描述

  

(10)分析程序

#include<iostream>
using namespace std;

class Base
{
public:
	virtual int foo(int x){
		return x * 10;
	}
	
	int foo(char x[14]){
		return sizeof(x) + 10;
	}
};

class Derived: public Base
{
	int foo(int x){
		return x * 20;
	}
	
	virtual int foo(char x[10]){
		return sizeof(x) + 20;
	}
} ;

int main()
{
	Derived stDerived;
	Base *pstBase = &stDerived;
	char x[10];
	printf("%d\n", pstBase->foo(100) + pstBase->foo(x));
	return 0;
}

  在32位环境下,以上程序的输出结果是?

  A. 2000
  B. 2004
  C. 2014
  D. 2024

  答案:C

int main()
{
	Derived stDerived;
	Base* pstBase = &stDerived;//1.多态形成
	char x[10];                //2.此时父类指针调用foo函数,因为多态,调用子类函数,100*20=200
	printf("%d\n", pstBase->foo(100) + pstBase->foo(x));//3.此时父类指针直接调用父类函数,8+10=18,一共是2000+18=2018
	return 0;                                           //注意32位下指针是4字节,64位下指针是8字节
}

在这里插入图片描述

            

编程题 day16

完全数计算

完全数计算

  解题思路:本题可以通过遍历每一个约数,求和,判断完全数。约数计算可以遍历sqrt(n)的范围。

#include<iostream>
using namespace std;

int Count_Of_Perfect_Number(int n) 
{
    int count = 0, sum = 0;
    for (int i = 2; i <= n; ++i) 
    {
        for (int j = 1; j < i; ++j) 
        { 
            if (i % j == 0) //对约数进行求和
                sum += j;
        }
        if (sum == i)
            count++;
        sum = 0;
    }
    return count;
}

int main() 
{
    int n, count;
    while (cin >> n) 
    {
        count = Count_Of_Perfect_Number(n);
        cout << count << endl;
    }
    return 0;
}

  

扑克牌大小

扑克牌大小

  解题思路:本题的题目意思是输入的只是这些类型中的一种,个子,对子,顺子(连续5张),三个,炸弹(四个)和对王。其实就是最多5张牌(顺子),最少1一张牌之间的比较。不存在其他情况。由于输入保证两手牌都是合法的,顺子已经从小到大排列,按照题意牌面类型的确定和大小的比较直接可以转换为牌个数的比较。

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

string FindMax(const string& line) 
{
    if (line.find("joker JOKER") != string::npos)
        return "joker JOKER";
    int dash = line.find('-');
    //分开两手牌
    string car1 = line.substr(0, dash);
    string car2 = line.substr(dash + 1);
    //获取两手牌的张数
    int car1_cnt = count(car1.begin(), car1.end(), ' ') + 1;
    int car2_cnt = count(car2.begin(), car2.end(), ' ') + 1;
    //获取两手牌的各自第一张牌
    string car1_first = car1.substr(0, car1.find(' '));
    string car2_first = car2.substr(0, car2.find(' '));
    if (car1_cnt == car2_cnt) 
    { 
        //两手牌的类型相同
        string str = "345678910JQKA2jokerJOKER";
        if (str.find(car1_first) > str.find(car2_first))
            return car1;
        return car2;
    }
    if (car1_cnt == 4) //说明是炸弹
        return car1;
    else if (car2_cnt == 4)
        return car2;
    return "ERROR";
}

int main() 
{
    string line, res;
    while (getline(cin, line)) 
    {
        res = FindMax(line);
        cout << res << endl;
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1298543.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

树莓派CSI摄像头在新系统(23年12月)中的不用设置了,没有开关,也没有raspistill

网上都是老信息&#xff0c;用的raspistill命令&#xff0c;至少新系统没有这个东西了&#xff0c;也不会在sudo raspi-config里面也没有摄像头的开关了。 ls /dev/video* 能看到摄像头video0&#xff0c;但是vcgencmd get_camera supported0&#xff0c; detected0&#xff0…

IEEE期刊论文模板

一、模板下载 1、登陆IEEE作者中心Author Center 地址&#xff1a;Publish with IEEE Journals - IEEE Author Center Journals 2、点击“Download a template” 3、在弹出的模板下载页面点击IEEE模板选择器“IEEE Template Selector” 4、在弹出的模板选择器页面点击“Tran…

积分商城小程序源码

商城小程序核心功能模块商城、积分商城、二级分销。php开发语言&#xff0c;有成品源码&#xff0c;支持二开&#xff0c;定制开发。 一 商城 商品分类&#xff0c;在线选择规格&#xff0c;加入购物车&#xff0c;在线下单支付&#xff0c;管理我的订单。 二 积分商城 在商…

C++初阶-string类的模拟实现

string类的模拟实现 一、经典的string类问题1.1 构造函数1.1.1 全缺省的构造函数 2.1 拷贝构造3.1 赋值4.1 析构函数5.1 c_str6.1 operator[]7.1 size8.1 capacity9.1 比较&#xff08;ASCII&#xff09;大小10.1 resize11.1 reserve12.1 push_back(尾插字符)13.1 append(尾插字…

二叉树的锯齿形层序遍历[中等]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给你二叉树的根节点 root &#xff0c;返回其节点值的 锯齿形层序遍历 。&#xff08;即先从左往右&#xff0c;再从右往左进行下一层遍历&#xff0c;以此类推&#xff0c;层与层之间交替进行&#xff09;。 示例 1&#xff1a; 输…

优化 | 用CVXPY手搓一个SVM

支持向量机&#xff08;Support Vector Machine&#xff0c;SVM&#xff09;是一种常用的机器学习算法&#xff0c;用于分类和回归问题。SVM的基本思想是寻找一个最优的超平面&#xff0c;将不同类别的数据样本分隔开来。设样本点为 ( x i , y i ) ( i 1 , ⋯ , n ) (x_i,y_i…

排序算法---冒泡排序

1. 原理 对数组进行遍历&#xff0c;每次对相邻的两个元素进行比较&#xff0c;如果大的在前面&#xff0c;则交换两个元素的位置&#xff0c;完成一趟遍历后&#xff0c;数组中最大的数值到了数组的末尾。再对前面n-1个数值进行相同的遍历。一共完成n-1趟遍历就实现了排序。 1…

分享下我发现的16个AI辅助编程的网站

这些工具和服务覆盖了多个方面&#xff0c;包括编程辅助、代码生成、问题解决、Git指令辅助、代码安全扫描等&#xff0c;为开发者提供了丰富的选择。 Codegeex (codegeex.cn/zh-CN): 类型&#xff1a;AI编程助手支持语言&#xff1a;Python, C/C, Java, Go, JavaScript等特点…

docke网络之bridge、host、none

一、bridge网络 1.创建一个测试容器 [rootlocalhost ~]# docker run -d -it --name busybox_1 busybox /bin/sh -c "while true;do sleep 3600;done" 03b308c847edd23f21ba69afb825d92f7aaeb05b1ff4431dd47ccee439a0361a 2.查看当前机器docker有哪些网络 [rootlocal…

获取类class对象的方式

一、什么是class对象 Class类位于java核心包lang包中&#xff0c;它是反射的源头。Class对象用于记录每个类的运行时数据结构&#xff0c;或者说是在内存中访问类的静态数据的接口&#xff0c;每个类都有一个唯一的Class对象。Class对象不能直接通过new来获取&#xff0c;因为…

空中消防员:无人机森林防火应用全面升级

森林是生态系统的重要组成部分&#xff0c;也是人类得以生存的关键。我国森林面积广大&#xff0c;存在火灾频发的困境。提升森林火灾防控能力是维护生态平衡、保护资源和保障人民生命安全的必要步骤。随着无人机技术的发展&#xff0c;其在无人机森林防火中的应用为传统巡查工…

temu发货单在哪里打印

在Temu平台上&#xff0c;打印发货单是进行订单发货的重要步骤之一。通过打印发货单&#xff0c;您可以方便地记录订单信息并与物流公司进行配合。以下是在Temu平台上打印发货单的详细步骤和注意事项。 先给大家推荐一款拼多多/temu运营工具——多多情报通 多多情报通是拼多多…

Chart 8 内核优化

文章目录 前言8.1 内核融合和拆分8.2 编译选项8.3 Conformant&#xff08;规范&#xff09; vs. fast vs. native math functions8.4 Loop unrolling8.5 避免分支发散8.6 Handle image boundaries8.7 Avoid the use of size_t8.8 通用 vs. 具名内存地址空间8.9 Subgroup8.10 Us…

C++ 哈希表实现

目录 前言 一、什么是哈希表 二、直接定值法 三、开放定值法&#xff08;闭散列&#xff09; 1.开放定制法定义 2.开放定制法实现 2.1类的参数 2.2类的构造 2.3查找实现 2.4插入实现 2.5删除实现 2.6string做key 四、哈希桶&#xff08;开散列&#xff09; 1.开散…

让老板成为数据分析师,我用 ChatGpt 链接本地数据源实战测试

本文探究 ChatGpt 等AI机器人能否帮助老板快速的做数据分析&#xff1f;用自然语言同老板进行沟通&#xff0c;满足老板的所有数据分析的诉求&#xff1f; 一、背景 设想这样一个场景&#xff1a;你是某贸易公司的老板&#xff0c;公司所有的日常运转数据都在私域的进销存系统…

tqdm详细教程,实现tqdm进度条完美设计;解决进度条多行一直刷新的问题;如何使得滚动条不上下滚动(保持一行内滚动)

一、tqdm简介 tqdm是一个python进度条库&#xff0c;可以在 Python长循环中添加一个进度提示信息。 二、3种使用方法 1.tqdm(range)-自动更新 import time from tqdm import range# 自动更新 for i in tqdm(range(10)): # 共可以更新10次进度条time. Sleep(0.5) # 每次更新间…

nginx多端口部署

1.配置nginx.conf文件 有几个端口需要部署就写几个server&#xff0c;我这里只部署了两个端口分别为80和81端口&#xff0c;所以有两个server文件。80端口项目入口在根目录的test文件中&#xff0c;81端口项目入口在根目录的test1文件夹中。 2.准备项目文件html文件 在/test1…

2023年终总结-轻舟已过万重山

自我介绍 高考大省的读书人 白&#xff0c;陇西布衣&#xff0c;流落楚、汉。-与韩荆州书 我来自孔孟故里山东济宁&#xff0c;也许是小学时的某一天&#xff0c;我第一次接触到了电脑&#xff0c;从此对它产生了强烈的兴趣&#xff0c;高中我有一个愿望&#xff1a;成为一名计…

【漏洞复现】华脉智联指挥调度平台/xml_edit/fileread.php文件读取漏洞

Nx01 产品简介 深圳市华脉智联科技有限公司&#xff0c;融合通信系统将公网集群系统、专网宽带集群系统、不同制式、不同频段的短波/超短波对讲、模拟/数字集群系统、办公电话系统、广播系统、集群单兵视频、视频监控系统、视频会议系统等融为一体&#xff0c;集成了专业的有线…

【力扣】移除链表元素203

目录 1.前言2. 题目描述3. 题目分析3.1 不带哨兵位3.2 带哨兵位 4. 附代码4.1 不带哨兵位4.2 带哨兵位 1.前言 这里开始介绍从网上一些刷题网站上的题目&#xff0c;在这里做一些分享&#xff0c;和学习记录。 先来介绍一些力扣的OJ题目。 这里的OJ就是我们不需要写主函数&…