Lazy loaded image
难题解惑(2026.01.10)
字数 11412阅读时长 29 分钟
2026-1-10
2026-1-9
password
comment
type
status
date
slug
summary
tags
category
icon

📝 原题再现

选自信息学院 ITC 平台 “c/c++程序设计实验课-补充练习

选择题

1. 下列描述错误的是:

A. 在创建对象前,静态成员不存在
B. 静态成员是类的成员
C. 静态成员不能是虚函数
D. 静态成员函数不能直接访问非静态成员
答案:A
解析:
静态成员属于类本身,而不是某个对象。
  • 在程序运行时,类一旦被编译并链接,静态成员就已经存在
  • 不需要创建对象即可访问(如 ClassName::staticMember
    • 因此“在创建对象前,静态成员不存在”是错误的。
      其余选项均是静态成员的正确特性。

2. 定义析构函数时应该注意

A. 其名与类名完全相同
B. 返回类型是void类型
C. 无形参,也不可重载
D. 函数体必须有delete语句
答案:C
解析:
析构函数的特点:
  • 名字是 ~类名(不是“完全相同”,而是带 ~
  • 没有返回类型(连 void 都不写)
  • 不能有参数,因此不能重载
  • 不一定要写 delete(是否释放资源取决于类中是否动态分配内存)
所以只有 C 是正确描述。

3. 类成员的访问权限中,只能被本类的成员函数和其友元函数访问的是

A. shared
B. public
C. private
D. protected
答案:C
解析:
  • private 成员:只能被本类成员函数和友元访问
  • protected:派生类也能访问
  • public:任何地方都能访问
因此符合题意的是 private

4. 考虑函数原型 void test(int a, int b = 7, char ch = '*'),下面函数调用中,不合法的是

A. test(5);
B. test(5,8);
C. test(6,'#');
D. test(0,0,'*');
答案:C
解析:
默认参数必须从右向左依次省略
  • A:bch 使用默认值,语义正确
  • B:ch 使用默认值,语义正确
  • D:全部参数给出,语义正确
  • C:'#' 会被当作第二个参数 b,但 bint,语义错误

5. 若一个类拥有多个构造函数,则这些构造函数之间为

A. 重复关系
B. 重载关系
C. 继承关系
D. 拷贝关系
答案:B
解析:
多个构造函数:
  • 函数名相同
  • 参数列表不同
这是典型的函数重载

6. 有如下定义:

以下引用方式不正确的是
A. work->no
B. work.no
C. (*p).no
D. p->no
答案:A
解析:
  • work 是结构体对象,只能用 .
  • -> 只能用于指针
因此 work->no 是错误的。

7. 下列说明中 const char *ptr="hello";,其中 ptr 应该是

A. 指向字符常量的指针
B. 指向字符的常量指针
C. 指向字符串常量的指针
D. 指向字符串的常量指针
答案:C
解析:
const char *ptr 的含义是:
  • 指针本身可变
  • 指向的内容不可变
"hello" 是字符串常量,所以是指向字符串常量的指针

8. 作用域运算符“::”的功能是

A. 标识作用域的级别
B. 指出作用域的范围
C. 给定作用域的大小
D. 标识成员是属于哪个类的
答案:B
解析:
:: 用来限定名字属于哪个作用域,如:
本质作用是指出作用域范围

9. 关于 this 指针使用说法正确的是

A. 保证每个对象拥有自己的数据成员,但共享处理这些数据的代码
B. 保证基类私有成员在子类中可以被访问
C. 保证基类保护成员在子类中可以被访问
D. 保证基类公有成员在子类中可以被访问
答案:A
解析:
this 指针:
  • 指向当前对象本身
  • 使得同一份成员函数代码可以操作不同对象的数据
与继承访问权限无关。

10. 关于 const 关键字说法错误的是

A. const关键字可以修饰对象和成员函数
B. const对象不能被修改
C. const成员函数不能修改类数据成员
D. const可以用于说明类
答案:D
解析:
  • const 可修饰变量、对象、函数、成员函数
  • 不能直接修饰类本身
所以 D 错。

11. C++ 中不能被重载的一组运算符是

A. :: ?: . sizeof
B. ?: . sizeof ++ ->
C. :: ?: new delete
D. ++ -- ?: sizeof
答案:A
解析:
不能重载的运算符包括:
  • ::(作用域运算符)
  • ?:(条件运算符)
  • .(成员访问)
  • sizeof
A 正好全是不可重载的。

12. 如果类 A 被说明为类 B 的友元,则

A. 类A的成员既是类B的成员
B. 类B的成员既是类A的成员
C. 类A的成员函数可以访问类B的所有成员
D. 类B的成员函数可以访问类A的所有成员
答案:C
解析:
友元关系:“谁是友元,谁就可以访问对方的私有成员”
AB 的友元 ⇒ A 可以访问 B 的所有成员。

13. 已知 print 是类的常成员函数,正确声明是

A. void print() const;
B. const void print();
C. void const print();
D. void print(const);
答案:A
解析:
  • const 成员函数必须写在函数声明末尾
  • 表示该函数不能修改对象的数据成员

14. 在下面的类定义中,错误的语句是

A.①
B.②
C.③
D.④
答案:C
解析:
aint,初始化为 2.5 会发生类型不匹配(考试中视为错误)。

15. 下面关于友元的描述中,错误的是

A. 友元函数可以访问私有成员
B. 友元类中所有成员函数都是友元函数
C. 友元提高效率但破坏封装
D. 友元关系不能继承,是双向的
答案:D
解析:
  • 友元关系不能继承,表述正确
  • 不是双向的(单向),表述错误

16. 以下关于运算符重载的叙述中,正确的是

A. 有的运算符只能作为友元函数重载
B. 可以定义新的运算符
C. 运算符函数名是 +
D. 二元运算符必须有两个参数
答案:A
解析:
  • <<>> 通常必须用友元重载
  • 运算符函数名应为 operator+
  • 成员函数形式的二元运算符只需一个参数

17. 实现运行时多态性采用

A. 重载函数
B. 构造函数
C. 析构函数
D. 虚函数
答案:D
解析:
运行时多态 = 虚函数 + 基类指针/引用

18. 派生类对象对基类成员中可以访问的是

A. 公有继承的公有成员
B. 公有继承的保护成员
C. 保护继承的保护成员
D. 保护继承的公有成员
答案:A
解析:
通过派生类对象在类外访问,只能访问公有继承的公有成员

19. C++ 中声明常量的关键字是

A. extern
B. public
C. virtual
D. const
答案:D
解析:
const 用于定义常量。

20. 可以作为类 AA 构造函数的是

A. void AA(int);
B. int AA();
C. AA(int) const;
D. AA(int);
答案:D
解析:
构造函数:
  • 无返回类型
  • 名字与类名相同

21. 采用函数重载的目的在于

A. 实现共享
B. 减少空间
C. 提高速度
D. 使用方便,提高可读性
答案:D
解析:
函数重载的核心思想是:用同一个函数名完成“语义相同、参数不同”的操作
这样做的好处是:
  • 减少程序员记忆多个函数名的负担
  • 让代码语义更直观(如 print(int)print(double)
  • 提高程序的可读性和可维护性
函数重载不会直接减少内存占用,也不会提高运行速度,因此选 D。

22. 下列静态数据成员特性中,错误的是

A. 说明静态数据成员时前边要加 static
B. 静态数据成员要在类体外进行初始化
C. 引用静态数据成员时,要加类名和作用域符
D. 静态数据成员不是所有对象共有的
答案:D
解析:
静态数据成员的本质是:属于类,而不属于某个具体对象
因此:
  • 所有对象共享同一份静态数据成员
  • 修改一次,所有对象都受影响
选项 D 说“不是所有对象共有的”,与事实完全相反。

23. 在 C++ 类中定义的成员,其默认访问权限为

A. private
B. public
C. protected
D. static
答案:A
解析:
  • class 的默认访问权限是 private
  • struct 的默认访问权限是 public
这是 C++ 非常经典、非常容易考的对比点。

24. 下列关于类和对象的叙述中,错误的是

A. 对象是类的具体实例
B. 类是对某一类对象的抽象
C. 类和对象的关系是一种数据类型与变量的关系
D. 一个类只能有一个对象
答案:D
解析:
  • 类可以创建任意多个对象
  • 不存在“一类只能有一个对象”的限制
A、B、C 都是对类与对象关系的正确描述。

25. 以下各类函数中,不是类的成员函数的是

A. 构造函数
B. 析构函数
C. 拷贝构造函数
D. 友元函数
答案:D
解析:
友元函数的特点是:
  • 不属于类
  • 但可以访问类的私有和保护成员
构造、析构、拷贝构造函数都是真正的类成员函数

26. 以下不正确的语句是

A. if (x > y);
B. if (x = y) && ( x!= 0) x += y;
C. if (x !=y) scanf("%d", &x); else scanf("%d", &y);
D. if (x < y) {x++; y++;}
答案:B
解析:
if 语句的语法是:
B 中实际写成了:
这是语法错误,因为 if 后的条件必须整体放在一对括号中。

27. 下列各类函数中,不是类的成员函数的是

A. 构造函数
B. 析构函数
C. 友元函数
D. 拷贝构造函数
答案:C
解析:
与第 25 题考点相同:友元函数不是成员函数

28. 字符串 "\ta\017bc" 的长度(不包括结束符)是

A. 9
B. 5
C. 6
D. 7
答案:B
解析:
逐个分析转义字符:
  • \t → 一个字符
  • a → 一个字符
  • \017 → 八进制转义,表示一个字符
  • b → 一个字符
  • c → 一个字符
总共 5 个字符,不包括 \0

29. 下列说法中正确的是

A. 类定义中只能说明函数头,不能定义函数体
B. 类中的函数成员可以在类体中定义,也可以在类体之外定义
C. 类外定义必须与类声明在同一文件
D. 类外定义不能访问私有数据成员
答案:B
解析:
  • 成员函数可以:
    • 在类体内定义(自动内联)
    • 在类体外定义(通过 类名::
  • 类外定义的成员函数仍然是类的成员,可以访问私有成员

30. 有如下类定义:

下列关于 setValue 成员函数的实现中,正确的是
A.sample::setValue(int n0){ n = n0; }
B.void sample::setValue(int n0){ n = n0; }
C.void setValue(int n0){ n = n0; }
D.setValue(int n0){ n = n0; }
答案:B
解析:
先明确一个核心规则
在类外实现成员函数时,必须同时写:
1.返回类型
2.类名 + 作用域运算符 ::
3.函数名 + 参数表
即标准形式是:
下面对四个选项进行逐个分析:
A.错误原因
  • 缺少返回类型
  • C++ 中任何函数定义都必须有返回类型
  • 即便是 void,也不能省略
编译错误:语法不完整
B.完全正确,原因如下:
  • void —— 返回类型正确
  • sample:: —— 指明这是 sample 类的成员函数
  • setValue(int n0) —— 与类中声明完全一致
  • 可以直接访问私有成员 n(因为这是成员函数)
这是标准、规范、唯一正确的类外实现方式
C.错误原因(两层):
  1. 没有 sample::
      • 这是一个普通全局函数
      • 不属于 sample
  1. 无法访问成员变量 n
      • nsample 的私有成员
      • 全局函数无权访问
即使语法能通过,也会在访问 n 时报错
D.错误原因
  • 没有返回类型
  • 没有作用域限定符
  • C++ 不允许省略返回类型(这不是 C 语言旧规则)
语法错误,无法编译

31. 类的实例化是指

A. 定义类
B. 创建类的对象
C. 指明具体类
D. 调用类的成员
答案:B
解析:
  • 类(class:只是一个“抽象模板”,描述对象的属性和行为
  • 实例化:就是根据这个模板创建具体对象
逐项分析:
  • A.定义类只是设计蓝图,还没有对象
  • B.创建类的对象,正是实例化的含义
  • C.说法模糊,不是规范术语
  • D.调用成员是“使用对象”,不是实例化本身

32. 关于对象概念的描述中,说法错误的是

A. 对象就是 C 语言中的结构变量
B. 对象代表着正在创建的系统中的一个实体
C. 对象是类的一个变量
D. 对象之间的信息传递是通过消息进行的
答案:A
解析:
这是一个概念辨析题
  • A.
    • 对象 ≠ C 语言结构变量
    • 对象 = 数据 + 操作(成员函数),而结构体只有数据
  • B.面向对象中,对象就是系统中的一个实体
  • C.对象是类实例化后得到的“变量”
  • D.面向对象理论中,对象通过“消息(方法调用)”通信
易错点:对象比结构体“多了行为”

33. 假定 A 为一个类,a() 为该类公有函数成员,x 为该类的一个对象,则访问 x 对象中函数成员 a() 的格式为

A. x.a
B. x.a()
C. x->a
D. (*x).a()
答案:B
解析:
  • x对象(不是指针)
  • 访问对象成员函数:用点号 .并且必须加括号
逐项:
  • A.缺少 (),这是函数,不是变量
  • B.正确
  • C.-> 只能用于指针
  • D.x 不是指针,不能解引用

34. 下列不能作为类的成员的是

A. 自身类对象的指针
B. 自身类对象
C. 自身类对象的引用
D. 另一个类的对象
答案:B
解析:
  • 类中不能直接包含自身类型的对象,否则会导致无限递归定义,内存无法确定
逐项分析:
  • A.指针大小固定,可以
  • B.自身类对象 → 无限嵌套(非法)
  • C.引用本质是地址,也可以
  • D.可以包含其他类对象
注意:
类中可以有“自己”的指针或引用,但不能有“自己本身”

35. 假设要对类 A 定义加号操作符重载成员函数,实现两个 A 类对象的加法,并返回相加结果,则该成员函数的声明语句是

A. A operator +(A &a, A &b);
B. operator +(A a);
C. A operator +(A &a);
D. A &operator +();
答案:C
解析:
这是成员函数形式的运算符重载
等价于:
所以:
  • 左操作数是 this
  • 只需要一个参数
逐项:
  • A.两个参数,属于非成员函数写法
  • B.没有返回类型
  • C.返回 A,参数是右操作数
  • D.无参数,逻辑错误

36. 已知:

执行 d = a + b + c; 后,变量 d 的数据类型为
A. int
B. char
C. float
D. double
答案:A
解析:
  • 表达式 a + b + c 中:
    • a → 提升为 double
    • 结果类型是 double
  • 但赋值给 dint
最终 d 的类型仍然是 int
注意:
  • 表达式类型 ≠ 接收变量类型

37. 设有定义 int x; double y; 及语句 x = y;,正确说法是

A. 将 y 的整数部分赋给 x
B. 将 y 的值四舍五入为整数后赋给 x
C. 该语句执行后 xy 相等
D. 将 x 的值转换为实数后赋给 y
答案:A
解析:
  • double → int强制类型转换
  • 直接截断小数部分,不是四舍五入
例如:
逐项:
  • A.正确
  • B.不四舍五入
  • C.类型不同,值也不同
  • D.方向说反了

38. 若变量已正确定义并赋值,以下符合 C/C++ 语言语法的表达式是

A. a := b + 1
B. a = b = c + 2
C. int 18.5 % 3
D. a = a + 7 = c + b
答案:B
解析:
  • C/C++ 中赋值表达式是有值的
逐项:
  • A.:= 不是 C/C++ 运算符
  • B.合法,等价于:
    • C.int 是关键字,不能这样写
    • D.a+7 不是左值,不能再赋值
    易考点:赋值运算符是右结合

    39. 以下选项中不是面向对象程序设计所具有的特性的是

    A. 数据封装
    B. 模板
    C. 继承
    D. 多态性
    答案:B
    解析:
    • 面向对象三大特性:
      • 封装
      • 继承
      • 多态
    • B 选项中模板属于泛型编程,不是 OOP 核心特性
    高频考点:模板 ≠ 面向对象三大特性

    40. 执行以下程序段后,y 的值是

    A. 24
    B. 4
    C. 2
    D. 1
    答案:B
    解析:
    1.初始状态:
    • ptr = &a[1] → 指向 3
    • x = 0y = 1
    2.判断循环:
    • !x!0true,进入循环
    3.循环体:
    • y = 1 + 3 = 4
    4.判断:
    • !x!1false,退出循环
    最终:y = 4,故选 B。

    41. 对于任意一个类,析构函数的个数最多为

    A. 0
    B. 1
    C. 2
    D. 3
    答案:B
    解析:
    析构函数用于在对象生命周期结束时释放资源。
    在 C++ 中,析构函数具有固定名称 ~类名()不能重载,因此一个类中最多只能有一个析构函数
    • A 错误:若类未显式定义析构函数,编译器仍会自动生成一个
    • B 正确
    • C、D 错误:析构函数不允许存在多个

    42. 若有定义 int a[3][3]={{1,2},{5},{2,4,8}};,初始值 5 是数组 a 存储在内存中的第几个元素

    A. 4
    B. 3
    C. 2
    D. 1
    答案:A
    解析:
    二维数组按行优先顺序存储。
    数组展开为一维序列如下:
    位置
    元素
    第1个
    1
    第2个
    2
    第3个
    0
    第4个
    5
    第5个
    0
    第6个
    0
    第7个
    2
    第8个
    4
    第9个
    8
    因此,数值 5 是第 4 个元素。

    43. 设整型变量 xy 的值均为 7,则表达式 x/(y-4) 的值是

    A. 3
    B. -3
    C. 2
    D. 1
    答案:C
    解析:
    • y − 4 = 7 − 4 = 3
    • x / (y − 4) = 7 / 3
    • 整型除法结果取整数部分
    因此结果为 2

    44. 所谓数据封装就是将一组数据和与这组数据有关的操作组装在一起,形成一个实体,这实体也就是

    A. 类
    B. 对象
    C. 函数体
    D. 语句块
    答案:A
    解析:
    数据封装是面向对象的基本思想之一,其核心是:
    • 数据成员操作这些数据的成员函数封装在一起
    • 形成一个抽象的数据类型
    该抽象实体称为,对象是类的实例。

    45. 关于构造函数,下列说法不正确的是

    A. 构造函数的名字和类名相同
    B. 构造函数有且只有一个
    C. 构造函数在创建对象时自动执行
    D. 构造函数无任何函数返回类型
    答案:B
    解析:
    • A 正确:构造函数名必须与类名相同
    • B 错误:构造函数可以被重载,一个类中可以有多个构造函数
    • C 正确:对象创建时自动调用构造函数
    • D 正确:构造函数不具有返回类型

    46. 执行语句 printf("%o",-1); 后屏幕的显示为

    A. -1
    B. 1
    C. 177777
    D. -177777
    (已知 int 占 2 个字节)
    答案:C
    解析:
    • int 占 2 字节,共 16 位
    • 1 的补码表示为:
      • 将该二进制数按无符号数解释并以八进制输出
      • 16 位全为 1,对应的八进制表示为 177777
      因此输出为 177777

      47. 下面判断正确的是

      A. char c[4]="abc", d[4]="abc"; 等价于 char c[4]=d[4]="abc";
      B. char *s="china"; 等价于 char *s; s="china";
      C. char *a="china"; 等价于 char *a; *a="china";
      D. char str[10]={"china"}; 等价于 char str[10]; str[]={"china"};
      答案:B
      解析:
      • A 错误:数组不能整体赋值
      • B 正确:字符串常量地址可以赋给字符指针
      • C 错误:a 是字符,不能接收字符串
      • D 错误:数组只能在定义时初始化,不能再赋值

      48. 若有变量定义 int a; double b;,要输入数据存放在 ab 中,正确的语句是

      A. scanf("%d%f",a,b);
      B. scanf("%d%f",&a,&b);
      C. scanf("%d%lf",&a,&b);
      D. scanf("%d%lf",a,b);
      答案:C
      解析:
      • scanf 需要变量地址
      • int 使用 %d
      • double 使用 %lf
      因此只有 C 选项格式和参数均正确。

      49. 以下各选项中,正确的函数声明是

      A. double func( int x , int y )
      B. int func( int x ; int y );
      C. float func( int x , int y );
      D. char func( int x , y );
      答案:C
      解析:
      • A 缺少分号
      • B 参数分隔符错误,应使用逗号
      • C 返回类型、参数列表和分号均正确
      • D 参数类型不完整

      50. 以下不正确的语句是

      A. if (x > y);
      B. if (x = y) && (x != 0) x += y;
      C. if (x != y) scanf("%d",&x); else scanf("%d",&y);
      D. if (x < y) { x++; y++; }
      答案:B
      解析:
      • A 语法正确,但条件后为空语句
      • B 错误:逻辑表达式必须整体放在 if()
      • C 正确:语法合法
      • D 正确:复合语句结构正确

      51. 一个函数功能不太复杂,但要求被频繁调用,则应把它定义为

      A. 内联函数
      B. 重载函数
      C. 递归函数
      D. 嵌套函数
      答案:A
      解析:
      内联函数在编译时将函数调用直接展开为函数体代码,可以减少函数调用过程中压栈、跳转等开销。
      对于功能简单且被频繁调用的函数,使用内联函数能够提高程序执行效率。
      重载、递归和嵌套函数均不能直接减少函数调用开销。

      52. 执行以下程序段后,变量 a、b、c 的值分别为

      A. a = 9, b = 9, c = 9
      B. a = 8, b = 8, c = 10
      C. a = 9, b = 10, c = 9
      D. a = 9, b = 10, c = 11
      答案:B
      解析:
      1. 初始:x = 10y = 9
      1. 判断表达式 -x == y++
          • -xx 先减 1x = 9
          • y++:先参与比较,值为 9,随后 y 变为 10
          • 比较结果为真
      1. 条件成立,执行 -xx 再减 1x = 8,因此 a = 8
      1. 执行 b = x++b = 8x 变为 9
      1. 执行 c = yy = 10
      最终结果:a = 8b = 8c = 10

      53. 在 C++ 语言中的 if 语句中,用作判断的表达式为

      A. 关系表达式
      B. 逻辑表达式
      C. 算术表达式
      D. 任意表达式
      答案:D
      解析:
      C++ 中 if 语句的判断条件可以是任意表达式
      表达式的结果会被转换为布尔值:
      • 0 值视为真
      • 0 视为假
        • 因此算术、关系、逻辑表达式都可以作为条件。

      54. 下面关于 C++ 语言的描述错误的是

      A. C++ 语言支持数据封装
      B. C++ 语言中引入友元没有破坏封装性
      C. C++ 语言允许函数名和运算符重载
      D. C++ 语言支持动态联编
      答案:B
      解析:
      友元可以访问类的私有和保护成员,突破了访问控制机制,在一定程度上破坏了封装性。
      其引入是为了提高程序灵活性,但并非不破坏封装。
      其余选项均为 C++ 的正确特性描述。

      55. 下列说明中 const char *p = "ok";,其中 p 应该是

      A. 指向字符常量的指针
      B. 指向字符的常量指针
      C. 指向字符串常量的指针
      D. 指向字符串的常量指针
      答案:C
      解析:
      const char *p 表示:
      • 指针本身可变
      • 指向的内容不可通过该指针修改
      字符串字面量属于常量存储区,因此 p指向字符串常量的指针

      56. 在表达式 x + y * 2 中,+ 作为成员函数重载,作为非成员函数重载,则 operator+operator* 分别有多少个参数

      A. 1、1
      B. 1、2
      C. 2、1
      D. 2、2
      答案:B
      解析:
      • 成员函数形式的二元运算符:隐含一个 this 指针,只需 1 个显式参数
      • 非成员函数形式的二元运算符:需要 2 个参数
      因此 operator+ 有 1 个参数,operator* 有 2 个参数。

      57. 若可以在类外用 p.a 的形式访问派生类对象 p 的基类成员 a,则 a

      A. 公有继承的私有成员
      B. 公有继承的保护成员
      C. 公有继承的公有成员
      D. 私有继承的公有成员
      答案:C
      解析:
      • 类外访问要求成员是 public
      • 只有在公有继承下,基类的公有成员在派生类中仍保持公有
      因此 a 必须是公有继承的公有成员。

      58. 下列程序划线处应填入的正确语句是

      A. fun();
      B. Base.fun();
      C. Base::fun();
      D. Base->fun();
      答案:C
      解析:
      在派生类中调用被覆盖的基类成员函数,必须使用作用域运算符明确指定基类。
      Base::fun() 是合法且规范的写法,其余选项语法错误或含义不正确。

      59. 在一个类中,可以对一个操作符进行

      A. 1 种
      B. 不超过 2 种
      C. 不超过 3 种
      D. 多种
      答案:D
      解析:
      同一个运算符可以根据参数类型不同进行多次重载,例如:
      • 成员函数重载
      • 非成员函数重载
      • 不同参数组合
      因此一个操作符可以有多种重载形式。

      60. 在公有继承的情况下,基类非私有成员在派生类中的访问权限

      A. 受限制
      B. 受保护
      C. 不受保护
      D. 保持不变
      答案:D
      解析:
      公有继承遵循“是什么”关系,
      • 基类的 public 成员仍为 public
      • 基类的 protected 成员仍为 protected
      因此访问权限保持不变。

      61. 保护继承时,基类的哪些成员在派生类中成为保护成员,不能通过派生类对象直接访问

      A. 任何成员
      B. 公有成员和私有成员
      C. 公有成员和保护成员
      D. 私有成员
      答案:C
      解析:
      保护继承规则:
      • 基类的 publicprotected 成员在派生类中变为 protected
      • 基类的 private 成员不可直接访问
      因此不能通过派生类对象直接访问的是公有成员和保护成员。

      62. 类 A 中的一个成员函数原型为 void Set(A &a);,其中 A &a 的含义是

      A. 指向类 A 的指针为 a
      B. 将 a 的地址值赋给变量 set
      C. a 是类 A 对象的引用,用来作函数 Set 的形参
      D. 变量 Aa 按位相与作为函数 Set 的参数
      答案:C
      解析:
      A &a 表示:
      • a 是类 A 对象的引用参数
      • 函数内部对 a 的修改将直接作用于实参对象
        • 该写法常用于避免对象拷贝并提高效率。

      63. 以下对派生类的描述中,错误的是

      A. 一个派生类可以作为另外一个派生类的基类
      B. 派生类至少有一个基类
      C. 从派生类中继承的基类成员的访问权限到派生类中保持不变
      D. 派生类的成员除了其自己的成员外,还包含了其基类的成员
      答案:C
      解析:
      基类成员在派生类中的访问权限是否改变,取决于继承方式(公有、保护或私有继承)。
      只有在公有继承时访问权限才保持不变,因此该说法不具有普遍性,是错误的。

      填空题

      1. 给出下述程序的执行结果。

      答案:8
      解析:
      该函数实现的是斐波那契数列:
      • fib(0)=0
      • fib(1)=fib(2)=1
      • fib(n)=fib(n−1)+fib(n−2)
      依次计算:
      • fib(3)=2
      • fib(4)=3
      • fib(5)=5
      • fib(6)=8
      因此程序输出结果为 8

      2. 下面的函数 invert 的功能是将一个字符串的内容颠倒过来。

      答案:
      k-1
      解析:
      • 变量 k 用于暂存字符,实现交换
      • 字符串下标最大值为 strlen(str)-1,因为下标从 0 开始
      • 若不减 1,则会访问字符串结束符 '\0',导致错误
      完整逻辑是从字符串首尾向中间逐字符交换,实现反转。

      3. 若有说明char *language[] = {"FORTRAN", "BASIC", "PASCAL", "JAVA", "C"};,则表达式 *language[1] > *language[3] 比较的是

      A. 字符 F 和字符 P
      B. 字符串 BASIC 和字符串 JAVA
      C. 字符 B 和字符 J
      D. 字符串 FORTRAN 和字符串 PASCAL
      答案:C
      解析:
      • language[1] 指向字符串 "BASIC"
      • language[1] 取的是该字符串的第一个字符 'B'
      • language[3] 指向 "JAVA"
      • language[3]'J'
      因此比较的是字符 'B''J' 的 ASCII 值。

      4. 已知:char x='A', y='B';,执行 bool z = (x='B') || (y='C'); 后,变量 xy 的值分别为

      答案:B, B
      解析:
      • (x='B') 是赋值表达式,结果为 'B',非 0,逻辑值为真
      • 逻辑或 || 具有短路特性,左侧为真,右侧 (y='C') 不再执行
      • 因此:
        • x 被赋值为 'B'
        • y 保持原值 'B'

      5. 在 C/C++ 语言程序中,转义字符 \n 的功能是

      答案:换行
      解析:
      \n 表示换行符,用于将输出光标移动到下一行的行首,常用于格式化输出。

      6. 计算机中内存储器的最小存储单位是

      答案:bit
      解析:
      • bit(位)是计算机中最小的数据单位
      • 8 个 bit 组成 1 个 byte(字节)
      • 内存的基本寻址单位通常是字节,但最小存储单位仍是 bit

      7. 预处理命令行都必须以 号开始。

      答案:#
      解析:
      C/C++ 中的预处理指令(如 #include#define#ifdef
      均以 # 开头,用于在编译前进行文本处理。

      8. 给出下述程序的输出结果

      答案:$$$
      解析:
      • 表达式 a=b+c 为赋值表达式
      • b+c=0,因此 a 被赋值为 0
      • if(0) 条件为假,理论上应进入 else,应输出 $$$

      9. 以下程序的运行结果是

      答案:s=2,t=3
      解析:
      • 初始:s=1t=1
      • a>0 成立,s++s=2
      • a>b 成立,执行 t+=st=1+2=3
      • 后续 else ifelse 不再执行
      最终输出 s=2,t=3

      10. 在 C/C++ 语言中,八进制整型常量以 作为前缀。

      答案:0
      解析:
      • 八进制整数以前导 0 表示,如 012
      • 十六进制以前导 0x0X 表示
      • 十进制不使用前缀

      判断题

      1.函数模版中的模版参数只能有一个。

      答案:错误
      解析:函数模板可以定义多个模板参数,参数之间使用逗号分隔。例如 template <typename T1, typename T2>,这允许函数处理多种不同类型的数据组合。

      2.转换函数不是成员函数,它是用来时行强制类型转换的。

      答案:错误
      解析:转换函数(类型转换运算符重载)必须是类的成员函数。它没有返回类型声明(返回类型由函数名推断),且通常声明为 const。虽然它的功能是进行类型转换,但在语法定义上它属于成员函数。

      3.每个类有且仅有一个拷贝构造函数。

      答案:错误
      解析:C++ 允许重载拷贝构造函数。一个类可以同时拥有针对 const 引用和非 const 引用的拷贝构造函数。此外,如果用户未定义,编译器会自动生成一个默认的拷贝构造函数。

      4.面向对象程序设计有四个主要特点,即抽象、封装、继承和多态。

      答案:正确
      解析:这是面向对象编程(OOP)公认的四大核心特性。抽象是将复杂系统简化为模型;封装是隐藏实现细节;继承是实现代码复用和层级关系;多态是允许不同类的对象对同一消息作出不同响应。

      5.析构函数是一种函数体为空的成员函数。

      答案:错误
      解析:析构函数的函数体不一定为空。虽然默认生成的析构函数可能为空,但用户定义的析构函数通常包含释放动态分配的内存、关闭文件句柄或释放其他系统资源的关键代码。

      6.友元函数是用关键字 friend 修饰的成员函数。

      答案:错误
      解析:友元函数虽然在类内部使用 friend 关键字进行声明,但它不是该类的成员函数。它是一个拥有特殊访问权限的普通函数(或另一个类的成员函数),可以访问该类的私有和保护成员,但不属于该类的作用域。

      7.C++类的组成包括数据成员和成员函数,友元不是该类的成员函数。

      答案:正确
      解析:类的成员严格指数据成员(属性)和成员函数(方法)。友元函数是独立于类之外的外部函数,它只是获得了访问类私有成员的特权,并不属于类的成员列表。

      8.运算符重载函数必须是类的成员函数。

      答案:错误
      解析:运算符重载函数既可以是类的成员函数,也可以是类的友元函数(全局函数)。对于某些特定运算符(如输入输出流运算符 <<>>),通常必须重载为友元函数,因为左操作数(流对象)不是该类的对象。

      9.派生类中的成员不能直接访问基类中的私有成员。

      答案:正确
      解析:基类的私有成员(private)对于派生类是不可见的。无论采用何种继承方式,派生类的成员函数都无法直接访问基类的私有成员,必须通过基类提供的公有或保护接口进行访问。

      10.非成员函数应声明为类的友元函数才能访问这个类的 private 成员。

      答案:正确
      解析:类的私有成员(private)体现了封装性,默认对外部不可见。非成员函数若想直接访问类的私有数据,必须被该类显式声明为友元(friend)。

      11.派生类的构造函数一般有 3 项工作要完成:首先基类初始化,其次成员对象初始化,最后执行派生类构造函数体。

      答案:正确
      解析:这是C++规定的派生类对象构造顺序:系统先调用基类构造函数初始化基类部分,再调用内嵌对象(子对象)的构造函数,最后执行派生类自身的构造函数体代码。

      12.对象数组的元素可以是不同类的对象。

      答案:错误
      解析:C++ 中的数组是同质的,即数组中的所有元素必须是相同的数据类型(也就是同一个类)。若要实现存放不同类对象的效果,通常需要使用基类指针数组结合多态来实现。

      13.已知:m 是类 A 的对象,n 是类 A 的公有数据成员,p 是指向类 An 成员的指针。则这两种表示是等价的:m.nm.*p

      答案:正确
      解析:p 是一个指向类数据成员的指针,m.*p 是使用成员指针访问对象 m 中特定成员的标准语法。如果 p 初始化为指向 n,则 m.*p 确实访问的是 mn 成员,与 m.n 等价。

      14.所谓私有成员是指只有类中的成员函数才能直接使用它们,任何类以外的函数(友元函数除外)对它们的访问都是非法的。

      答案:正确
      解析:该描述准确定义了私有成员(private)的访问权限。除了该类的成员函数和特许的友元函数外,其他任何函数或对象都不能直接访问私有成员。

      15.创建对象时,需要显式调用类的构造函数对其进行初始化。

      答案:错误
      解析:构造函数的调用通常是隐式的。当定义一个对象时(例如 A obj;new A;),编译器会自动调用相应的构造函数进行初始化,程序员不能像调用普通成员函数那样显式调用构造函数。

      16.保护派生时,基类的公有成员成为派生类的公有成员;保护成员成为派生类的保护成员,私有成员成为派生类的保护成员。

      答案:错误
      解析:在保护继承中,基类的公有成员和保护成员在派生类中都变为保护成员。但是,基类的私有成员在派生类中仍然是不可访问的,它们不会变成保护成员。

      17.若派生类执行无参构造函数,则其基类也将调用无参构造函数,即基类必须定义有无参构造函数。

      答案:正确
      解析:如果派生类的构造函数没有在初始化列表中显式调用基类的特定构造函数,编译器将尝试隐式调用基类的默认构造函数(无参构造函数)。如果基类没有可用的无参构造函数,编译将报错。

      18.虚基类是用来解决多继承中公共基类在派生类中只产生一个基类子对象的问题。

      答案:正确
      解析:这是虚基类的核心作用。在多重继承的菱形结构中,使用虚继承可以保证公共基类在最终派生类中只有一份副本,避免数据冗余和二义性。

      19.在公有继承中,基类中的公有成员和私有成员在派生类中都是可见的。

      答案:错误
      解析:即使是公有继承,基类的私有成员(private)在派生类中也是不可见的。派生类只能访问基类的公有成员和保护成员。

      20.派生类是从基类派生出来,它不能再生成新的派生类。

      答案:错误
      解析:C++ 支持多层继承。派生类完全可以作为基类,继续派生出新的子类,形成继承链。

      21.由 new 运算符创建的动态对象,程序结束时系统会自动执行其析构函数。

      答案:错误
      解析:使用 new 在堆上创建的对象,必须显式使用 delete 运算符来销毁。如果程序结束时没有执行 delete,这些对象的析构函数不会被自动调用,这属于内存泄漏。

      22.类模板可以生成若干个模板类,每个模板类又可定义若干个对象。

      答案:正确
      解析:类模板通过传入不同的类型参数实例化为不同的模板类,例如 vector<int>vector<double>。每个实例化后的类都可以像普通类一样创建任意数量的对象。

      23.预定义的提取符和插入符是可以重载的。

      答案:正确
      解析:C++ 允许重载流插入运算符 << 和流提取运算符 >>,以便让标准输入输出流支持用户自定义类型的操作。

      24.虚函数是用 virtual 关键字说明的成员函数。

      答案:正确
      解析:在基类中声明成员函数时使用 virtual 关键字,即将其定义为虚函数。这是实现运行时多态(动态绑定)的基础机制。

      25.具有纯虚函数的类是抽象类,它的特点是不可以定义对象。

      答案:正确
      解析:包含至少一个纯虚函数的类被称为抽象类。抽象类仅作为接口规范,不能被实例化,即不能定义抽象类的对象,只能定义指向它的指针或引用。

      26.构造函数说明为纯虚函数是没有意义的。

      答案:正确
      解析:构造函数不能是虚函数,更不能是纯虚函数。构造函数的任务是初始化对象,而虚函数机制依赖于对象已存在(通过虚函数表),且构造时对象的类型是确定的,多态概念不适用于构造过程。

      27.析构函数和构造函数都不能重载。

      答案:错误
      解析:构造函数可以重载(可以有多个不同参数列表的构造函数),以便以不同方式初始化对象。只有析构函数不能重载,因为析构函数没有参数且一个类只能有一个。
      上一篇
      C / C++语言程序设计复习大纲
      下一篇
      复杂度

      评论
      Loading...
      目录