C++笔试题(知识点)

答案在最后

1.下列关于纯虚函数的描述中,正确的是

A.纯虚函数是一种特殊的虚函数,是空函数
B.具有纯虚函数的类称为虚基类
C.一个基类中说明有纯虚函数,其派生类一定要实现该纯虚函数
D.具有纯虚函数的类不能创建类对象,因为它是虚基类

2.关于引用与指针的区别,下列叙述错误的是

A.引用必须被初始化,指针不必
B.删除空指针是无害的,不能删除引用
C.不存在指向空值的引用,但是存在指向空值的指针
D.指针初始化以后不能被改变,引用可以改变所指的对象

3.在创建类派生对象时,构造函数的执行顺序是

A.对象成员构造函数,派生类本身的构造函数,基类构造函数
B.派生类本身的构造函数,基类构造函数,对象成员构造函数
C.派生类本身的构造函数,对象成员构造函数,基类构造函数
D.基类构造函数,对象成员构造函数,派生类本身的构造函数

4.将父类的析构函数定义为虚函数,下列正确的是

A.释放子类指针时能正确释放父类对象
B.这样做是错误的
C.释放父类指针时能正确释放子类对象
D.以上全错

5.假定指针变量p定义为“int *p = new int(100);”,要释放p所指向的动态内存,应使用语句

A. delete *p;
B. delete p;
C. delete &p;
D. delete []p;

6.程序阅读

#include <iostream>
using namespace std;

class A 
{
    
    
public:
    A(){
    
    cout << "A";}
};
class B
{
    
    
public:
    B(){
    
    cout << "B";}
};
class C : public A
{
    
    
B b;
public:
    C(){
    
    cout << "C";}
};
int main() {
    
    
    C obj;
    return 0;
}

7.程序阅读

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

int main() {
    
    
  vector<int> myvector;
  for (int i = 1; i <= 10; i++) {
    
    
    myvector.push_back(i);
  }
  myvector.erase(myvector.begin()+6);
  myvector.erase(myvector.begin(), myvector.begin() + 4);
  for (unsigned i = 0; i < myvector.size(); i++) {
    
    
    cout << myvector[i] << ' ';
  }
}

8.程序阅读

#include <iostream>
using namespace std;

int main() {
    
    
  int x = -1;
  try {
    
    
    cout << "Inside try" << endl;
    if (x < 0) {
    
    
      throw x;
      cout << "After throw" << endl;
    }
  } catch (int x) {
    
    
    cout << "Exception Caught" << endl;
  }
  cout << "After catch" << endl;
  return 0;
}

9.对于c++语言,下面描述正确的是

A. 线性表的逻辑顺序和物理顺序总是一致的。
B. 线性表的顺序存储表示优于链式存储表示。
C. 线性表若采用链式存储表示时所有节点之间的存储单元地址可连续可不连续
D. 二维数组是其数组元素为线性表的线性表。

10.设哈希表长m=13,哈希函数H(key)=key MOD 11。表中已有4个节点:addr(16)=5,addr(28)=6,addr(84)=7,addr(19)=8其余地址为空,如用线性探测再散列处理冲突,则其关键字为38的地址为

11.下列关于死锁的叙述中,哪些是正确的(多选题)

A. 死锁产生的原因是进程推进顺序不当
B. 环路是死锁产生的必要条件
C. 采用银行家算法能有效地实现死锁避免
D. 系统出现死锁是因为进程调度不当

12.下面关于const正确的是(多选题)

A. 欲阻止一个变量被改变,可以使用cosnt关键字
B. 在定义该const变量时,不用将其初始化
C. 在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值
D. 对于类的成员函数,有时候必须指定其返回值为const类型,以使其返回值不为”左值“

13.请找出下面程序的错误之处:

#define UT_ADMINISTRATOR 1
#define UT_NORMAL 2
void GetAccountList(std::vector<CString> UserList)
{
    
    
          UserList = GUserList;
}
void CTestPrj1Dlg::OnBnClickedButton2(UINT32 nUserID)
{
    
    
          std::vector<CString> UserList;
          int iCurUserType = GetUserType(nUserID);
          if (iCurUserType == UT_ADMINISTRATOR)
          {
    
    
                    GetAccountList(UserList);
                    for (size_t i=0; i<UserList.size(); i++)
                    {
    
    
                             lbUsers.AddString(UserList[i]);
                    }
          }else
                    MessageBox(_T("Access denied."));
}

14.请找出下面程序的错误之处

std::vector<CString> GUserList;
          // 数据初始化
          GUserList.push_back(_T("aaa"));
          GUserList.push_back(_T("bbb"));
          GUserList.push_back(_T("ccc"));
          GUserList.push_back(_T("ddd"));
          GUserList.push_back(_T("eee"));// 需求:遍历容器,找到匹配项并删除它
          for (std::vector<CString>::iterator it =   
                    GUserList.begin(); it != GUserList.end(); it++)
          {
    
    
                    CString str = *it;
                    if (str.CompareNoCase(_T("bbb")) == 0)
                             GUserList.erase(it);
          }

15.请写出代码执行后p的值

  char szLog[] = "2014‐11‐11 12:35:47,2048,Hello World!,120395;";
  char *p = strstr(szLog, ",");
  if (p)
  {
            p++;
            char *p1 = strstr(p, ",");
            if (p1)
            {
                     *p1 = 0;
            }
  }

16.程序阅读

#include <iostream>
using namespace std;
class Base   
{
    
    
public:
    int iValue;
    virtual void fun1()
    {
    
    
       cout<<"Base fun1"<<endl;
       fun2();
    }
    void fun2 ()
    {
    
    
       cout<<"Base fun2"<<endl;
    }
};
class Derived : public Base
{
    
    
public:
    char* pValue;
    virtual void fun1()
    {
    
    
       cout<<"Derived fun1"<<endl;
       fun2();
       Base::fun1();
    }
    void fun2 ()
    {
    
    
       cout<<"Derived fun2"<<endl;
    }
};
class MoreDerived : public Derived
{
    
    
public:
    static double dValue;
};
int main(int argc, char* argv[])
{
    
    
    cout<<sizeof(Base)<<endl
       <<sizeof(Derived)<<endl
       <<sizeof(MoreDerived)<<endl;
    Derived d;
    Base& rB = d;
    rB.fun1();
    Base* pB = &d;
    pB‐>fun1();
    pB = &((Base)d);
    pB‐>fun1();
    return 0;
}
  

答案

1.正确选项:C
A:纯虚函数只是没具体实现的函数,不是空函数
B:称为抽象类,虚基类是另外一种东西
D:前面对,后面错,他是抽象类
2.正确选项:D:指针可以在任意地方初始化,引用一旦被初始化,就不能改变指向对象
3.正确选项:D
4.正确选项:C
5.正确选项:B
这个语句表示定义了一个指针变量p,并让它指向了堆上新创建并初始化为100的int类型的变量,这道题中delete p会发生未定义行为,因为p是一个整数值100,而不是一个指针。delete运算符只能用于释放由new运算符分配的内存块,而不能用于释放任意的值。
p是一个指针,它指向了堆上的一个int类型的变量,这个变量的值是100。但是
p不是一个指针,而是一个int类型的值
6.ABC。首先调用基类A的构造函数,输出"A"。然后调用成员变量b的构造函数,输出"B"。最后调用派生类C自己的构造函数,输出"C"。
因此,最终的输出结果是"ABC"。
7.5 6 8 9 10 第一个erase的意思是删除第七个元素
然后正常
8.Inside try Exception Caught After throw After catch
9.C
10.9
11.ABC。系统出现死锁是因为进程推进顺序不当
12.B,const变量必须初始化
13.GetAccountList函数没有使用引用类型,导致UserLIst为临时对象
14.迭代器失效(解决方法,用一个迭代器接受删除元素的下一个元素)
15.p=2048,strstr函数会找到第一个需要字符的位置,这里由于p1置为0,截断了字符串,所以p现在只指向2048.
16.

  • Base类一个int型和一个虚函数表指针8B

  • 派生类一个char类型的指针和一个虚函数表指针,还有一个继承来的int,一共12B

  • MoreDerived类由于使用了静态变量,不占用类空间,所以仍是12B

  • Base& rB = d;

  • rB.fun1();这段代码产生了动态绑定(Base类的指针)

  • 所以输出://df1 df2 bf1 bf2

  • 而pB->fun1();由于没有改变指针类型,所以和上一道题答案一样

  • pB = &((Base)d)

  • pB->fun1();进行了类型转换,所以这时候调用基类,输出bf1,bf2

猜你喜欢

转载自blog.csdn.net/m0_50816320/article/details/129326233