【C/C++笔试练习】内联函数、函数重载、调用构造函数的次数、赋值运算符重载、静态成员函数、析构函数、模板定义、最近公共祖先、求最大连续bit数

文章目录

  • C/C++笔试练习
  • 选择部分
    • (1)内联函数
    • (2)函数重载
    • (3)调用构造函数的次数
    • (4)赋值运算符重载
    • (5)静态成员函数
    • (6)调用构造函数的次数
    • (7)析构函数
    • (8)程序分析
    • (9)构造函数和析构函数
    • (10)模板定义
  • 编程题 day11
    • 最近公共祖先
    • 求最大连续bit数

C/C++笔试练习

选择部分

(1)内联函数

  关于内联函数说法错误的是()

  A. 不是任何一个函数都可定义成内联函数
  B. 内联函数的函数体内不能含有复杂的结构控制语句
  C. 递归函数可以被用来作为内联函数
  D. 内联函数一般适合于只有1~5行语句的小函数

  答案:C

  一般符合符合特定条件(如函数体内没有循环、递归)的函数才能被定义为内联函数。 因为内联函数的目的是通过将函数调用替换为函数体来减少函数调用的开销,如果函数体内包含复杂的控制结构,这种替换的效果可能会被削弱。

  内联函数只是一个给编译器的建议,最后内联是否实现,还需要看编译器是否会将其优化。一般内联函数一般适合于只有1~5行语句的小函数。这是因为内联函数的目的是减少函数调用的开销,而小函数体量小,更容易被编译器优化为内联形式。所以选项C是错误的。

  

(2)函数重载

  以下不是double compare(int,int)的重载函数的是()

  A. int compare(double,double)
  B. double compare(double,double)
  C. double compare(double,int)
  D. int compare(int,int)

  答案:D

  函数重载概念:

  函数重载: 是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同 ,常用来处理实现功能类似数据类型不同的问题。

  原函数double compare(int,int)的意思是接受两个整数作为参数,并返回一个double类型的数。

  A. int compare(double,double) - 这个函数接受两个double类型作为参数,并返回一个整数。这符合函数重载的条件,因为参数类型不同

  B. double compare(double,double) - 这个函数接受两个double类型作为参数,并返回一个double类型。这也符合函数重载的条件,虽然参数类型和原函数相同,但是参数类型不同,和第一个构成的原理一样。

  C. double compare(double,int) - 这个函数接受一个double类型和一个int类型作为参数,并返回一个double类型。这也符合函数重载的条件,因为参数类型不同

  D. int compare(int,int) - 这个函数接受两个int类型作为参数,并返回一个整数。虽然返回类型不同。但是返回类型不能作为函数重载的条件,因此这个选项不能被视为对原始函数的重载。所以选择D。

  

(3)调用构造函数的次数

  假定有类AB,有相应的构造函数定义,能正确执行语句,请问执行完此语句后共调用该类的构造函数次数为___

AB a(4),b(5),c[3],*p[2]={&a,&b}

  A. 5
  B. 4
  C. 3
  D. 9

  答案:A

  在执行AB a(4),b(5),c[3],*p[2]={&a,&b}时,首先创建了a和b两个对象,调用AB类的构造函数2次;然后创建了c数组,调用AB类的构造函数3次;最后创建了p数组,将a和b的地址赋给了p数组的两个元素,因为此时的p数组中存的值是指针类型,所以不会再次调用AB类的构造函数。因此,AB类的构造函数被调用了2+3=5次。所以答案为A。

  

(4)赋值运算符重载

  下列关于赋值运算符“=”重载的叙述中,正确的是

  A. 赋值运算符只能作为类的成员函数重载
  B. 默认的赋值运算符实现了“深层复制”功能
  C. 重载的赋值运算符函数有两个本类对象作为形参
  D. 如果己经定义了复制拷贝构造函数,就不能重载赋值运算符

  答案:A

  A. 赋值运算符只能作为类的成员函数重载。在C++中,赋值运算符“=”只能作为类的成员函数重载。通过将它重载为类的成员函数,我们可以控制类的对象之间的赋值行为。

  B. 默认的赋值运算符实现的是“浅层复制”,它只复制对象的值,而不会复制对象内部的指针或引用。所以默认的赋值运算符无法实现“深层复制”功能。

  C. 重载的赋值运算符函数应该只有一个本类对象作为形参,该函数将返回本类对象的引用。

  D. 如果已经定义了复制拷贝构造函数,就不能重载赋值运算符。这是不正确的。实际上,我们可以同时定义复制拷贝构造函数和重载赋值运算符。这两个操作是不同的,它们各自处理不同的情况。所以答案是A。

  

(5)静态成员函数

  下列有关静态成员函数的描述中,正确的是:

  A. 静态数据成员(非const类型)可以在类体内初始化
  B. 静态数据成员不可以被类对象调用
  C. 静态数据成员不受private控制符作用
  D. 静态数据成员可以直接用类名调用

  答案:D

  静态成员变量的概念:

  所有对象共享,并不属于具体的某个对象,静态成员变量需要在类中声明然后需要在类外单独进行定义,一定不能在构造函数初始化列表的位置初始化。

  在类外访问静态成员变量的时候可以使用: 对象.静态成员变量 或 类名::静态成员变量。

// 通过类名直接访问静态成员变量  
int MyClass::staticVar;  
// 通过对象名访问静态成员变量  
MyClass obj;  
int var = obj.staticVar;

  A.静态数据成员需要在类体外进行初始化,不能在类体内进行初始化。 静态数据成员(非const类型)不可以在类体内初始化。

  B. 静态成员函数可以通过类名或对象名调用, 所以静态数据成员可以通过合适的方法被类对象调用。

  C. 静态数据成员可以被声明为private、protected或public,并同样受到相应的访问控制。

  D. 静态成员函数可以通过类名或对象名调用, 不需要创建类的对象。所以答案是D。

  

(6)调用构造函数的次数

  若PAT是一个类,则程序运行时,语句“PAT(*ad)[3];”调用PAT的构造函数的次数是()

  A. 2
  B. 3
  C. 0
  D. 1

  答案:C

  注意该语句"PAT(ad)[3];",创建的是一个数组指针,是指向存放了3个PAT类型对象的数组的指针,类型还是指针,所有没有创建对象就没有调用构造函数。因此,答案为C。

  

(7)析构函数

  下面对析构函数的正确描述是()

  A. 系统不能提供默认的析构函数
  B. 析构函数必须由用户定义
  C. 析构函数没有参数
  D. 析构函数可以设置默认参数

  答案:C

  析构函数是一个特殊的成员函数,它用于释放对象使用的资源。系统提供了默认的析构函数,也可以由用户定义。析构函数没有参数,也不可以设置默认参数。 因此,选项C是正确的描述。

  

(8)程序分析

关于以下代码,哪个说法是正确的()

void myClass::foo(){
	delete this;
}
..
void func(){
	myClass *a = new myClass();
	a->foo();
}

  A. 它会引起栈溢出
  B. 都不正确
  C. 它不能编译
  D. 它会引起段错误

  答案:B

  该代码是先创建了一个对象myClass,然后用指向这个对象的指针a,去调用了这个类中的foo函数,这个函数是一个删除操作,可能缺失了部分函数体,但是没有语法问题。

【C/C++笔试练习】内联函数、函数重载、调用构造函数的次数、赋值运算符重载、静态成员函数、析构函数、模板定义、最近公共祖先、求最大连续bit数_第1张图片

  

(9)构造函数和析构函数

  哪种说法是错误的()?

  A. 构造函数可以有形参
  B. 析构函数可以有形参
  C. 构造函数无任何函数类型
  D. 析构函数无任何函数类型

  答案:B

  在C++中,构造函数和析构函数都是特殊的成员函数,它们分别在对象创建和销毁时调用。构造函数可以有形参,例如拷贝构造函数。

  析构函数不能有参数。它的作用是清理对象占用的资源,不需要传递任何参数。构造函数和析构函数都没有任何函数返回类型, 所以答案是B。

  

(10)模板定义

  有如下模板定义,在下列对fun的调用中,错误的是()

template <class T>
T fun(T x,T y){
	return x*x+y*y;
}

  A. fun(1, 2)
  B. fun(1.0, 2)
  C. fun(2.0, 1.0)
  D. fun< float >(1, 2.0)

  答案:B

  函数模版的实例化:

  fun的隐式实例化, 传给fun的两个形参类型必须一致,如fun(int,int),fun(double,double)

  fun的显示实例化, 两个参数可以不同,但是必须可以发生隐式实例化,加上转换后的类型即可,如 fun< float >(1, 2.0)

            

编程题 day11

最近公共祖先

最近公共祖先

【C/C++笔试练习】内联函数、函数重载、调用构造函数的次数、赋值运算符重载、静态成员函数、析构函数、模板定义、最近公共祖先、求最大连续bit数_第2张图片

  根据上述树中子节点与父节点之间的关系为root = child / 2,所以如果a != b,就让其中的较大数除以2, 如此循环直到a == b 即是原来两个数的最近公共祖先 比如: 2和7的最近公共祖先:7/2 = 3 —> 3/2 = 1, 2/2 = 1, 得到1为它们的公共祖先。

class LCA {
  public:
    int getLCA(int a, int b) 
    {
        while (a != b)
         {
            if (a > b)
                a /= 2;
            else
                b /= 2;
        }
        return a;
    }
};

  

求最大连续bit数

求最大连续bit数

【C/C++笔试练习】内联函数、函数重载、调用构造函数的次数、赋值运算符重载、静态成员函数、析构函数、模板定义、最近公共祖先、求最大连续bit数_第3张图片
  根据位运算,获取每一位的二进制值。获取第i位的值: (n >> i) & 1。如果1连续,则计数累加,如果不连续,则从0开始计数。

#include
#include
#include
using namespace std;

int main()
{
    int n;
    while (cin >> n) 
    {
        int count = 0, maxCount = 0;
        // n右移32次就变为0
        while (n) 
        {
            //获取当前位的二进制值
            if (n & 1) 
            {
                //如果1的值连续,计数累加,并且跟新最大计数
                ++count;
                maxCount = max(count, maxCount);
            } 
            else 
            {
            //如果1的值不连续,重新累加
                count = 0;
            }
            //右移一次,为获取下一位二进制值做准备
            n = n >> 1;
        }
        cout << maxCount << endl;
    }
    return 0;
}

你可能感兴趣的:(C/C++笔试练习,c语言,c++)