【笔试刷题训练】day_08

选择题

在这里插入图片描述

  1. 引用可以看作一个变量的别名,定义的时候必须进行初始化(即说明是哪一个变量的别名),而指针可以不需要初始化,后期进行赋值使用
  2. 由于引用必须在定义的时候初始化,所以不存在空引用(必须是一个变量或者常量的别名),但指针可以是空指针,不指向任何内容
  3. 引用定义之后就是一个变量的别名,不可以再引用其他变量。但指针可以
int main()
{
	int a = 10;
	int& ra = a;	//ra是a的引用
	int b = 20;
	ra = 20;		//这里并不能让ra引用b,而是把ra所指空间的内容改为了20
  1. 函数传参的时候,函数参数可以是引用也可以是指针类型。

  2. 引用的底层是指针,所以引用传参的时候底层也是传递的地址,只是在语法角度看到的是传值

int func(int& left,int& right)
{
	cout << "func()"<<endl;
}
int main()
{
	int a = 10,b=20;
	func(a,b);		//这里传递的其实是 a和b的地址(汇编角度)
	return 0;
}

综上几条,答案选择E,引用其实也是传递的地址!

在这里插入图片描述

在这里插入图片描述

对于B:用一个类的对象赋值给一个另一个对象,说明另一个对象是已经存在的,所以会调用赋值运算符重载,不会调用拷贝构造!

在这里插入图片描述

在这里插入图片描述

这一题考察了构造和拷贝构造的编译器优化问题
具体的可以看这篇文章:构造和拷贝构造的优化

在这里插入图片描述

运算符重载指的是:定义一个类之后,如果想通过该类的对象直接使用某种运算符,编译器是不支持的,因为他不知道对于这个自定义类型这种运算表示什么具体含义。所以需要对运算符进行重载,重载类专属的运算符
运算符重载

  1. 重载成类的成员函数,此时有一个默认的形参就是this,所以形参个数看上去比运算符需要的个数少1
  2. 重载成类的友元函数(因为需要访问到类内部成员,需要友元关系),形参必须要有一个类类型的对象!否则怎么使用该类的成员以达成重载的目的?

所以,如果用友元函数重载成一个运算符,而参数列表中没有任何参数,那么一定是重载错误的!友元函数又没有默认的this,你一个参数都没有怎么算是这个类的运算符重载?所以选D,重载错误
如果是用成员函数重载运算符,即使一个参数都不设置,也会有一个默认的this指针,也就是说至少是一个一元运算符。如果是友元函数重载运算符,一个参数都没有,就是0元运算符?那就不是运算符了(重载错误),运算符必须要有操作数哇!)

在这里插入图片描述

先构造的后析构,后构造的先析构
所以a先构造 b后构造
则b先析构 a后析构
选D
具体看我这篇文章呀:👉 构造函数和析构函数的顺序问题

在这里插入图片描述

这个题主要说一下B选项
我们知道引用就是某一块空间的另一个名字,但是如果该空间本身不属于你,而是属于错误的内存地址或者无权限的地址,那么这个引用就是悬挂引用

int func(int& ref)
{
	 cout << ref << endl;	//输出ref
}
int main()
{
	int* ptr = nullptr;
	func(*ptr);	//这里把ptr解引用 传递给形参ref 
	//因为ptr不指向任何空间,所以*ptr就是一个错误的内存空间
	// 而ref引用该内存空间,所以ref就是一个悬挂引用
}

编程题

1. 最小公倍数

👉 题目链接

思路1:暴力枚举

有两个数 A、B

要求A和B的最小公倍数,最小公倍数一定是大于等于这两个数的

所以我们可以从A和B中较大的那个数开始向上走,一定会遇到一个数可以整除A和B,遇到的第一个满足该条件的就是 最小公倍数

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

int main()
{
    int A,B;
    //输入两个正整数
    cin >> A >> B;
    //死循环,遇到最小公倍数跳出
    for(int i = max(A,B);;i++)
    {
        //如果两个都能被整除
        if(i%A ==0 && i%B==0)
        {
            cout << i << endl;
            break;
        }
    }
    return 0;
}

思路2:最小公倍数 = 两数之积/最大公约数

  • 首先求最小公约数:辗转相除法

    辗转相除法例子:

    A:30 B:12
    
    n1为30  n2为12
    第一次:30 % 12 = 6
    	   此时n1变为12 , n2变为6(上一次的余数)
    第二次:12 % 6 = 0
    	   当n1%n2=0的时候,跳出循环
    	   最大公约数就是此时的n2
    
  • 然后返回(A*B)/ 最大公约数

#include<iostream>
using namespace std;

int main()
{
    int A,B;
    //输入两个正整数
    cin >> A >> B;
    int mul = A*B;
    int ret = A%B;
    while(ret)
    {
        A = B;
        B = ret;
        ret = A%B;
    }
    //最大公约数就是B
    cout << mul/B << endl;
    return 0;
}

2. 两种排序方法

👉 题目链接

这道题思路也很简单

用vector存放多个字符串

  • 如果 某一次arr[i] > arr[i+1] 说明不符合字典排序

  • 如果 某一次arr[i].size() > arr[i+1].size() 说明不符合长度排序

最后根据两个布尔值来判断输出什么

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

int main()
{
    int n;
    cin >> n;
    vector<string> v;
    v.resize(n);
    for(size_t i = 0;i < v.size();++i)
    {
        cin >> v[i];
    }
    bool dict_sort = true;
    bool length_sort = true;
    for(size_t i = 0 ;i < v.size()-1;++i)
    {
        if(v[i].size() > v[i+1].size())
        {
            length_sort = false;
        }
        if(v[i] > v[i+1])   //调用string的运算符重载
        {
            dict_sort = false;
        }
    }
    if(dict_sort && length_sort)
    {
        cout << "both" << endl;
    }
    else if(dict_sort)
    {
        cout << "lexicographically" << endl;
    }
    else if(length_sort)
    {
        cout << "lengths" << endl; 
    }
    else
    {
        cout << "none" << endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

2021狮子歌歌

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

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

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

打赏作者

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

抵扣说明:

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

余额充值