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;
}
  

17.假设A为抽象类,下列声明( )是正确的

A.A fun(int);
B.A*p;
C.int fun(A);
D.A obj;

18.test.c文件中包括如下语句:

#define INT_PTR int*
typedef int*int_ptr;
INT_PTR a,b;
int_ptr c,d;
文件中定义的四个变量,哪个变量不是指针类型?

19.下面代码会输出什么

int main(int argc, char **argv)
{
    int a[4] = {1, 2, 3, 4};
    int *ptr = (int *)(&a + 1);
    printf("%d", *(ptr - 1));
}

20.程序阅读

class A
{
public:
    void foo()
    {
        printf("1");
    }
    virtual void fun()
    {
        printf("2");
    }
};
class B: public A
{
public:
    void foo()
    {
        printf("3");
    }
    void fun()
    {
        printf("4");
    }
};
int main(void)
{
    A a;
    B b;
    A *p = &a;
    p->foo();
    p->fun();
    p = &b;
    p->foo();
    p->fun();
    A *ptr = (A *)&b;
    ptr->foo();
        ptr->fun();
    return 0;
}

21.下面数据结构能够支持随机的插入和删除操作、并具有较好的性能的是____。

A数组和链表
B链表和哈希表
C哈希表和队列
D队列和堆栈
E堆栈和双向队列
F双向队列和数组

22.在 TCP/IP 参考模型中 TCP 协议工作在()

A应用层
B传输层
C互连层
D主机-网络层

23.下列代码的运行结果是()

下列代码的运行结果是()

int a[]={1,2,3,4};
int *b=a;
*b+=2;
*(b+2)=2;
b++;
printf(%d,%d\n”,*b,*(b+2));

24.假设用于通信的电文由 5 个字母组成,字母在电文中出现的频率分别为 2,4,5,7,8 根为第一层,用这 5 个字母设计哈弗曼树带权路径长度为()

25.32位环境下,给定结构体

Struct A

{

Char t:4;

Char k:4;

Unsigned short i:8;

Unsigned long m;

};

问 sizeof ( A ) =_____;

26.int x[6][4], (*p)[4];

p = x;
则*(p+2)指向哪里?

27.下面有关C++中为什么用模板类的原因,描述错误的是?

A.可用来创建动态增长和减小的数据结构
B.它是类型无关的,因此具有很高的可复用性
C.它运行时检查数据类型,保证了类型安全
D.它是平台无关的,可移植性

28.程序阅读

int func(int a){
    int b;
    switch (a){
        case 1: b = 30;
        case 2: b = 20;
        case 3: b = 16;
        default: b = 0;
    }
    return b;
}

29.下面对静态数据成员的描述中,正确的是?

A.静态数据成员可以在类体内进行初始化
B.静态数据成员不可以被类的对象调用
C.静态数据成员不受private控制符的作用
D.静态数据成员可以直接用类名调用

30.#include<file.h> 与 #include "file.h"的区别?

31.下面的代码输出什么

#include <iostream>
using namespace std;
class A  
{  
public:  
    A()  {  cout << "Create A!" << endl;  }
    A(const A& para)
    {
		cout << "Copy constructor A!" << endl;
    }  
    ~A() {    cout<<"~A"<<endl;   }  
};  
   
class B:public A  
{  
    public:  
        B(A &a):_a(a)  
        {  
             cout << "Create B!" << endl;
        }  
        ~B()  
        {  
            cout<<"~B"<<endl;  
        }  
    private:  
        A _a;  
};      
int main(void)  
{  
        A a;        
        B b(a); 
} 

32.switch©语句中,c不可以是什么类型()

A.int
B.long
C.char
D.float

33.头文件中的 ifndef/define/endif 干什么用?

A.定义常量
B.标记为特殊的头文件
C.防止头文件被重复引用
D.注释头文件

34.如果打开文件时,选用的文件操作方式为“wb+”,则下列说法中正确的是(多选)

A.要打开的文件是二进制文件
B.要打开的文件必须存在
C.要打开的文件可以不存在
D.打开文件后可以读取数据

35.下面关于线程和进程正确的说法有(多选)

A.进程间相互独立,同一进程的各线程间共享。某进程内的线程在其他进程不可见。
B.线程间可以直接读写进程数据段(如全局变量)来通信。
C.线程上下文切换要比进程快得多。
D.一旦一个线程被创建,它就立刻开始运行。

36.已知一段文本有1382个字符,使用了1382个字节进行存储,这段文本全部是由a、b、c、d、e这5个字符组成,a出现了354次,b出现了483次,c出现了227次,d出现了96次,e出现了232次,对这5个字符使用哈夫曼(Huffman)算法进行编码,则以下哪些说法正确(多选)

A.使用哈夫曼算法编码后,用编码值来存储这段文本将花费最少的存储空间
B.使用哈夫曼算法进行编码,a、b、c、d、e这五个字符对应的编码值是唯一确定的。
C.使用哈夫曼算法进行编码,a、b、c、d、e这5个字符对应的编码值可以有多套,但每个字符编码的位(bit)数是确定的
D.b这个字符的哈夫曼编码值位数应该最短,d这个字符的哈夫曼编码值位数应该最长

37.若有说明int a[2][3]; 则对a数组元素的正确引用是( )

A.a[0][1+1]
B.a[1][3]
C.a[1,3]
D.a(1)(1)

38.程序阅读

union MyUnion
{
 int a;
 short b;
};
int main()
{
 MyUnion value;
 value.a = 3;
 printf("%d", value.b & 1);
} 在大端模式下输出结果是什么?

39.程序阅读

#include <iostream>
using namespace std;

class A
{
public:
	A() {
		num++;
	}
	 void print() { std::cout << num; }
private:
	int num = { 0 };
};
class B : public A
{
public:
	virtual void print() { std::cout << num; }
private:
	int num = { 0 };
};
int main()
{
	A* a = new B();
	a->print();
}

40.程序阅读

class A 
{
public:
 virtual void a() = 0;
 A() {
  std::cout << "A ";
 }
};
class B : public A
{
public:
 B() {
  std::cout << "B ";
 }
};
int main() 
{
 A* a = new B();
 return 0;
} 

41.假定T是一个C++类,下列语句执行之后,内存里创建了()个T对象。

T b(5);
T c[6];
T &d = b;
T e=b;
T *p = new T (4);

42.枚举

enum string
{    
    x1,    
    x2,    
    x3 = 10,    
    x4,    
    x5,    
} x;函数外部访问x等于什么?

43.关于以下代码,哪个说法是正确的?

myClass::foo(){
    delete this;
}
..
void func(){
    myClass *a = new myClass();
    a->foo();
}

A.它会引起栈溢出
B.都不正确
C.它不能编译
D.它会引起段错误

44.下面协议中用于WWW传输控制的是? ( )

A.URL
B.SMTP
C.HTTP
D.HTML

45.缺省的Linux系统中,从后台启动进程,应在命令的结尾加上哪个符号? ( )

A @
B &
C ^
D $

46.请选择表达式 ‘0’ + 1 的结果(本题数值均为十进制)()

A 2
B 31
C 32
D 49

47.以下表达式选择结果是()

int a = 0;
int b = (a=-1) ? 2:3;
int c = (a=0) ? 2:3;

A.b=2, c=2
B.b=3, c=3
C.b=2, c=3
D.b=3, c=2

48多个进程怎样共享一个监听端口?( )

A.每个进程都使用SO_REUSEADDR选项,然后绑定同一个端口
B.每个进程分别绑定一次即可
C.使用fork共享
D.只有最后一个绑定端口的进程才能收到数据

49.对于int *pa[5];的描述,正确的是()

A.pa是一个具有5个元素的指针数组,每个元素是一个int类型的指针;
B.pa[5]表示某个数组的第5个元素的值;
C.pa是一个指向数组的指针,所指向的数组是5个int类型的元素;
D.pa是一个指向某个数组中第5个元素的指针,该元素是int类型的变量;

答案

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 这里的右区间是闭区间
然后正常
8.Inside try Exception Caught After throw After catch
9.C
10.9
11.ABC。系统出现死锁是因为进程推进顺序不当
12.ACD,const变量必须初始化
13.GetAccountList函数没有使用引用类型,导致UserLIst为临时对象
14.迭代器失效(解决方法,用一个迭代器接受删除元素的下一个元素)
15.p=2048,strstr函数会找到第一个需要字符的位置,这里由于p1置为0,截断了字符串,所以p现在只指向2048.
16.

Base类一个int型和一个虚函数表指针8B,共16B
派生类一个char类型的指针和一个虚函数表指针,还有一个继承来的int,一共24B
MoreDerived类由于使用了静态变量,不占用类空间,所以仍是24B Base& rB = d;
rB.fun1();这段代码产生了动态绑定(Base类的指针) 所以输出://df1 df2 bf1 bf2
而pB->fun1();由于没有改变指针类型,所以和上一道题答案一样
pB = &((Base)d) pB->fun1();进行了类型转换,所以这时候调用基类,输出bf1,bf2

17.B
A 抽象类不能被实例化,也不能创建对象,因此不能有构造函数
B 指向抽象类的指针是允许的,可以用指针来访问派生类的对象
C 在抽象类中通常定义纯虚函数,纯虚函数没有具体实现,因此无法直接传入抽象类的对象作为参数
D 抽象类不能被实例化,因此无法创建对象

18.B
宏是简单替换,a是b不是
19.4
i

nt a[4] = {1, 2, 3, 4}; 定义了一个包含四个整型元素的数组 a,内容为 {1, 2, 3, 4}。 int *ptr
= (int )(&a + 1); 这一行中 &a 取得数组 a 的地址,然后将其转换为 int 类型,并加上 1。这样 ptr 指向了数组 a 之后的位置。 printf(“%d”, *(ptr - 1)); 在这里,(ptr - 1) 将指针回退一个 int
的长度,指向了数组 a 的最后一个元素的位置,也就是 4 所在的位置。最后通过 *(ptr - 1) 取出该位置的值,即输出 4。

20.121414
这里注意类A不是虚函数,因此会根据指针类型确定调用的方法,所以后面也一样,如果改成B* ptr = (B*)&b;那么最后就会输出34
21.B
22.B
23.(2,4)
这里注意*(b+2)操作并没有使指针移动
24.58
23+43+(5+7+8)*2 = 58
25.8
两个char占共两个字节,short占两个,32位系统以4字节为内存对齐,32位系统long为4字节,加起来共八字节,不用内存对齐
26.x[2][0]
(*p)[4] 定义了一个指针 p,指向长度为 4 的一维数组。星(p+2)相当于在一维数组的基础上移动两位
27 C

A.STL就是模板类实现的,可以根据需要动态调整其大小 C C++
中,模板类在编译时进行类型检查,而不是在运行时。模板类的实例化是在编译时完成的,因此在编译过程中会检查数据类型是否符合模板类的要求,从而保证类型安全。因此,模板类并不会在运行时检查数据类型,它通过静态类型检查来确保类型安全。

28.0
case 语句后面没有跟 break,所以会顺序执行 b = 30; b = 20; b = 16; b = 0。所以最后结果为 0。
29.D
static数据成员必须在类体之外进行定义。通常在定义时才进行初始化。但是,当类型为const static时的整形时可以在类体内进行初始化。因此A有正确的地方,但是也有错误的情况,因此不选A。 选D
30.前者首先从Standard Library的路径寻找和引用file.h,而后者首先从当前工作路径搜寻并引用file.h
31.Create A! Create A! Copy constructor A! Create B! ~B ~A ~A ~A
这里构造函数和析构函数是配对的,有四个构造函数所以也会有四个析构函数,拷贝构造函数当然也算构造函数
32.D
33.C
34.ACD
“w” 模式表示写入模式,如果文件不存在,则会创建一个新文件,如果文件存在则会清空内容
wb指以二进制写入模式打开文件。
wb+指以二进制读写模式打开文件
35.AC
B在多线程编程中,线程之间并不直接共享进程数据段(如全局变量),因为线程是共享同一进程的资源的。如果多个线程同时访问和修改全局变量,可能会导致数据竞争和不确定的行为,从而引发程序错误。
36.ACD
编码值会根据字符频率的不同而设置
37 A
B越界了
38 1
大端模式下低地址在高位,这里由于是联合,int和short占用同一项地址空间, 所以value.b=3(注意如果这里反过来是b=3,访问a会得到乱码),3的二进制0011和1进行按位与(两个都为1则为1,有一个0就是0),答案还是1
39. 0

这里如果print不定为虚函数,则会输出1,因为父类的Num是1,但是这里是虚函数,根据动态绑定调用了子类的print,所以输出子类的num
40. C
只要有纯虚函数,就是抽象类,抽象类无法实例化对象
41. 9

T b(5);:这行代码创建了一个名为b的T对象,并且调用了T类的构造函数,因此在内存中创建了1个T对象。

T c[6];:这行代码创建了一个由6个T对象组成的数组c,因此在内存中创建了6个T对象。

T &d = b;:这行代码并没有创建新的T对象,而是创建了一个对现有T对象b的引用d。

T e=b;:这行代码创建了一个名为e的T对象,并且调用了T类的拷贝构造函数,因此在内存中创建了1个T对象。

T *p = new T (4);:这行代码使用new运算符在堆上创建了一个T对象,并调用了T类的构造函数,因此在内存中创建了1个T对象。

综上所述,在执行完以上代码之后,在内存里总共创建了9个T对象。

  1. 0
    在这段代码中,定义了一个枚举类型 string,其中 x1 的值默认为 0,x2 的值默认为 1,x3 的值被显式设置为 10,而后续的枚举值会依次递增,因此 x4 的值为 11,x5 的值为 12。
    当在函数外部访问枚举变量 x 时,默认情况下它的值会是枚举类型中第一个枚举值的值,即 x1 的值,也就是 0。

  2. B
    这段代码没问题

  3. C
    HTTP(超文本传输协议)是用于WWW(万维网)传输控制的协议。它定义了浏览器和 Web 服务器之间的通信规则,使得用户可以在浏览器中请求和接收 Web 页面。SMTP(简单邮件传输协议)用于电子邮件传输,而 URL(统一资源定位符)用于标识 Web 资源的位置。HTML(超文本标记语言)是用于创建 Web 页面的标记语言。

45 B
"缺省"一词在这里指的是默认的、预设的意思。在这个问题中,指的是在默认情况下(即常规设置下)启动进程时所需的操作或设置。在 Linux 系统中,如果要将一个进程放到后台运行,通常在命令的结尾加上 “&” 符号。这样可以让该进程在后台运行,而不会阻塞当前终端的使用。

46 D
0的ASCII的值是48
47. C
48. C
49. A
int pa[5],首先[]优先级比高,所以pa与[]先结合,pa[5]表明pa是一个数组,大小是5,既然知道pa是数组了,接下来就是确认数组元素了,int*表明数组元素是指针;

int(p)[5],首先()优先级比[]高,所以pa先与结合,*pa表明pa是一个指针,既然知道pa是指针,接下来确认指针指向的数据类型,int [5]表明指针指向大小为5的int型数组。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值