备战秋招 | 笔试强训8

目录

一、选择题

二、编程题

三、选择题题解

四、编程题题解


一、选择题

1、关于重载函数,哪个说明是正确的()

A. 函数名相同,参数类型或个数不同

B. 函数名相同,返回值类型不同

C. 函数名相同,函数内部实现不同

D. 函数名称不同

2、关于引用以下说法错误的是()。

A. 引用必须初始化,指针不必

B. 引用初始化以后不能被改变,指针可以改变所指的对象

C. 不存在指向空值的引用,但是存在指向空值的指针

D. 一个引用可以看作是某个变量的一个“别名”

E. 引用传值,指针传地址

F. 函数参数可以声明为引用或指针类型

3、类定义的外部,一定可以被访问的成员有( )

A. 所有类成员

B. private或protected的类成员

C. public的类成员

D. public或private的类成员

4、请将下列构造函数补充完整,使得程序的运行结果是5

#include<iostream>
using namespace std;
class Sample
{
public:
    Sample(int x)
    {
        ________
    }
    ~Sample()
    {
        if(p) delete p;
    }
    int show()
    {
        return *p;
    }
private:
    int*p;
};
int main()
{
    Sample S(5);
    cout<<S.show()<<endl;
    return 0;
}

A. *p=x;

B. p=new int(x);

C. *p=new int(x);

D. p=&x;

5、下列情况中,不会调用拷贝构造函数的是()

A. 用一个对象去初始化同一个类的另一个新对象时

B. 将类的一个对象赋值给该类的另一个对象时

C. 函数的形参对象,调用函数进行形参和实参结合时

D. 函数的返回值是类的对象,函数执行返回调用时

6、以下代码共调用多少次拷贝构造函数:

Widget f(Widget u)
{
    Widget v(u);
    Widget w=v;
    return w;
}
int main()
{
    Widget x;
    Widget y=f(f(x));
    return 0;
}

A. 1

B. 3

C. 5

D. 7

7、如果友元函数重载一个运算符时,其参数表中没有任何参数则说明该运算符是()

A. 一元运算符

B. 二元运算符

C. 选项A)和选项B)都可能

D. 重载错误

8、在 main 函数中,变量 a 和 b 的构造函数和析构函数的调用顺序是()

class A;
class B;
int main() 
{
    A a;
    B b;
    return 0;
}

A. b构造 - a构造 - a析构 - b析构

B. a构造 - a析构 - b构造 - b析构

C. b构造 - a构造 - b析构 - a析构

D. a构造 - b构造 - b析构 - a析构

9、下面 C++ 程序的运行结果为()

#include <iostream>
using namespace std;
class cla 
{
    static int n;
public:
    cla() { n++; }
    ~cla() { n--; }
    static int get_n() { return n; }
};
int cla::n = 0;
int main() 
{
    cla* p = new cla;
    delete p;
    cout << "n=" << cla::get_n() << endl;
    return 0;
}

A. n=3

B. n=4

C. n=1

D. n=0

10、运行的程序总要与内存进行交互。内存作为操作系统中的重要资源,对内存的分配和释放进行管理是一项非常重要的工作,以下说法中错误的是 ______。

A. 内存泄露是内存管理中的常见问题

B. 悬挂引用指的是对某个对象的应用实际上指向一个错误的内存地址

C. 在C、C++等系统语言中,有自动的内存管理机制,不需要考虑内存管理的问题

D. 程序的动态性越强,内存管理就越重要,内存分配程序的选择也就更重要

二、编程题

1、两种排序方法  题目链接

 2、求最小公倍数  题目链接

三、选择题题解

1、关于重载函数,哪个说明是正确的()

A. 函数名相同,参数类型或个数不同

B. 函数名相同,返回值类型不同

C. 函数名相同,函数内部实现不同

D. 函数名称不同

正确答案:A

题解:

         关于C++函数重载,主要条件是函数名相同,函数的参数个数,类型不同,底层原理是函数名的修饰规则;

2、关于引用以下说法错误的是()。

A. 引用必须初始化,指针不必

B. 引用初始化以后不能被改变,指针可以改变所指的对象

C. 不存在指向空值的引用,但是存在指向空值的指针

D. 一个引用可以看作是某个变量的一个“别名”

E. 引用传值,指针传地址

F. 函数参数可以声明为引用或指针类型

正确答案:E

题解:

         关于引用,E选项主要错误,引用其实并不是传值,引用的本质就是指针,我们可以通过如下代码反汇编直接看汇编代码;

实际上,引用并不是传值,就是传地址,只不过被封装了;故E选项错误;

3、类定义的外部,一定可以被访问的成员有( )

A. 所有类成员

B. private或protected的类成员

C. public的类成员

D. public或private的类成员

正确答案:C

题解:

         在类外中,只能访问pubic成员,不能访问protected与private成员;

4、请将下列构造函数补充完整,使得程序的运行结果是5

#include<iostream>
using namespace std;
class Sample
{
public:
    Sample(int x)
    {
        ________
    }
    ~Sample()
    {
        if(p) delete p;
    }
    int show()
    {
        return *p;
    }
private:
    int*p;
};
int main()
{
    Sample S(5);
    cout<<S.show()<<endl;
    return 0;
}

A. *p=x;

B. p=new int(x);

C. *p=new int(x);

D. p=&x;

正确答案:B

题解:

         首先,我们看到调用了一个构造,而类内恰好有一个指针,我们这里就不能构造局部对象,然后让这个指针指向这个局部对象,因为局部对象出作用域会被销毁,因此我们选择在堆上申请空间并初始化为5,故选B;

5、下列情况中,不会调用拷贝构造函数的是()

A. 用一个对象去初始化同一个类的另一个新对象时

B. 将类的一个对象赋值给该类的另一个对象时

C. 函数的形参对象,调用函数进行形参和实参结合时

D. 函数的返回值是类的对象,函数执行返回调用时

正确答案:B

题解:

         A选项,用同类对象初始化会调用拷贝构造,B选项,赋值并不会调用拷贝构造,只会调用赋值重载;C选项,形参如果是对象,我们传参时会调用拷贝构造,因为形参是实参的一份临时拷贝;D选项,当函数返回一个对象时,我们会调用拷贝构造构造出一份临时拷贝;

6、以下代码共调用多少次拷贝构造函数:

Widget f(Widget u)
{
    Widget v(u);
    Widget w=v;
    return w;
}
int main()
{
    Widget x;
    Widget y=f(f(x));
    return 0;
}

A. 1

B. 3

C. 5

D. 7

正确答案:D

题解:

         调用过程如下图所示;

故一共调用了7次,如果编译器不优化则会调用9次; 

7、如果友元函数重载一个运算符时,其参数表中没有任何参数则说明该运算符是()

A. 一元运算符

B. 二元运算符

C. 选项A)和选项B)都可能

D. 重载错误

正确答案:D

题解:

         首先我们要明确,友元函数的形参中并不会有this指针,因此,若是没有任何参数则重载的运算符也没有任何参数,但是并没有没有参数的运算符,故重载错误,选D

8、在 main 函数中,变量 a 和 b 的构造函数和析构函数的调用顺序是()

class A;
class B;
int main() 
{
    A a;
    B b;
    return 0;
}

A. b构造 - a构造 - a析构 - b析构

B. a构造 - a析构 - b构造 - b析构

C. b构造 - a构造 - b析构 - a析构

D. a构造 - b构造 - b析构 - a析构

正确答案:D

题解:

         观察代码,我们发现,我们是定义的a对象,在定义b对象,因此我们先构造a在构造b,在这个栈帧空间中,b位于栈顶,当我们释放这个栈帧空间时,我们先释放栈顶元素,因此先调用b的析构函数,再调用a对象的析构函数;

9、下面 C++ 程序的运行结果为()

#include <iostream>
using namespace std;
class cla 
{
    static int n;
public:
    cla() { n++; }
    ~cla() { n--; }
    static int get_n() { return n; }
};
int cla::n = 0;
int main() 
{
    cla* p = new cla;
    delete p;
    cout << "n=" << cla::get_n() << endl;
    return 0;
}

A. n=3

B. n=4

C. n=1

D. n=0

正确答案:D

题解:        

         首先我们观察类内成语,有一个静态成员变量,并在类外初始化为1,构造函数中,我们对这个静态成员变量+1,析构对其-1,再观察主函数,我们首先new了一个对象,new其实做了两件事,1是申请空间,2是调用默认构造进行初始化,delete也是如此,做了两件事,1是调用析构函数,2是释放空间;故选D;

10、运行的程序总要与内存进行交互。内存作为操作系统中的重要资源,对内存的分配和释放进行管理是一项非常重要的工作,以下说法中错误的是 ______。

A. 内存泄露是内存管理中的常见问题

B. 悬挂引用指的是对某个对象的应用实际上指向一个错误的内存地址

C. 在C、C++等系统语言中,有自动的内存管理机制,不需要考虑内存管理的问题

D. 程序的动态性越强,内存管理就越重要,内存分配程序的选择也就更重要

正确答案:C

题解:

        在C、C++中,我们不得不注意内内存管理的问题,稍不注意可能会产生内存泄漏的问题;

四、编程题题解

1、两种排序方法

思路:我们可以写两个函数,分别判断是否是按字典序排序和是否按字符串长短排序;然后分别进行判断即可;代码如下;

#include <iostream>
#include <vector>
#include <string>
using namespace std;
// 是否按字典序排序
bool is_dict_order(vector<string>& vs)
{
    for(int i = 0; i < vs.size() - 1; i++)
    {
        if(vs[i] > vs[i + 1])
            return false;
    }
    return true;
}
// 是否按长度排序
bool is_length_order(vector<string>& vs)
{
    for(int i = 0; i < vs.size() - 1; i++)
    {
        if(vs[i].size() > vs[i + 1].size())
            return false;
    }
    return true;
}

int main() 
{
    int n = 0;
    cin >> n;
    vector<string> vs(n, string(""));
    for(int i = 0; i < n; i++)
    {
        cin >> vs[i];
    }

    if(is_dict_order(vs) && is_length_order(vs))
    {
        cout << "both" << endl;
    }
    else if(is_dict_order(vs))
    {
        cout << "lexicographically" << endl;
    }
    else if(is_length_order(vs))
    {
        cout << "lengths" << endl;
    }
    else 
    {
        cout << "none" << endl;
    }
    return 0;
}

2、求最小公倍数

思路一:暴力法,找到两个数中较大的那一个,然后往后遍历,依次判断是否是这两个数的最小公倍数;

思路二:我们先用辗转相除法求出最大公约数,然后通过公式求出最小公倍数

(a + b)/ 最小公倍数 = 最大公约数,本题采用思路二;

 

#include <iostream>
using namespace std;

int main() 
{
    int num1, num2;
    cin >> num1 >> num2;
    int a = num1, b = num2;
    // 辗转相除法
    int c = a % b;
    while(c)
    {
        a = b;
        b = c;
        c = a % b;
    }
    // 此时b是最大公约数(运用公式求最小公倍数)
    cout << ((num1 * num2) / b) << endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值