【C++笔试强训】第十二天

选择题

image-20230404173833709

解析:引用:引用是对象的别名,并没有开辟属于自己的空间,两者同用一块内存,引用值改变也会引起引用对象值的改变;

引用在声明的时候必须要初始化,而指针不用,指针可以为空指针;

引用之后就不能引用别的对象,此时再引用只是将值传递给了引用。

image-20230404173846086

解析:析构函数可以在类体内定义,也可以先在类内声明,在类外定义;

一个类只有一个析构函数,析构函数不能重载;

析构函数的函数名和类名相同,只不过是加了一个~

析构函数无显示参数,只有一个隐藏的this指针。

image-20230404173855240

解析:运算符重载要使用operator关键字,加上+运算符,同时要有参数,参数是类;+有两个操作数,在类中定义的所以有一个隐藏的this指针,所以显示参数只有一个。不能重载的运算符有. sizeof :: .* ?:

同时还要有返回值,对于加法运算符的重载,它要返回加的结果,所以返回值也是一个类。

image-20230404173936938

解析:只有创建对象才会调用构造函数。

c1是个类会调用构造函数,c2是个指针并不会调用构造函数,c3也是一个指针,但是用new的时候会自动调用构造函数,c4是c1的别名并没有调用构造函数。

image-20230404173947471

解析:类和c语言中的结构体还是不同的,c语言中的结构体里面只能声明变量,不能声明函数,而类里面就是可以;

类是用来描述对象的,描述对象有哪些属性,有哪些方法,对象是类的具体的体现;类和对象的关系就是抽象和具体的关系。

image-20230404173957013

解析:只有单例模式中一个类只能创建一个对象,别的都可以创建多个;

一个类可以实例化出很多对象,类是对某一类对象的抽象,类和对象的关系是一直数据类型与变量的关系。

image-20230404174004130

解析:该段代码中有好几处错误:

1.delete释放的空间应该为动态开辟的,但是该对象并不是动态开辟的,所以错误;

2.在析构函数中使用delete,会造成无穷递归,因为delete会自动调用析构函数,析构函数中又有delete……可以通过编译,但是运行时会崩溃;

3.this = NULL会编译失败,因为this类型是const修饰的:类类型* const this ,即this指针的指向不能被修改。

解析:类可以有多个构造函数,但是每个类只会有一个析构函数;

而对于拷贝构造并不是每个类都必须的,当我们没有自己实现的时候,编译器会生成默认的拷贝构造函数,完成浅拷贝;

对于每个类都有一个什么类型的构造函数是我们所不能确定的

image-20230404174105781

解析:静态的成员函数没有this指针,友元函数也没有this指针,不是类的成员函数也没有this指针。

f1不是成员函数,没有;f2是静态,也没有;f3是友元函数,友元函数不是类的成员函数,所以友元函数也没有this指针,也不会受访问限定符的限制;f4是非静态成员函数。

image-20230404174114278

解析:堆的开辟需要向操作系统递交请求,所以受操作系统的限制,一般来说栈的大小都是很小的。 堆必须要动态的申请,栈既可以动态的申请也可以静态的分配。

编程题

1.二进制插入

image-20230401212956063

解析:通过下图我们可以看出将n向左移动j位,再与m按位或就可以得到结果。

image-20230401212902685

class BinInsert {
public:
    int binInsert(int n, int m, int j, int i) {
        // write code here
        return (m << j) | n;
    }
};

2.查找组成一个偶数最接近的两个素数

image-20230401213311648

解析:我们可以通过将这个偶数从1开始拆分,拆分之后判断这两个数是否是素数(判断是否是素数,要用本身%2~本身-1才能准确判断),是素数直接跳出本次循环,不是素数的计算差值,找到最小差值的两个数保存起来。(这个思路是自己想到的)

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

int main() {
    int n = 0;
    cin >> n;
    int i = 1;
    int count1 = 0;
    int count2 = 0;
    while (i <= n / 2) {
        int min_num = 0;
        int num1 = i;
        int num2 = n - i;
        if (i == 1)
            min_num = num2 - num1;
        for (int j = 2; j <= max(num1, num2); j++) {
            if ((num1 % j == 0 && num1 != j) || (num2 % j == 0 && num2 != j)) {
                break;
            }
            if (j == max (num1, num2)) {
                if (min_num < num2 - num1 && num2 - num1 >= 0)
                    min_num = num2 - num1;
                    count1 = num2;
                    count2 = num1;
                }
        }
        i++;
    }
    if(count1 + count2 == n)
    {
        cout << count2 << endl;
        cout << count1 << endl;
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

答案解析:本题首先需要判断素数,素数表示除过1和本身,不能被其它数整除(sqrt函数是用来开平方的,求一个数是不是素数只用%到其一半即可)。通过循环遍历来判断一个数是否为素数。最近的两个素数应该从最中间的位置开始向两边查找。

#include <iostream>
#include <cmath>
using namespace std;
bool IsPrime(int x)
{
    for(int i = 2; i <= sqrt(x); i++)
    {
        if(x % i == 0)
            return false;
    }
    return true;
}
int main() {
    int n = 0;
    while(cin >> n)
    {
        for(int i = n / 2; i >= 0; i--)
        {
            if(IsPrime(i) && IsPrime(n - i))
            {
                cout << i << endl;
                cout << n - i << endl;
                break;
            }
        }
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

猜你喜欢

转载自blog.csdn.net/weixin_53943591/article/details/129972802