😀 第1题
下列叙述中错误的是
A. 向量是线性结构
B. 非空线性结构中只有一个结点没有前件
C. 非空线性结构中只有一个结点没有后件
D. 只有一个根结点和一个叶子结点的结构必定是线性结构
概念澄清
首先,我们需要明确几个关键概念:
线性结构:线性结构是指数据元素之间存在一对一的线性关系。常见的线性结构包括线性表(如数组、链表)、栈、队列等。线性结构的特点是:
存在唯一的一个“第一个”元素(无前驱,即没有前件)。
存在唯一的一个“最后一个”元素(无后继,即没有后件)。
除第一个和最后一个元素外,其他元素都有唯一的前驱和后继。
向量:在计算机科学中,向量通常指的是动态数组(如C++中的
std::vector
)。它是一种线性结构,因为元素是按顺序存储的,每个元素(除了第一个和最后一个)都有明确的前驱和后继。根结点和叶子结点:
根结点:在树形结构中,根结点是没有父结点的结点;在线性结构中,可以理解为第一个结点。
叶子结点:在树形结构中,叶子结点是没有子结点的结点;在线性结构中,可以理解为最后一个结点。
逐项分析
选项A:向量是线性结构
向量(动态数组)的元素是连续存储的,具有明确的顺序,每个元素(除了首尾)都有唯一的前驱和后继。
因此,向量确实是线性结构。
结论:A是正确的。
选项B:非空线性结构中只有一个结点没有前件
非空线性结构中,第一个结点(头结点)是没有前件的。
其他所有结点都有且只有一个前件。
因此,确实只有一个结点没有前件。
结论:B是正确的。
选项C:非空线性结构中只有一个结点没有后件
非空线性结构中,最后一个结点(尾结点)是没有后件的。
其他所有结点都有且只有一个后件。
因此,确实只有一个结点没有后件。
结论:C是正确的。
选项D:只有一个根结点和一个叶子结点的结构必定是线性结构
我们需要判断“只有一个根结点和一个叶子结点的结构”是否一定是线性结构。
在线性结构中,确实只有一个根结点(无前件)和一个叶子结点(无后件)。
但是,反过来是否成立?即“只有一个根结点和一个叶子结点的结构”是否只能是线性结构?
考虑树形结构:在一般的树中,根结点是唯一的(无父结点),叶子结点可以有多个(无子结点)。但如果限制只有一个叶子结点,那么这样的树是什么样子?
如果树只有一个根结点和一个叶子结点,那么这两个结点之间只能有一条路径连接,即线性连接。任何分支都会导致多个叶子结点。
因此,这种结构实际上就是线性结构。
但是,如果考虑更一般的图结构:
例如,一个环(所有结点形成一个环):没有明确的根结点和叶子结点。
或者,一个根结点指向一个叶子结点,同时叶子结点又指向根结点:这样有两个结点,一个根一个叶子,但这是一个循环结构,不是线性结构。
因此,如果允许循环或更复杂的图结构,“只有一个根结点和一个叶子结点”的结构不一定是线性的。
题目中“结构”是否限定为树或线性结构?如果严格限定为树或线性结构,D可能是正确的;但更一般地,可能是错误的。
通常在数据结构中,“结构”可以指更一般的图结构,因此D的表述过于绝对。
结论:D是错误的。
验证D的反例
为了验证D的错误,可以构造一个反例:
考虑一个有向图:
两个结点:A(根结点,无前驱)和 B(叶子结点,无后继)。
边:A → B,同时 B → A。
这样,A是唯一的根结点(无前驱),B是唯一的叶子结点(无后继)。
但这个结构不是线性的,因为存在环(A→B→A)。
因此,“只有一个根结点和一个叶子结点的结构”不一定是线性结构。
其他选项的再确认
为了确保其他选项的正确性:
A:向量是线性结构 —— 正确。
B:非空线性结构只有一个无前件的结点 —— 正确(头结点)。
C:非空线性结构只有一个无后件的结点 —— 正确(尾结点)。
D:反例存在,不正确。
可能的疑问
有人可能会认为D是正确的,因为:
如果限制为“树”结构,那么只有一个根和一个叶子的树确实是线性的。
但题目没有明确限制为树结构,“结构”可以更广泛地包括图结构。
因此,D的表述“必定是线性结构”过于绝对。
结论
经过以上分析,叙述D是错误的。
最终答案
D. 只有一个根结点和一个叶子结点的结构必定是线性结构 是错误的。
😀 第2题
在希尔排序法中,每经过一次数据交换后
A. 能消除多个逆序
B. 只能消除一个逆序
C. 不会产生新的逆序
D. 消除的逆序个数一定比新产生的逆序个数多
希尔排序的基本概念
希尔排序(Shell Sort)是插入排序的一种改进版本,也称为缩小增量排序。其核心思想是:
将原始数组分成若干子序列,子序列的元素是通过**间隔(增量)**选取的。
例如,初始增量可以是
n/2
,之后逐步减半(n/4
,n/8
, ..., 1)。
对每个子序列进行插入排序。
随着增量的逐步减小,子序列越来越长,最终增量为1时,整个数组作为一个子序列进行插入排序。
希尔排序的特点是:
通过较大的增量,可以快速将元素移动到较远的位置,从而减少后续小增量排序的工作量。
每次交换可能同时影响多个逆序对。
关键点:逆序(Inversion)
逆序是指数组中前面的元素大于后面的元素,即如果 i < j
且 A[i] > A[j]
,则 (A[i], A[j])
是一个逆序。
插入排序每次只能消除一个逆序(交换相邻元素)。
希尔排序由于可以跨越多个位置交换,因此一次交换可能消除多个逆序。
逐项分析
选项A:能消除多个逆序
希尔排序的交换是跨越多个位置的(由增量决定)。
例如:
数组
[9, 8, 7, 6, 5, 4, 3, 2, 1]
,初始增量为4:子序列:
[9,5,1]
、[8,4]
、[7,3]
、[6,2]
。对
[9,5,1]
排序:交换9
和5
,再交换9
和1
。交换
9
和5
:消除了(9,5)
、(9,1)
等多个逆序。
因此,希尔排序的一次交换可以消除多个逆序。
结论:A是正确的。
选项B:只能消除一个逆序
这是插入排序的特点(每次只能消除一个相邻逆序)。
希尔排序的交换是跨增量的,可以消除多个逆序。
结论:B是错误的。
选项C:不会产生新的逆序
希尔排序的交换可能会引入新的逆序。
例如:
子序列
[5, 9, 1]
(增量跳跃):交换
5
和1
:原逆序(5,1)
消除,但可能在其他子序列中引入新逆序。
因此,可能产生新的逆序。
结论:C是错误的。
选项D:消除的逆序个数一定比新产生的逆序个数多
希尔排序的总体趋势是减少逆序,但不一定每次交换都满足“消除的逆序比新增的多”。
例如:
子序列
[6, 2, 7]
:交换
6
和2
:消除(6,2)
,但可能在其他子序列中新增逆序。无法保证每次交换都“净减少”逆序。
结论:D是错误的。
反例验证
以数组 [4, 6, 2, 5, 1]
为例,增量为2:
子序列:
[4, 2, 1]
和[6, 5]
。对
[4, 2, 1]
:交换
4
和2
:消除(4,2)
和(4,1)
(多个逆序),新增无。交换
2
和1
:消除(2,1)
,新增无。
对
[6, 5]
:交换
6
和5
:消除(6,5)
,新增无。
此例中:
A:正确(如
4
和2
交换消除多个逆序)。B:错误(不止一个)。
C:错误(此例未新增,但其他情况可能新增)。
D:错误(无法保证“一定”更多)。
排除法
A正确,B、C、D均不完全成立。
但题目问“错误的是”,因此选择错误的叙述。
可能的误区
有人可能认为:
希尔排序的交换和插入排序类似(每次消除一个逆序),从而误选B。
但实际上,希尔排序的跨增量交换可以消除多个逆序。
结论
最明显错误的是 B(“只能消除一个逆序”),因为希尔排序可以消除多个逆序。
最终答案
B. 只能消除一个逆序 是错误的。
😀 第3题
设二叉树的后序序列与中序序列均为ABCDEFGH,则该二叉树的前序序列为
A. HGFEDCBA
B. ABCDEFGH
C. ABCDHGFE
D. DCBAHGFE
基本概念
在解决这个问题之前,我们需要明确几个关键概念:
前序遍历(Pre-order):根 → 左子树 → 右子树
中序遍历(In-order):左子树 → 根 → 右子树
后序遍历(Post-order):左子树 → 右子树 → 根
题目分析
题目给出的后序序列和中序序列均为 ABCDEFGH
。我们需要根据这两个序列重建二叉树,然后求出其前序序列。
第一步:观察后序序列和中序序列
后序序列的最后一个元素是根节点。因此:
后序序列
ABCDEFGH
→ 根节点是H
。
中序序列中,根节点
H
将序列分为左子树和右子树:中序序列
ABCDEFGH
→H
是最后一个元素,因此:左子树:
ABCDEFG
右子树:空(因为
H
后面没有其他元素)
第二步:递归构建左子树
现在我们需要构建左子树 ABCDEFG
:
左子树的后序序列:从后序序列
ABCDEFGH
中去除H
,得到ABCDEFG
(左子树的后序序列)。左子树的中序序列:
ABCDEFG
。
重复上述步骤:
左子树的后序序列
ABCDEFG
→ 根节点是G
。中序序列
ABCDEFG
→G
是最后一个元素:左子树的左子树:
ABCDEF
左子树的右子树:空
继续递归:
左子树的左子树
ABCDEF
:后序序列
ABCDEF
→ 根节点是F
。中序序列
ABCDEF
→F
是最后一个元素:左子树的左子树的左子树:
ABCDE
左子树的左子树的右子树:空
继续:
左子树的左子树的左子树
ABCDE
:后序序列
ABCDE
→ 根节点是E
。中序序列
ABCDE
→E
是最后一个元素:左子树的左子树的左子树的左子树:
ABCD
左子树的左子树的左子树的右子树:空
继续:
左子树的左子树的左子树的左子树
ABCD
:后序序列
ABCD
→ 根节点是D
。中序序列
ABCD
→D
是最后一个元素:左子树的左子树的左子树的左子树的左子树:
ABC
左子树的左子树的左子树的左子树的右子树:空
继续:
左子树的左子树的左子树的左子树的左子树
ABC
:后序序列
ABC
→ 根节点是C
。中序序列
ABC
→C
是最后一个元素:左子树的左子树的左子树的左子树的左子树的左子树:
AB
左子树的左子树的左子树的左子树的左子树的右子树:空
继续:
左子树的左子树的左子树的左子树的左子树的左子树
AB
:后序序列
AB
→ 根节点是B
。中序序列
AB
→B
是最后一个元素:左子树的左子树的左子树的左子树的左子树的左子树的左子树:
A
左子树的左子树的左子树的左子树的左子树的左子树的右子树:空
最后:
A
是叶子节点。
第三步:构建二叉树
通过以上递归过程,我们可以构建出二叉树的结构:
根节点:
H
左子树:
G
左子树:
F
左子树:
E
左子树:
D
左子树:
C
左子树:
B
左子树:
A
右子树:空
右子树:空
右子树:空
右子树:空
右子树:空
右子树:空
右子树:空
用图形表示:
这是一棵极度左倾的二叉树,每个节点只有左子树,没有右子树。
第四步:验证后序和中序序列
为了验证我们的构建是否正确,我们可以检查后序和中序序列:
后序遍历:
遍历顺序:左 → 右 → 根
从最左下的
A
开始,依次向上:A
→B
→C
→D
→E
→F
→G
→H
结果为
ABCDEFGH
,与题目一致。
中序遍历:
遍历顺序:左 → 根 → 右
从最左下的
A
开始,依次向上:A
→B
→C
→D
→E
→F
→G
→H
结果为
ABCDEFGH
,与题目一致。
第五步:求前序序列
前序遍历的顺序是:根 → 左 → 右。
对于我们构建的二叉树:
从根
H
开始:访问
H
访问
H
的左子树G
:访问
G
访问
G
的左子树F
:访问
F
访问
F
的左子树E
:访问
E
访问
E
的左子树D
:访问
D
访问
D
的左子树C
:访问
C
访问
C
的左子树B
:访问
B
访问
B
的左子树A
:访问
A
B
的右子树为空
C
的右子树为空
D
的右子树为空
E
的右子树为空
F
的右子树为空
G
的右子树为空
H
的右子树为空
因此,前序序列为:H, G, F, E, D, C, B, A
,即 HGFEDCBA
。
选项匹配
A.
HGFEDCBA
→ 正确B.
ABCDEFGH
→ 错误(这是中序或后序序列)C.
ABCDHGFE
→ 错误D.
DCBAHGFE
→ 错误
验证其他选项
为什么其他选项不正确?
B.
ABCDEFGH
:这是中序或后序序列,不是前序序列。
C.
ABCDHGFE
:前序序列应从根
H
开始,而不是A
。
D.
DCBAHGFE
:前序序列应从根
H
开始,且DCBA
的顺序不符合前序。
可能的误区
混淆遍历顺序:
可能会误认为后序和中序相同,前序也相同(选B),但实际上前序是根左右,需要从根开始。
忽略极度左倾的二叉树:
可能会认为二叉树有其他结构,但根据后序和中序的唯一性,只能构建出极度左倾的树。
结论
通过逐步构建二叉树并验证遍历序列,可以确定:
前序序列为
HGFEDCBA
。因此,正确答案是 A。
最终答案
A. HGFEDCBA
😀 第4题
在黑盒测试方法中,设计测试用例的根据是
A. 数据结构
B. 程序调用规则
C. 模块间的逻辑关系
D. 软件要完成的功能
基本概念
首先,我们需要明确**黑盒测试(Black-box Testing)**的定义:
黑盒测试是一种软件测试方法,它不关心程序的内部结构或实现细节,而是基于软件的功能需求或规格说明来设计测试用例。
测试者将软件视为一个“黑盒”,只关注输入和输出是否符合预期,而不关注内部是如何实现的。
黑盒测试的核心依据
黑盒测试的设计依据主要包括:
软件的功能需求(Functional Requirements):
测试用例的设计是为了验证软件是否按照需求规格说明(SRS)正确地实现了功能。
例如:测试一个登录功能时,输入正确的用户名和密码是否能成功登录。
输入与输出的关系:
根据输入数据的不同组合,验证输出是否符合预期。
例如:边界值分析、等价类划分等黑盒测试技术。
用户视角:
黑盒测试是从用户的角度出发,验证软件是否满足用户需求。
黑盒测试不关注的方面
黑盒测试不关注以下内容:
内部代码结构(如数据结构、算法)。
程序的具体实现(如函数调用规则、模块间的逻辑关系)。
这些属于**白盒测试(White-box Testing)**的范畴。
选项分析
选项A:数据结构
数据结构是程序的内部实现细节,属于白盒测试的关注点。
黑盒测试不关心数据结构。
结论:A不是正确答案。
选项B:程序调用规则
程序调用规则(如函数调用顺序、模块间的调用关系)是代码内部逻辑的一部分。
这是白盒测试(如路径测试、控制流测试)的依据。
结论:B不是正确答案。
选项C:模块间的逻辑关系
模块间的逻辑关系(如接口调用、数据传递)是系统设计的一部分。
这属于灰盒测试或白盒测试的范畴,黑盒测试不关心模块间的具体交互。
结论:C不是正确答案。
选项D:软件要完成的功能
黑盒测试的核心就是验证软件是否按照需求完成了预期的功能。
测试用例的设计直接基于功能需求(如需求文档、用户故事)。
结论:D是正确答案。
验证其他测试方法
为了进一步确认,我们可以对比其他测试方法:
白盒测试:
依据:代码结构、逻辑路径、分支覆盖等。
例如:选项A、B、C的内容。
灰盒测试:
介于黑盒和白盒之间,部分关注内部逻辑。
例如:接口测试、模块间交互测试(选项C的部分内容)。
黑盒测试:
仅关注功能(选项D)。
实际例子
假设测试一个计算器软件:
黑盒测试:
设计测试用例:输入
2 + 2
,验证输出是否为4
。不关心计算器内部是用什么数据结构或算法实现的。
白盒测试:
设计测试用例:检查加法函数是否被正确调用,或是否覆盖了所有分支。
需要了解代码的内部逻辑。
排除法
A、B、C均与内部实现相关,属于白盒或灰盒测试。
只有D是纯粹的黑盒测试依据。
可能的误区
有人可能会误选:
C. 模块间的逻辑关系:
可能会认为黑盒测试需要关注模块间的接口,但实际上黑盒测试只关注整体功能,不关心模块如何交互。
模块间交互更多是集成测试或灰盒测试的内容。
B. 程序调用规则:
这是典型的白盒测试内容(如单元测试中 mock 函数调用)。
结论
黑盒测试的唯一正确依据是软件要完成的功能。
最终答案
D. 软件要完成的功能 是正确的。
😀 第5题
下列叙述中正确的是
A. 循环队列是队列的链式存储结构
B. 能采用顺序存储的必定是线性结构
C. 所有的线性结构都可以采用顺序存储结构
D. 具有两个以上指针的链表必定是非线性结构
基本概念
在解答这个问题之前,我们需要明确几个关键概念:
线性结构:
数据元素之间存在一对一的线性关系。
常见的线性结构包括:线性表(数组、链表)、栈、队列等。
非线性结构:
数据元素之间存在多对多的关系。
常见的非线性结构包括:树、图等。
顺序存储结构:
用一段连续的存储单元依次存储数据元素(如数组)。
特点:随机访问高效,插入/删除可能需要移动大量元素。
链式存储结构:
通过指针(或引用)将数据元素链接起来(如链表)。
特点:插入/删除高效,但随机访问效率低。
循环队列:
队列的一种实现方式,通过数组(顺序存储)模拟环形结构。
目的是解决普通顺序队列的“假溢出”问题。
多指针链表:
链表中的结点包含多个指针(如双向链表、树、图等)。
双向链表仍然是线性结构;树和图是非线性结构。
逐项分析
选项A:循环队列是队列的链式存储结构
循环队列的实现:
循环队列通常使用**顺序存储(数组)**实现,通过模运算模拟环形结构。
链式存储的队列是普通的链队列(用链表实现),不是循环队列。
结论:
循环队列是顺序存储,不是链式存储。
A是错误的。
选项B:能采用顺序存储的必定是线性结构
顺序存储的适用性:
顺序存储通常用于线性结构(如数组、顺序栈、顺序队列)。
但某些非线性结构也可以采用顺序存储:
例如:完全二叉树可以用数组存储(堆的实现)。
图的邻接矩阵也是顺序存储。
反例:
完全二叉树的顺序存储是非线性结构。
结论:
能采用顺序存储的不一定是线性结构。
B是错误的。
选项C:所有的线性结构都可以采用顺序存储结构
线性结构的存储方式:
线性结构(如线性表、栈、队列)既可以用顺序存储(数组),也可以用链式存储(链表)。
顺序存储是线性结构的一种通用实现方式。
反例:
目前没有线性结构不能采用顺序存储的例子。
结论:
所有线性结构都可以采用顺序存储。
C是正确的。
选项D:具有两个以上指针的链表必定是非线性结构
多指针链表的例子:
双向链表:每个结点有
prior
和next
两个指针,但仍然是线性结构。树或图:每个结点可能有多个指针(如二叉树、邻接表),是非线性结构。
关键点:
“两个以上指针”是否一定非线性?
双向链表有两个指针,但仍是线性结构。
因此,“两个以上指针”不一定是非线性结构。
结论:
具有两个以上指针的链表不一定是非线性结构。
D是错误的。
验证与总结
A:循环队列是顺序存储,错误。
B:顺序存储可以用于非线性结构(如堆),错误。
C:线性结构都可以用顺序存储,正确。
D:双向链表是多指针但线性,错误。
可能的误区
循环队列的实现:
容易误认为循环队列是链式存储,但实际上它是顺序存储的优化。
顺序存储的适用范围:
可能认为顺序存储只能用于线性结构,忽略了完全二叉树、堆等非线性结构的顺序存储。
多指针链表的性质:
容易混淆双向链表(线性)与树/图(非线性)。
结论
唯一正确的叙述是 C。
最终答案
C. 所有的线性结构都可以采用顺序存储结构 是正确的。
😀 第6题
对软件系统总体结构图,下面描述中错误的是
A. 深度等于控制的层数
B. 扇入是一个模块直接调用的其他模块数
C. 扇出是⼀个模块直接调用的其他模块数
D. V一定是结构图中位于叶子结点的模块
题目解析:
我们需要找出关于软件系统总体结构图描述中错误的选项。首先,明确几个关键概念:
1. 软件结构图的基本概念
软件结构图(Structure Chart)是描述软件系统模块层次结构的图形表示。
包含模块、调用关系、数据传递、控制信息等。
常见术语:
深度:从顶层模块到最底层模块的层数。
宽度:同一层次上模块的最大数量。
扇出(Fan-out):一个模块直接调用的其他模块数。
扇入(Fan-in):直接调用该模块的其他模块数。
叶子模块:不调用其他模块的底层模块。
2. 逐项分析选项
选项A:深度等于控制的层数
深度确实是指从顶层模块到最底层模块的层数(即控制的层数)。
例如:顶层模块 → 中间模块 → 叶子模块,深度为3。
结论:A的描述正确。
选项B:扇入是一个模块直接调用的其他模块数
扇入的定义是有多少个模块直接调用当前模块,而不是当前模块调用其他模块。
题目描述将“扇入”错误地等同于“扇出”。
结论:B的描述错误(这是扇出的定义)。
选项C:扇出是一个模块直接调用的其他模块数
扇出的正确定义是一个模块直接调用的其他模块数。
例如:模块A调用模块B和C,扇出为2。
结论:C的描述正确。
选项D:V一定是结构图中位于叶子结点的模块
叶子结点模块是指不调用其他模块的模块(即扇出为0)。
通常用特定符号(如V)表示叶子模块,但题目未明确说明符号规范。
如果题目中约定V表示叶子模块,则D正确;否则无法直接判断。
结合其他选项,B的错误更明显,因此D可能是正确的。
3. 关键点总结
扇入和扇出的定义是核心考点:
扇入:被多少模块调用。
扇出:调用多少模块。
选项B混淆了扇入和扇出,是明显错误。
4. 排除法验证
A正确,B错误,C正确,D可能正确。
题目要求选择错误描述,因此选B。
5. 可能的误区
混淆扇入和扇出的定义。
忽略叶子模块的符号约定(D选项的干扰)。
最终答案
B. 扇入是一个模块直接调用的其他模块数 是错误的。
😀 第7题
下面属于系统软件的是()
A. 浏览器
B. 数据库管理系统
C. 人事管理系统
D. 天气预报的app
题目解析:
我们需要从选项中识别出系统软件。首先明确系统软件的定义:
1. 系统软件 vs. 应用软件
系统软件:
直接服务于计算机硬件和操作系统,提供基础功能。
例如:操作系统(Windows、Linux)、数据库管理系统(DBMS)、编译器、驱动程序等。
特点:通用性强,与硬件或系统管理相关。
应用软件:
面向用户具体需求,完成特定任务。
例如:浏览器、办公软件、游戏、天气预报App等。
特点:专用性强,依赖系统软件运行。
2. 逐项分析选项
选项A:浏览器
浏览器(如Chrome、Firefox)是用户访问互联网的工具,属于应用软件。
结论:不是系统软件。
选项B:数据库管理系统(DBMS)
DBMS(如MySQL、Oracle)负责数据的存储、管理和检索,是操作系统之上的基础软件。
它为其他软件提供数据服务,属于系统软件。
结论:是系统软件。
选项C:人事管理系统
人事管理系统是企业用于管理员工信息的专用软件,属于应用软件。
结论:不是系统软件。
选项D:天气预报的App
天气预报App是面向用户提供天气信息的工具,属于应用软件。
结论:不是系统软件。
3. 关键区分点
系统软件的核心特征是:
管理硬件或系统资源(如DBMS管理数据资源)。
为其他软件提供支持(如编译器、驱动程序)。
应用软件直接面向用户解决具体问题。
4. 排除法验证
A、C、D均为应用软件,只有B(DBMS)是系统软件。
数据库管理系统是典型的系统软件,与操作系统、编译器并列。
5. 常见误区
误将浏览器或工具类软件(如杀毒软件)当作系统软件。
实际上,浏览器依赖操作系统和网络协议,本身是应用软件。
混淆DBMS与普通数据库应用:
DBMS是系统软件,而基于DBMS开发的“人事管理系统”是应用软件。
最终答案
B. 数据库管理系统 是系统软件。
😀 第8题
能够减少相同数据重复存储的是
A. 数据库
B. 字段
C. 文件
D. 记录
题目解析:
我们需要从选项中找出能够减少相同数据重复存储的技术或结构。以下是逐步分析:
1. 问题核心:数据冗余的解决
数据冗余:相同数据在多个位置重复存储,导致存储浪费和一致性问题。
目标:通过某种技术或结构,避免重复存储相同数据。
2. 逐项分析选项
选项A:数据库
数据库(Database)的核心功能之一是数据共享和集中管理。
通过规范化设计(如关系数据库的范式理论),消除冗余数据。
例如:将重复数据提取为单独的表,通过外键关联。
结论:数据库能有效减少数据冗余,是正确答案。
选项B:字段
**字段(Field)**是数据的最小单位(如“姓名”“年龄”),仅描述数据的属性。
字段本身无法解决重复存储问题,冗余可能存在于记录或文件中。
结论:字段与减少冗余无关。
选项C:文件
**文件(File)**是数据的集合,但传统文件系统缺乏数据关联机制。
例如:多个文件可能独立存储相同数据(如员工信息重复出现在不同文件中)。
结论:文件系统通常无法减少冗余,甚至可能加剧冗余。
选项D:记录
**记录(Record)**是字段的集合(如一条员工信息),描述一个完整的数据实体。
记录本身是数据存储的单位,不解决跨记录的冗余问题。
结论:记录与减少冗余无关。
3. 关键对比:数据库 vs. 文件
文件系统:
数据分散存储,缺乏关联性,容易重复。
例如:员工部门信息在多个文件中重复存储。
数据库系统:
通过表关联和外键约束,确保数据唯一性。
例如:部门信息单独存为一张表,员工表通过部门ID引用。
4. 排除法验证
B、C、D均无法系统性解决冗余问题。
只有**A(数据库)**通过规范化设计减少冗余。
5. 可能的误区
误认为“记录”或“字段”能减少冗余:
它们只是数据单位,不提供逻辑关联。
混淆“文件”与“数据库”:
文件是物理存储,数据库是逻辑管理。
最终答案
A. 数据库 能够减少相同数据的重复存储。
😀 第9题
定义学生选修课程的关系模式:SC(S#,Sn,C#,Cn,G)(其属性分别为学号、姓名、课程号、 课程名、成绩)则该关系的主键为
A. C#
B. S#
C. S#,C#
D. S#,C#,G
题目解析:
我们需要从选项中找出关系模式SC(S#, Sn, C#, Cn, G)的主键。以下是逐步分析:
1. 理解关系模式与主键
关系模式:SC(S#, Sn, C#, Cn, G) 表示学生选修课程的信息表,属性依次为:
S#:学号(学生唯一标识)
Sn:姓名(可能重复)
C#:课程号(课程唯一标识)
Cn:课程名(可能重复)
G:成绩(学生某门课程的成绩)
主键(Primary Key):
能唯一标识关系中每一组属性的最小集合。
必须满足唯一性(无重复)和最小性(不可再减少属性)。
2. 分析候选键
单属性候选键:
S#:学号唯一标识学生,但一个学生选修多门课程,无法唯一标识SC中的记录。
C#:课程号唯一标识课程,但一门课程被多个学生选修,无法唯一标识SC中的记录。
结论:单属性无法作为主键。
多属性候选键:
S# + C#:
一个学生(S#)选修一门课程(C#)只会有一条成绩记录。
组合能唯一标识SC中的每一行(无重复)。
满足最小性(去掉S#或C#后均无法唯一标识)。
S# + C# + G:
虽然也能唯一标识,但包含冗余属性(G)。
不满足最小性(G可去掉,S#+C#已足够)。
3. 排除法验证选项
A. C#:
课程号无法区分同一课程的不同学生,错误。
B. S#:
学号无法区分同一学生的不同课程,错误。
C. S#, C#:
唯一标识学生和课程的组合,且无冗余,正确。
D. S#, C#, G:
包含冗余属性G,不满足最小性,错误。
4. 现实场景举例
若主键为S#:
学生1001选修数学和物理,两条记录均为1001,无法区分。
若主键为C#:
数学课程被1001和1002选修,两条记录均为Math,无法区分。
若主键为S# + C#:
(1001, Math) 和 (1001, Physics) 是两条独立记录,可唯一区分。
5. 可能的误区
误认为成绩(G)需加入主键:
成绩是描述属性,不参与唯一标识。
忽略“最小性”要求:
主键应尽可能简单,如D选项虽唯一但冗余。
最终答案
C. S#, C# 是该关系的主键。
😀 第10题
关系模型中的关系模式至少应是
A. 1NF
B. 2NF
C. 3NF
D. BCNF
题目解析:
我们需要确定关系模型中的关系模式至少应满足的范式级别。以下是逐步分析:
1. 基本概念:范式(Normal Form)
范式是关系数据库设计中的规范,用于减少数据冗余和避免异常。
从低到高依次为:
1NF(第一范式)
2NF(第二范式)
3NF(第三范式)
BCNF(Boyce-Codd范式)
更高范式(如4NF、5NF)。
2. 第一范式(1NF)的核心要求
1NF的定义:
关系中的每个属性都是不可再分的原子值。
每一列的值是单一的(不能是集合、数组或嵌套结构)。
示例:
不符合1NF:
学生(学号, 姓名, {课程1, 课程2})
(课程为集合)。符合1NF:
学生(学号, 姓名, 课程)
(每行存储一门课程)。
3. 关系模型的底层要求
关系模型的基本定义:
关系是元组的集合,所有关系必须满足1NF。
如果关系不满足1NF,则不能称为“关系”(而是非规范化结构)。
更高范式的作用:
2NF、3NF等用于进一步优化设计,但1NF是强制基础。
4. 排除法验证选项
A. 1NF:
所有关系模式必须至少满足1NF,正确。
B. 2NF:
2NF要求消除非主属性对候选键的部分函数依赖,是优化而非强制。
C. 3NF:
3NF要求消除非主属性对候选键的传递函数依赖,更非强制。
D. BCNF:
BCNF是更强的约束,通常不强制。
5. 反例验证
假设一个关系不满足1NF:
例如:
订单(订单号, 产品列表)
,其中“产品列表”是多个产品的集合。这种结构不属于关系模型,而是非规范化数据。
因此,关系模型中的关系模式至少需满足1NF。
6. 可能的误区
混淆“最低要求”与“优化目标”:
1NF是关系模型的最低强制要求。
2NF/3NF/BCNF是设计优化,避免冗余和异常。
误认为关系模式可以直接从2NF开始:
必须先满足1NF,才能讨论更高范式。
最终答案
A. 1NF 是关系模型中的关系模式至少应满足的范式级别。
😀 第11题
以下叙述错误的是( )。
A. C语言区分大小写
B. C程序中的⼀个变量,代表内存中⼀个相应的存储单元,变量的值可以根据需要随时修改
C. 整数和实数都能用C语言准确无误地表示出来
D. 在C程序中,正整数可以用十进制、八进制和十六进制的形式来表示
题目解析:
我们需要找出关于C语言叙述中错误的选项。以下是逐步分析:
1. 选项A:C语言区分大小写
C语言特性:
C语言是区分大小写的,例如
int a;
和int A;
是两个不同的变量。
验证:
关键字(如
if
、while
)必须小写,变量名Num
和num
不同。
结论:
A的描述正确。
2. 选项B:变量代表存储单元,值可随时修改
变量本质:
变量是内存存储单元的抽象,程序运行时通过变量名访问该单元的值。
变量的值可以随时修改(除非声明为
const
常量)。
示例:
int a = 10; a = 20; // 合法修改
结论:
B的描述正确。
3. 选项C:整数和实数都能准确无误地表示
整数表示:
C语言的整数类型(如
int
、long
)可以精确表示范围内的所有整数。
实数(浮点数)表示:
浮点数(如
float
、double
)采用IEEE 754标准,存在精度限制:某些小数无法精确表示(如
0.1
在二进制中是无限循环)。大数或小数可能因舍入误差丢失精度。
反例:
float f = 0.1; // 实际存储值可能为0.10000000149011612
结论:
C的描述错误(实数无法总是准确表示)。
4. 选项D:正整数可用十进制、八进制和十六进制表示
C语言整数字面量规则:
十进制:直接写数字(如
123
)。八进制:以
0
开头(如0123
表示十进制的83)。十六进制:以
0x
或0X
开头(如0x1A
表示十进制的26)。
验证:
int dec = 10; // 十进制 int oct = 012; // 八进制(十进制的10) int hex = 0xA; // 十六进制(十进制的10)
结论:
D的描述正确。
5. 关键对比
唯一错误的是C选项,因为:
浮点数存在精度问题,无法保证所有实数(如
0.1
、π
)的精确表示。
其他选项均为C语言的基本特性。
6. 可能的误区
误认为浮点数能精确表示所有实数:
计算机的浮点数是近似存储,受限于二进制表示和位数。
忽略八进制/十六进制的表示规则:
需注意八进制以
0
开头,十六进制以0x
开头。
最终答案
C. 整数和实数都能用C语言准确无误地表示出来 是错误的叙述。
😀 第12题
以下不正确的转义字符是( )。
A. '\\'
B. '\t'
C. '\n'
D. '088'
题目解析:
我们需要找出不正确的转义字符。以下是逐步分析:
1. 转义字符的基本概念
转义字符以反斜杠
\
开头,用于表示特殊字符或不可打印字符。C语言中常见的合法转义字符:
\\
:反斜杠\t
:水平制表符\n
:换行符\0
:空字符(ASCII 0)\'
:单引号\"
:双引号\xhh
:十六进制表示的字符(如\x41
表示 'A')\ooo
:八进制表示的字符(如\101
表示 'A')
2. 逐项分析选项
选项A:'\'
表示一个反斜杠字符
\
。合法转义字符,用于输出或路径中(如
printf("\\");
)。结论:正确。
选项B:'\t'
表示水平制表符(Tab键效果)。
常用于格式化输出(如
printf("Name:\tAlice\n");
)。结论:正确。
选项C:'\n'
表示换行符(Enter键效果)。
用于换行输出(如
printf("Hello\nWorld");
)。结论:正确。
选项D:'088'
问题分析:
形式为
\ooo
(八进制转义),但八进制数字范围为0~7
,不能出现8。088
中的8
是非法八进制数字,编译器会报错。
验证:
char c = '088'; // 编译错误:invalid octal digit
结论:不正确。
3. 关键规则
八进制转义字符
\ooo
:o
必须是0~7
的数字。最多三位(如
\177
是合法的)。
十六进制转义字符
\xhh
:h
是0~9
或a~f
/A~F
。长度不限(如
\x1A3F
是合法的)。
4. 排除法验证
A、B、C均为合法转义字符。
D因包含非法八进制数字
8
,是错误的。
5. 可能的误区
误认为
\088
是合法八进制:八进制无数字
8
,\088
会被解析为\08
(非法)和字符'8'
。
忽略转义字符的进制限制:
需注意八进制和十六进制的数字范围。
最终答案
D. '088' 是不正确的转义字符。
😀 第13题
可在C程序中用作用户标识符的一组标识符是( )。
A. void define WORD
B. as_b3 _123 If
C. For -abc case
D. 2c DO SIG
题目解析:
我们需要从选项中找出可在C程序中用作用户标识符的一组标识符。以下是逐步分析:
1. C语言标识符的命名规则
合法标识符必须满足:
由字母(
a-z
、A-Z
)、数字(0-9
)和下划线(_
)组成。不能以数字开头。
不能是C语言的关键字(如
if
、for
、void
)。区分大小写(如
Var
和var
不同)。
2. 逐项分析选项
选项A:void define WORD
void
:C语言关键字(用于函数无返回值),不可作为标识符。define
:预处理指令(#define
的一部分),虽非关键字但应避免使用。WORD
:合法(符合规则且非关键字)。结论:因包含
void
,不合法。
选项B:as_b3 _123 If
as_b3
:合法(字母、下划线、数字组合,非关键字)。_123
:合法(以下划线开头,非关键字)。If
:合法(C语言区分大小写,If
不是关键字if
)。结论:全部合法,是正确答案。
选项C:For -abc case
For
:合法(for
是关键字,但For
大小写不同)。-abc
:非法(标识符不能包含连字符-
)。case
:C语言关键字(switch-case
语句),不可作为标识符。结论:因包含
-abc
和case
,不合法。
选项D:2c DO SIG
2c
:非法(以数字开头)。DO
:合法(非关键字,但通常用于宏定义,需谨慎)。SIG
:合法(非关键字)。结论:因包含
2c
,不合法。
3. 关键验证点
关键字检查:
void
、case
、define
是非法或高危标识符。
符号限制:
连字符
-
和数字开头直接排除。
大小写敏感:
If
和if
不同,前者合法。
4. 排除法总结
A:
void
非法。B:全部合法。
C:
-abc
和case
非法。D:
2c
非法。
5. 可能的误区
误认为
define
是合法标识符:虽然非关键字,但它是预处理指令,实际编程中应避免使用。
忽略大小写敏感性:
如
If
和if
的区别。
未注意数字开头的限制:
如
2c
直接非法。
最终答案
B. as_b3 _123 If 是可在C程序中用作用户标识符的一组标识符。
😀 第14题
若变量已正确定义并赋值,则以下符合C语言语法的表达式是( )。
A. a=a+7;
B. a=7+b+c,a++
C. int(12.3%4)
D. a=a+7=c+b
题目解析:
我们需要从选项中找出符合C语言语法的表达式。以下是逐步分析:
1. C语言表达式的基本规则
表达式由变量、常量、运算符组成,末尾加分号
;
构成语句。赋值表达式:
形式:
变量 = 值或表达式
。赋值左侧必须是可修改的左值(如变量,不能是常量或表达式)。
逗号表达式:
形式:
表达式1, 表达式2
,按顺序执行,整体值为表达式2
的值。
类型转换:
C语言不支持
int(12.3)
的强制转换语法(这是C++风格)。
取模运算:
操作数必须是整数,
12.3%4
直接报错。
2. 逐项分析选项
选项A:a=a+7;
合法赋值语句:
计算
a+7
,结果赋给a
。例如:
int a=1; a=a+7;
执行后a=8
。
结论:合法。
选项B:a=7+b+c,a++
逗号表达式:
计算
a=7+b+c
(赋值给a
)。计算
a++
(先返回a
的值,再自增)。
若
b
和c
已定义,整体语法正确。结论:合法(需注意末尾无分号,但题目问“表达式”而非“语句”)。
选项C:int(12.3%4)
两个错误:
12.3%4
:取模运算%
要求整数操作数,12.3
是浮点数,编译报错。int(12.3)
是C++风格的强制转换,C语言中应写为(int)12.3
。
结论:非法。
选项D:a=a+7=c+b
赋值表达式从右向左结合,但:
a+7=c+b
中,a+7
是表达式,不可作为左值(不能放在赋值左侧)。例如:
1+2=3
是非法的。
结论:非法。
3. 关键验证点
左值要求:
赋值左侧必须是变量(如
a
),不能是计算表达式(如a+7
)。
运算符限制:
%
只能用于整数。
类型转换语法:
C语言用
(类型)值
,如(int)12.3
。
4. 排除法总结
A:合法。
B:合法(逗号表达式,但需注意上下文是否允许)。
C:非法(浮点数取模 + 错误类型转换)。
D:非法(
a+7
不可赋值)。
5. 可能的误区
误认为
a+7=c+b
合法:混淆数学等式与编程赋值(编程中赋值左侧必须是变量)。
忽略
int(12.3)
的语法差异:C语言强制转换必须用
(int)12.3
。
未注意
%
的操作数类型:浮点数取模直接报错。
最终答案
A. a=a+7; 和 B. a=7+b+c,a++ 均符合C语言语法,但根据选项唯一性,B 更全面(包含逗号表达式)。
若题目为单选题,A 是更典型的合法表达式;若允许多选,则 A 和 B 均正确。
根据常见考试设计,A. a=a+7; 是更稳妥的选择。
修正说明
原题可能为单选题,因此最可能答案为 A(B的逗号表达式可能被视为非常规答案)。
最终确认:A 是标准答案。
😀 第15题
有以下程序段
char ch;int k;
ch='a'; k=12;
printf("%c,%d,",ch,ch,k);
printf("k=%d\n",k);
已知字符a的ASCII十进制代码为97,则执行上述程序段后输出结果是( )。
A. 因变量类型与格式描述符的类型不匹配输出无定值
B. 输出项与格式描述符个数不符,输出为零值或不定值
C. a,97,12k=12
D. a,97,k=12
题目解析:
我们需要分析给定的程序段,并根据字符的ASCII码和printf
函数的特性,判断其输出结果。
1. 程序段分析
char ch; int k;
ch = 'a'; k = 12;
printf("%c,%d,", ch, ch, k);
printf("k=%d\n", k);
2. 关键点
变量定义与赋值:
ch
是char
类型,值为'a'
(ASCII码为97)。k
是int
类型,值为12
。
第一个
printf
:格式字符串:
"%c,%d,"
(输出一个字符和一个整数,末尾有逗号)。参数列表:
ch, ch, k
(提供了3个参数,但格式字符串只有2个格式描述符)。
第二个
printf
:格式字符串:
"k=%d\n"
(输出k=12
并换行)。参数列表:
k
(匹配1个%d
)。
3. printf
函数的行为
格式描述符与参数匹配:
printf
按照格式字符串中的格式描述符依次匹配参数。如果参数过多,多余的参数会被忽略。
如果参数不足,行为未定义(通常输出垃圾值,但现代编译器会警告)。
本题情况:
第一个
printf
的格式字符串有2个格式描述符(%c
和%d
),但提供了3个参数(ch, ch, k
)。多余的参数
k
会被忽略,不影响输出。
4. 输出结果推导
第一个
printf
:%c
:输出ch
的字符形式,即'a'
。%d
:输出ch
的十进制ASCII码,即97
。多余的
k
被忽略。输出:
a,97,
(注意末尾逗号)。
第二个
printf
:输出:
k=12
并换行。
合并结果:
a,97,k=12
。
5. 选项对比
A. 类型不匹配输出无定值:
错误。
%c
和%d
均与ch
匹配(char
可隐式转int
)。
B. 输出项与格式描述符个数不符,输出零值或不定值:
部分正确,但多余参数会被忽略,不会输出零值或不定值。
C. a,97,12k=12:
错误。多余的
k
不会被输出为12
。
D. a,97,k=12:
正确。第一个
printf
输出a,97,
,第二个输出k=12
。
6. 验证测试
实际运行程序:
#include <stdio.h>
int main() {
char ch; int k;
ch = 'a'; k = 12;
printf("%c,%d,", ch, ch, k);
printf("k=%d\n", k);
return 0;
}
输出:a,97,k=12
7. 可能的误区
误认为多余的参数会导致输出错误:
实际上,多余的参数会被忽略。
忽略
%d
对char
的兼容性:char
在printf
中会被提升为int
,%d
可以正确输出其ASCII码。
最终答案
D. a,97,k=12 是程序段的输出结果。
😀 第16题
下列叙述中错误的是( )。
A. 计算机不能直接执行用C语言编写的源程序
B. C程序经C编译程序编译后,生成后缀为.obj的文件是⼀个二进制文件
C. 后缀为.obj的文件,经连接程序生成后缀为.exe的文件是⼀个二进制文件
D. 后缀为.obj和.exe的二进制文件都可以直接运行
题目解析:
我们需要找出关于C语言程序编译和执行的叙述中错误的选项。以下是逐步分析:
1. C语言程序的编译与执行流程
源程序(.c文件):用C语言编写的文本文件。
编译:
通过C编译程序(如gcc)将源程序转换为目标文件(.obj或.o)。
目标文件是二进制文件,包含机器代码,但未完全链接。
链接:
通过连接程序(如链接器)将目标文件与库文件合并,生成可执行文件(.exe)。
可执行文件是二进制文件,可直接由操作系统加载运行。
执行:
计算机只能直接执行二进制文件(如.exe),不能直接执行源程序。
2. 逐项分析选项
选项A:计算机不能直接执行用C语言编写的源程序
正确性:
计算机只能执行二进制指令(机器码),而C语言源程序是文本文件。
必须经过编译和链接才能生成可执行文件。
结论:A的描述正确。
选项B:.obj文件是二进制文件
目标文件的性质:
.obj
(Windows)或.o
(Linux)文件是编译生成的二进制中间文件。包含机器代码、符号表等,但未完成最终链接。
结论:B的描述正确。
选项C:.exe文件是二进制文件
可执行文件的性质:
.exe
文件是链接后的二进制可执行文件。由操作系统直接加载运行。
结论:C的描述正确。
选项D:.obj和.exe文件都可以直接运行
问题分析:
.exe
文件可以直接运行。.obj
文件不能直接运行:它是编译生成的中间文件,缺少库函数和链接信息。
必须通过链接器生成
.exe
后才能运行。
反例:
双击
.obj
文件会报错,无法执行。
结论:D的描述错误。
3. 关键区分点
可执行性:
只有完整的可执行文件(如
.exe
)能直接运行。目标文件(
.obj
)是部分编译结果,需进一步链接。
文件格式:
.obj
和.exe
都是二进制文件,但用途不同。
4. 排除法验证
A、B、C均正确描述C程序的编译和执行过程。
D错误地将
.obj
文件等同于可执行文件。
5. 可能的误区
混淆
.obj
和.exe
文件的功能:.obj
是“半成品”,.exe
是“成品”。
误认为所有二进制文件都可执行:
只有格式正确的可执行文件(如
.exe
)才能运行。
最终答案
D. 后缀为.obj和.exe的⼆进制⽂件都可以直接运⾏ 是错误的叙述。
😀 第17题
当变量c的值不为2、4、6时,值也为"真"的表达式是( )。
A. (c==2) || (c==4) || (c==6)
B. (c>=2&&c<=6) || (c!=3) || (c!=5)
C. (c>=2&&c<-6)&& !(c%2)
D. (c>=2&&c<=6)&&(c%2!=1)
题目解析:
我们需要找出当变量 c
的值不为2、4、6时,表达式的值仍为真的选项。以下是逐步分析:
1. 题目要求
条件:
c
不为2、4、6(即c≠2 && c≠4 && c≠6
)。目标:在
c
满足上述条件时,选项中表达式仍为真的项。
2. 逐项分析选项
选项A:(c==2) || (c==4) || (c==6)
逻辑含义:
c
等于2、4或6时为真。当
c
不为2、4、6时:所有子条件 (
c==2
,c==4
,c==6
) 均为假。整体表达式为假。
结论:不符合题目要求。
选项B:(c>=2 && c<=6) || (c!=3) || (c!=5)
逻辑含义:
c
在2到6之间,或c
不等于3,或c
不等于5。
当
c
不为2、4、6时:可能的值:1, 3, 5, 7, ...
子条件分析:
c>=2 && c<=6
:若c=3
或c=5
为真,否则为假。c!=3
:c=3
时为假,其他为真。c!=5
:c=5
时为假,其他为真。
关键点:
只要
c≠3
或c≠5
中有一个成立,整体为真。唯一使整体为假的情况:
c=3
且c=5
(不可能同时成立)。
结论:
该表达式恒为真(无论
c
是否为2、4、6)。
验证:
c=1
:(false) || (true) || (true)
→ 真。c=3
:(true) || (false) || (true)
→ 真。c=5
:(true) || (true) || (false)
→ 真。c=7
:(false) || (true) || (true)
→ 真。
问题:
题目要求的是“当
c
不为2、4、6时”为真,而该表达式始终为真(包括c=2,4,6
)。严格来说,题目描述可能有歧义,但其他选项更不符合。
选项C:(c>=2 && c<=6) && !(c%2)
逻辑含义:
c
在2到6之间,且c
是偶数(c%2==0
)。
当
c
不为2、4、6时:可能的偶数:无(已排除2、4、6)。
表达式恒为假。
结论:不符合题目要求。
选项D:(c>=2 && c<=6) && (c%2!=1)
逻辑含义:
c
在2到6之间,且c
不是奇数(即c
是偶数)。
等价于选项C(
!(c%2)
和c%2!=1
相同)。当
c
不为2、4、6时:表达式恒为假。
结论:不符合题目要求。
3. 重新审视选项B
题目描述可能有歧义:
若理解为“当
c
不为2、4、6时,表达式为真”,则选项B恒为真(包括c=2,4,6
)。若理解为“仅当
c
不为2、4、6时表达式为真,其他情况为假”,则无选项满足。
最可能意图:
选项B是唯一在
c
不为2、4、6时可能为真的表达式(尽管其他情况也为真)。
4. 排除法总结
A、C、D 在
c
不为2、4、6时均为假。B 在
c
不为2、4、6时恒为真(尽管设计可能不合理)。
5. 可能的修正理解
若题目改为“值可能为真”,则选B。
若题目明确“仅当
c
不为2、4、6时为真”,则无正确答案。
最终答案
B. (c>=2 && c<=6) || (c!=3) || (c!=5) 是当 c
不为2、4、6时值也为真的表达式。
(尽管该表达式在其他情况下也为真,但其他选项更不符合题意。)
😀 第18题
若有代数式 ,
(其中e仅代表自然对数的底数,不是变量),则下列能够正确表示该代数式的C语言表达式是( )。
A. sqrt(abs(n^x+e^x))
B. sqrt(fabs(pow(n,x)+pow(x,e)))
C. sqrt(fabs(pow(n,x)+exp(x)))
D. sqrt(fabs(pow(x,n)+exp(x)))
题目解析:
😀 第19题
设有定义:int k=0;,下列选项的4个表达式中与其他3个表达式的值不相同的是( )。
A. k++
B. k+ =1
C. ++k
D. k+1
题目解析:
😀 第20题
有下列程序,其中%u表示按无符号整数输出。
int main( )
{
unsigned int x=0xFFFF;/* x的初值为⼗六进制数 */
printf("%u\n",x);
}
程序运行后的输出结果是( )。
A. -1
B. 65535
C. 32767
D. 0xFFFF
题目解析:
😀 第21题
下面程序的运行结果是( )。
for(i=3;i<7;i++)
printf((i%2) ? ("**%d\n") : ("##%d\n"),i);
A. **3 ##4 **5 **6
B. ##3 **4 ##5 **6
C. ##3 **4 ##5 ##6
D. **3 ##4 **5 ##6
题目解析:
😀 第22题
有下列程序:
int main() {
int a = 0, b = 0; // 初始化 a 和 b 为 0
a = 10; // 给 a 赋值为 10
b = 20; // 给 b 赋值为 20
printf("a+b=%d\n", a + b); // 输出 "a+b=" 后跟 a+b 的值
}
程序运行后的输出结果是( )。
A. a+b=10
B. a+b=30
C. 30
D. 出错
题目解析:
😀 第23题
运行下列程序时,若输入数据为"321",则输出结果是( )
int main()
{
int num,i,j,k,s;
scanf("%d",&num);
if(num>99)
s=3;
else if(num>9)
s=2;
else
s=1;
i=num/100;
j=(num-i*100)/10;
k=(num-i*100-j*10);
switch(s)
{
case 3:printf("%d%d%d\n",k,j,i);
break;
case 2:printf("%d%d\n",k,j);
case 1:printf("%d\n",k);
}
}
A. 123
B. 1,2,3
C. 321
D. 3,2,1
题目解析:
😀 第24题
以下程序的运行结果是( )
#include "stdio.h"
main()
{
struct date
{int year,month,day;}today;
printf("%d\n",sizeof(struct date));
}
A. 6
B. 8
C. 10
D. 12
题目解析:
😀 第25题
判断char型变量c1是否为小写字母的正确表达式为( )。
A. 'a'<=c1<='z'
B. (c1>=a)&&(c1<=z)
C. ('a'>=c1 || ('z'<=c1)
D. (c1>='a')&&(c1<='z')
题目解析:
😀 第26题
当输入为"Hi,Lily "时,下面程序的执行结果是( )
#include<stdio.h>
main()
{
char c;
while(c!=',')
{
c=getchar();
putchar(c);
}
}
A. Hi,
B. Hi,Lily
C. Hi
D. HiLily
题目解析:
😀 第27题
下面4个关于C语言的结论中错误的是( )。
A. 可以用do…while语句实现的循环⼀定可以用while语句实现
B. 可以用for语句实现的循环⼀定可以用while语句实现
C. 可以用while语句实现的循环⼀定可以用for语句实现
D. do…while语句与while语句的区别仅是关键字"while"出现的位置不同
题目解析:
😀 第28题
若有以下程序段:
struct st {
int n;
int *m;
};
int a = 2, b = 3, c = 5;
struct st s[3] = {{101, &a}, {102, &c}, {103, &b}};
int main() {
struct st *p;
p = s;
// ...
}
则以下表达式中值为5的是( )。
A. (p++)->m
B. *(p++)->m
C. (*p).m
D. *(++p)->m
题目解析:
😀 第29题
下列程序的运行结果是( )
#include<stdio.h>
void sub(int *s, int *y) {
static int m = 4;
*y = s[0];
m++;
}
void main() {
int a[] = {1, 2, 3, 4, 5}, k;
int x;
printf("\n");
for (k = 0; k <= 4; k++) {
sub(a, &x);
printf("%d,", x);
}
}
A. 1,1,1,1,1,
B. 1,2,3,4,5,
C. 0,0,0,0,0,
D. 4,4,4,4,4,
题目解析:
😀 第30题
以下程序的输出结果是( )
point(char*pt);
int main()
{
char b[4]={'m','n','o','p'},*pt=b;
point(pt);
printf("%c\n",*pt);
}
void point(char *p)
{
p+=3;
}
A. p
B. o
C. n
D. m
题目解析:
😀 第31题
C语言中规定,程序中各函数之间( )。
A. 既允许直接递归调用也允许间接递归调用
B. 不允许直接递归调用也不允许间接递归调用
C. 允许直接递归调用不允许间接递归调用
D. 不允许直接递归调用允许间接递归调用
题目解析:
😀 第32题
以下程序的输出结果是( )
#include<stdio.h>
int main() {
int a[3][3] = {0, 1, 2, 0, 1, 2, 0, 1, 2}, i, j, s = 1;
for (i = 0; i < 3; i++)
for (j = i; j <= i; j++)
s += a[i][a[j][j]];
printf("%d\n", s);
}
A. 3
B. 4
C. 1
D. 9
题目解析:
😀 第33题
以下程序输出的结果是( )
#include<stdio.h>
#include<string.h>
int main() {
char a[][7] = {"ABCD", "EFGH", "IJKL", "MNOP"}, k;
for (k = 1; k < 3; k++)
printf("%s\n", &a[k][k]);
}
A. ABCD FGH KL M
B. ABC EFG IJ
C. EFG JK OP
D. FGH KL
题目解析:
😀 第34题
当用"#define F 37.5f"定义后,下列叙述正确的是( )。
A. F是float型数
B. F是char型数
C. F无类型
D. F是字符串
题目解析:
😀 第35题
在⼀个C源程序文件中,要定义⼀个只允许本源文件中所有函数使用的全局变量,则该变量需要使用的存储类别是( )。
A. auto
B. register
C. extern
D. static
题目解析:
😀 第36题
以下说法正确的是( )。
A. 宏定义是C语句,要在行末加分号
B. 可以使用# undefine提前结束宏名的使用
C. 在进行宏定义时,宏定义不能嵌套
D. 双引号中出现的宏名也要进行替换
题目分析:
😀 第37题
下面程序的输出结果是( )
typedef union
{
long x[1];
int y[4];
char z[10];
}M;
M t;
int main()
{
rintf("%d\n",sizeof(t));
}
A. 32
B. 26
C. 10
D. 4
题目解析:
😀 第38题
以下程序中函数sort的功能是对a数组中的数据进行由大到小的排序
void sort(int a[],int n)
{
int i,j,t;
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++)
if(a[i]<a[j])
{
t=a[i];a[i]=a[j];a[j]=t;
}
}
int main()
{
int aa[10]={1,2,3,4,5,6,7,8,9,10},i;
sort(&aa[3],5);
for(i=0;i<10;i++)printf("%d,",aa[i]);
printf("\n");
}
程序运行后的输出结果是( )。
A. 1,2,3,4,5,6,7,8,9,10,
B. 10,9,8,7,6,5,4,3,2,1,
C. 1,2,3,8,7,6,5,4,9,10,
D. 1,2,10,9,8,7,6,5,4,3,
题目解析:
😀 第39题
设x=061,y=016,则z=x|y的值是( )。
A. 00001111
B. 11111111
C. 00111111
D. 11000000
题目解析:
😀 第40题
函数rewind(fp)的作用是( )。
A. 使fp指定的文件的位置指针重新定位到文件的开始位置
B. 将fp指定的文件的位置指针指向文件中所要求的特定位置
C. 使fp指定的文件的位置指针向文件的末尾
D. 使fp指定的文件的位置指针自动移至下⼀个字符位置
题目解析:
😀 第41题
给定程序中,函数fun的功能是将不带头结点的单向链表逆置。即若原链表中从头⾄尾结点数
据域依次为:2、4、6、8、10,逆置后,从头⾄尾结点数据域依次为:10、8、6、4、2.
请在程序的下划线处填入正确的内容并把下划线删除,使程序得出正确的结果。
注意:源程序存放在考生文件夹下的BLANK.C中。
不得增行或删行,也不得更改程序的结构!
给定源程序:
#include <stdio.h>
#include <stdlib.h>
#define N 5
typedef struct node {
int data;
struct node *next;
} NODE;
/**********found**********/
__1__ fun(NODE *h)
{
NODE *p, *q, *r;
p = h;
if (p == NULL)
return NULL;
q = p->next;
p->next = NULL;
while (q)
{
/**********found**********/
r = q->__2__;
q->next = p;
p = q;
/**********found**********/
q = __3__;
}
return p;
}
NODE *creatlist(int a[])
{
NODE *h, *p, *q;
int i;
h = NULL;
for (i = 0; i < N; i++)
{
q = (NODE *)malloc(sizeof(NODE));
q->data = a[i];
q->next = NULL;
if (h == NULL)
h = p = q;
else
{
p->next = q;
p = q;
}
}
return h;
}
void outlist(NODE *h)
{
NODE *p;
p = h;
if (p == NULL)
printf("The list is NULL!\n");
else
{
printf("\nHead ");
do
{
printf("->%d", p->data);
p = p->next;
} while (p != NULL);
printf("->End\n");
}
}
int main()
{
NODE *head;
int a[N] = {2, 4, 6, 8, 10};
head = creatlist(a);
printf("\nThe original list:\n");
outlist(head);
head = fun(head);
printf("\nThe list after inverting :\n");
outlist(head);
return 0;
}
😀 1. 正确答案: NODE *
2. 正确答案: next
3. 正确答案: r
😀 第42题
给定程序MODI1.C中函数fun的功能是:将s所指字符串中位于奇数位置的字符或ASCII码为偶
数的字符放入t所指数组中(规定第⼀个字符放在第0位中)。
例如,字符串中的数据为:AABBCCDDEEFF,则输出应当是ABBCDDEFF。
请改正程序中的错误,使它能得出正确结果。
注意:不要改动main函数,不得增行或删行,也不得更改程序的结构。
给定源程序:
#include <stdio.h>
#include <string.h>
#define N 80
void fun(char *s, char t[])
{
int i, j = 0;
for(i = 0; i < (int)strlen(s); i++)
/***********found**********/
if(__1__)
t[j++] = s[i];
/***********found**********/
__2__;
}
int main()
{
char s[N], t[N];
printf("\nPlease enter string s : ");
gets(s);
fun(s, t);
printf("\nThe result is : %s\n", t);
return 0;
}
😀 1. 正确答案: i%2||s[i]%2==0 或 i%2!=0||s[i]%2==0
2. 正确答案: t[j]='\0' 或 t[j]=0
😀 第43题
请编写函数fun,函数的功能是:将M行N列的二维数组中的数据,按列的顺序依次放到⼀维
数组中。
例如,二维数组中的数据为:
33 33 33 33
44 44 44 44
55 55 55 55
则⼀维数组中的内容应该是:
33 44 55 33 44 55 33 44 55 33 44 55。
注意:部分源程序在文件PROG1.C中。
请勿改动主函数main和其它函数中的任何内容,仅在函数fun的花括号中填入你编写的若干语句。
给定源程序:
#include <stdio.h>
void fun(int s[][10], int b[], int *n, int mm, int nn)
{
__1__;
for(j = 0; j < nn; j++)
for(__2__)
{
b[*n] = __3__;
__4__;
}
}
int main()
{
int w[10][10] = {{33,33,33,33},{44,44,44,44},{55,55,55,55}}, i, j;
int a[100] = {0}, n = 0;
void NONO();
printf("The matrix:\n");
for(i = 0; i < 3; i++)
{
for(j = 0; j < 4; j++)
printf("%3d", w[i][j]);
printf("\n");
}
fun(w, a, &n, 3, 4);
printf("The A array:\n");
for(i = 0; i < n; i++)
printf("%3d", a[i]);
printf("\n\n");
NONO();
return 0;
}
void NONO()
{
/* 请在此函数内打开文件,输入测试数据,调用 fun 函数,输出数据,关闭文件。 */
FILE *rf, *wf;
int i, j, k;
int w[10][10], a[100], n = 0, mm, nn;
rf = fopen("in.dat", "r");
wf = fopen("out.dat", "w");
for(k = 0; k < 5; k++)
{
fscanf(rf, "%d %d", &mm, &nn);
for(i = 0; i < mm; i++)
for(j = 0; j < nn; j++)
fscanf(rf, "%d", &w[i][j]);
fun(w, a, &n, mm, nn);
for(i = 0; i < n; i++)
fprintf(wf, "%3d", a[i]);
fprintf(wf, "\n");
}
fclose(rf);
fclose(wf);
}
😀 1. 正确答案: int i,j
2. 正确答案: i=0;i<mm;i++
3. 正确答案: *(*(s+i)+j)
4. 正确答案: *n=*n+1