C++笔试强训10


一、选择题

1-5题

在这里插入图片描述
前面做过很多次了,记住就好,不在赘述,选C。

内联函数经常使用的场景包括:

  1. 小型函数:当函数体非常小,只包含几条语句时,使用内联函数可以显著减少函数调用的开销。这是因为小型函数的函数体本身就很小,直接展开到调用点并不会显著增加代码大小,反而可以减少因函数调用而产生的额外开销。

  2. 频繁调用的函数:如果某个函数在程序中被频繁调用,那么将其定义为内联函数可以显著提高程序的执行效率。这是因为每次函数调用都会有一定的开销,如果这个函数被频繁调用,那么这些开销的累积就会非常显著。

  3. 不会改变函数参数或全局状态:内联函数通常不应该修改其参数或全局状态,因为内联展开后,这些修改可能会影响到程序的其他部分,导致难以追踪的错误。因此,那些只进行简单计算或数据转换,不改变外部状态的函数,更适合作为内联函数。

  4. 模板函数:在模板编程中,模板函数的实例化可能会导致大量的函数生成。如果这些模板函数很小且被频繁使用,将它们定义为内联函数可以减少代码膨胀并提高执行效率。


在这里插入图片描述
选C,解释如下:
在C++中,有些运算符是不能被重载的,这些运算符主要包括以下几类:

  1. 条件运算符(?:)

    • 条件运算符用于三元条件判断,其形式为exp1 ? exp2 : exp3
    • 不能重载的原因是,如果允许重载,则无法保证运算符的跳转性质,即只执行exp2exp3中的一个。
  2. 成员访问运算符(.)

    • 用于访问类的成员变量和成员函数。
    • 不能重载的原因是,重载后可能无法明确引用对象的成员,导致运算符意义的混淆。
  3. 域运算符(::)

    • 用于访问类的静态成员、命名空间的成员等。
    • 不能重载的原因是,该运算符只是在编译时进行域解析,没有运算的参与,且其运算对象是类型而不是变量或一般表达式,不具备重载的特征。
  4. 长度运算符(sizeof)

    • 用于返回数据类型或变量的大小。
    • 不能重载的主要原因是内部许多指针和操作都依赖它,重载后可能导致混乱和不可预测的行为。
  5. 成员指针访问运算符(->* 和 .*)

    • ->*用于通过指向类成员的指针访问类的成员。
    • .*用于通过对象直接访问类的成员指针所指向的成员。
    • 这两个运算符也不能被重载,因为它们涉及到类成员的指针访问,重载后可能破坏原有的语义和功能。

在这里插入图片描述
A:构造函数没返回值,故A错
B: 该函数只有一个参数,是对自身对象的引用,不是某个对象,故B错
C:若没有手动实现,编译器确实会自动生成,但访问权限不是protected而是共有的public,故C错。
D:符合构造函数的作用,正确。

故选D。


在这里插入图片描述
const成员函数,const加在函数名()的后面,此处的const实际上修饰的是this指针,表明在该成员函数中,不能修改非静态的成员变量。


在这里插入图片描述
函数类型即返回值类型不能作为重载函数的调用依据。
故选C。


6-10题

在这里插入图片描述
MyClass a[5],这个语句会调用5次构造函数,因为在栈上创建了五个该类型的对象。

MyClass* b[6],这个语句不会调用构造函数,因为它只是一个指针数组,里面存放的类型是MyClass*,此时还没有new,new的时候才会调用构造函数。

故选B。


在这里插入图片描述
此处考的是:
在初始化列表中初始化成员的次序:与该成员在初始化列表中出现的先后次序无关,真正的初始化次序与成员变量在类中声明的先后次序保持一致。

本题中声明次序是:
Printer a;
Printer b;
故会先初始化a,后初始化b,和初始化列表中a,b的顺序无关,故会输出ab
故选C。


在这里插入图片描述
在主流编译器中空类的大小一般都是1,如果空类的大小为0的话,比如说类A创建了三个对象a、b、c,那在内存上,这三对象不就在同一个内存位置了嘛?怎么区分呢?所以一般主流编译器都把空类大小设置成1。
主流编译器,vs或者g++上都是这样的。
其他的不能说太死
故选B。
在这里插入图片描述


在这里插入图片描述

如下图,选B。

在这里插入图片描述


在这里插入图片描述
a是const int类型的,&a就是const int*类型的,此处强转成int*类型赋值给p,然后通过p修改了值为20,然后打印出a的值和*p的值。按我们的认知应该都是20才对,但实际上不是,a是10,*p是20,原因如下:

C++中被const修饰的变量:该变量已经是一个常量了,还具有替换的作用编译器在编译代码,在程序中看到对常量中内容读取时,会直接使用常量中的内容替换该常量

  1. 声明和初始化:

    const int a = 10;
    

    编译器知道 aconst 并将其值设置为 10。它可能会将 a 放置在只读内存区域。

  2. 指针赋值:

    int * p = (int *)(&a);
    

    a 的地址被转换为 int * 并赋值给 p。这个操作本身无害,但为潜在的未定义行为做了准备。

  3. 尝试修改:

    *p = 20;
    

    这一行尝试修改 a 的内存地址中的值。由于 aconst,这会导致未定义行为。在许多系统上,这可能实际上不会改变 a 的值。

  4. 输出:

    cout << "a = " << a << ", *p = " << *p << endl;
    

    此处,编译器可能会直接使用 a 的常量值(10),因为它假设 a 未被改变。*p 访问修改后的内存位置,显示 20。

因此,打印的值是:

a = 10, *p = 20

结论
a 保持不变而 *p 显示 20 的关键原因是编译器优化和 a 可能被放置在只读内存中。const 修饰符通知编译器 a 不应被更改,导致输出中观察到的行为。


二、编程题

题目一

题目链接:
井字棋
在这里插入图片描述

提交代码:

class Board {
  public:
    bool checkWon(vector<vector<int> > board) {
        bool ret = false;
        for (int i = 0; i < board.size(); i++) {
            if (board[i][0] == 1 && board[i][1] == 1 && board[i][2] == 1) {
                return true;
            }
            else if (board[0][i] == 1 && board[1][i] == 1 && board[2][i] == 1) {
                return true;
            }
        }
        if(board[0][0] == 1 && board[1][1] == 1 && board[2][2] == 1){
            return true;
        }
        return false;
    }
};

运行结果:
在这里插入图片描述


题目二

题目链接:
密码强度等级
在这里插入图片描述

提交代码:

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

int main() {
    string str;
    cin >> str;
    int score = 0;
    size_t size = str.size();
    if (size <= 4) score += 5;
    else if (size >= 5 && size <= 7) score += 10;
    else score += 25;

    int number = 0, bigchars = 0, smallchars = 0, character = 0;
    for (auto s : str) {
        if (s >= 'a' && s <= 'z') smallchars++;
        else if (s >= 'A' && s <= 'Z') bigchars++;
        else if (s >= '0' && s <= '9') number++;
        else character++;
    }

    if (number == 0) score += 0;
    else if (number == 1) score += 10;
    else score += 20;

    if (bigchars == 0 && smallchars == 0) score += 0;
    else if ((bigchars == 0 && smallchars != 0) || (bigchars != 0 &&
             smallchars == 0)) score += 10;
    else score += 20;

    if (character == 0) score += 0;
    else if (character == 1) score += 10;
    else score += 25;

    if (bigchars != 0 && smallchars != 0 && number != 0 &&
            character != 0) score += 5;
    else if (((bigchars == 0 && smallchars != 0) || (bigchars != 0 &&
              smallchars == 0)) && number != 0 && character != 0) score += 3;
    else if (((bigchars == 0 && smallchars != 0) || (bigchars != 0 &&
              smallchars == 0)) && number != 0) score += 2;
    if (score >= 90) {
        cout << "VERY_SECURE" << endl;

    } else if (score >= 80) {
        cout << "SECURE" << endl;
    }

    else if (score >= 70) {
        cout << "VERY_STRONG" << endl;

    } else if (score >= 60) {
        cout << "STRONG" << endl;

    } else if (score >= 50) {
        cout << "AVERAGE" << endl;

    } else if (score >= 25) {
        cout << "WEAK" << endl;

    } else {
        cout << "VERY_WEAK" << endl;

    }
    return 0;
}
// 64 位输出请用 printf("%lld")

运行结果:
在这里插入图片描述

  • 27
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

争不过朝夕,又念着往昔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值