SLKJ笔试题解析

  1. 括号中的数字应该选择多少(A):0,4,18,(X),100

A.48

B.58

C.50

D.38

解析:

第n项 =n^2 ×(n−1)

  1. int x='f';printf("%c\n",'a'+(x-'a'+1));输出结果是(B

A.j

B.g

C.i

D.h

解析:

x - 'a' = 'f' - 'a' = 5('f'在 ASCII 表中比'a'大 5)

x - 'a' + 1 = 5 + 1 = 6

'a' + 6 = 字符'g'('a'往后数 6 个就是'g')

  1. C语言中,对下面一句声明,叙述正确的是(A

int (*s_calc_func(char op))(int, int);

A.这是一个函数声明,这个函数接收 **op**作为参数,返回一个接收两个 **int**值作为参数,返回int型值的函数的指针

B.这是一个函数声明,这个函数接受两个int值作为参数,返回一个接收char作为参数返回int型值的函数的声明

C.这是一个函数声明,这个函数接收两个int值作为参数,返回一个接收op作为参数返回int型值得函数的声明

D.这是一个不合法的函数声明

解析:

等价写法:

cpp 复制代码
typedef int (*func_t)(int, int);  // func_t 是"指向接收两个int、返回int的函数的指针"
func_t s_calc_func(char op);      // s_calc_func 接收char,返回 func_t

所以 s_calc_func 是一个函数,它接收 char op,返回一个函数指针;该指针指向的函数接收两个 int,返回 int

  1. 某存储器数据总线宽度为32bit,存取周期为250ns,则该存储器的理带宽为:(B

A.8MB/s

B.16MB/s

C.25MB/s

D.32MB/s

解析:

带宽 = 总线宽度(bit)÷ 8 ÷ 存取周期(s)

代入:32 ÷ 8 ÷ (250×10⁻⁹) = 4 ÷ (250×10⁻⁹) = 16×10⁶ B/s = 16 MB/s

  1. 如果一个递归函数最终会结束,那么这个函数一定是(B

A.使用了局部变量

B.有一个分支不调用自身

C.使用了全局变量或者使用了至少一个参数

D.都不对

  1. 关于可重入函数,下面说法错误 的是:(CD

A.可重入函数可以由多个线程并发使用,而不必担心数据错误

B.可重入函数不可以调用任何不可重入函数

C.可重入函数时必需使用互斥手段对临界代码加以保护

D.可重入函数可以调用malloc()或者free()函数

解析:

可重入函数不依赖共享状态,多个线程并发调用不会产生数据错误。

一旦调用了不可重入函数,整个调用链就可能访问共享状态,破坏可重入性。

  1. 下面的C代码作用是反转一维数组。例如当输入为{1,2,3,4,5}时,输出是(5,4,3,2,1}。
cpp 复制代码
int reverse_array(int* list, int len) {
    int* p1 = list, * p2 = list + len - 1;
    int temp;
    if (len <= 0) return -1;
    while (p1 != p2) {
        temp = *p1;
        *p1 = *p2;
        *p2 = temp;
        p1++;
        p2--;
    }
    return 0;
}

当编译并运行上述程序时,会发生什么情况:(C

A.编译错误

B.程序运行正确

C.输入数组长度为奇数时运行正确

D.输入数组长度为偶数时运行正确

E.都不对

解析:

偶数长度时,p1 与 p2 的初始距离为 len-1(奇数),每次循环距离减 2,因此距离永远是奇数,不可能等于 0。

循环条件 p1 != p2 永远成立,最终导致越界访问。

奇数长度时,初始距离为偶数,距离最终会减到 0,循环正常终止。

  1. 单元测试的定义:通过模块(类/方法/函数)测试,使代码达到设计要求主要目的是针对编码过程中可能存在的各种错误,例如用户输入验证过程中的边界值的错误。(A

A.True

B.False

  1. 假设你有8个球,其中一个略微重一些,但是找出这个球的唯一方法是将两个球放在天平上对比。最少要称多少次才能找出这个较重的球?

解析:

第一次称重:把 8 个球分成 3 个、3 个、2 个三组,将两组 3 个球分别放在天平两端。

若天平平衡:较重的球在剩下的 2 个球中。

若天平不平衡:较重的球在下沉的那 3 个球中。

第二次称重:

若在 2 个球中:直接把这两个球放在天平两端,下沉的就是较重的球。

若在 3 个球中:任取其中 2 个放在天平两端,若平衡则剩下的是较重球;若不平衡则下沉的是较重球。

所以,最优策略保证在 至多2次 内找出重球。

若第一次即不平衡,第二次从重的那3个中取2个上称即可确定,共 2 次;

若第一次平衡,第二次直接比较剩余2个,也是 2 次。

10 . Please list some command linux command eg. Show all process, show cpu usage,create new folder, change file attribute.

解析:

Show all process: ps aux

show cpu usage: top

create new folder: mkdir <folder_name>

change file attribute: chmod

11 . Shell 脚本中, $a == $b $a -eq $b 有什么区别?

解析:

$a == $b 是字符串比较,按字面内容判断是否相等;

$a -eq $b 是整数比较,按数值大小判断是否相等,且要求操作数为整数。

12 . Please describe the common technique to avoid a header file being included for multiple times?

解析:

Include guard with #ifndef/#define/#endif (portable, standard method using a unique macro to skip repeated inclusion).

#pragma once (compiler-supported directive to mark the header as "include once", simpler but slightly less portable).

13 . 数组边界溢出会导致什么?怎样防止数组边界溢出?

解析:

数组边界溢出会导致数据损坏、程序崩溃、安全漏洞等问题;

可通过边界检查、使用安全容器 / 函数、控制循环范围、工具检测等方式防止溢出。

14 . Heap与stack的内存分配和空间大小方面的差别?

解析:

内存分配:栈由系统自动分配释放、效率高、连续无碎片;

堆由程序员手动管理、效率较低、易产生碎片。

空间大小:栈空间固定且小;堆空间大且可动态扩展。

15 . What's the difference between physical address and virtual address? Who in charge of translate between physical address and virtual address? Give brief description about the benefit of virtual address, and the general translate process from virtual address to physical address.

解析:

Physical address is the actual RAM address; virtual address is a logical address per process.

Translation is handled by the MMU (hardware) with OS page tables.

Virtual address enables isolation, extended memory, protection, and flexible management.

Translation splits the virtual address into VPN/offset, uses the page table to get PFN, then combines with offset to form the physical address (with page fault handling if needed).

16 . 程序的局部变量存在于()中,动态申请的数据存在于()中。

解析:

栈(stack);堆(heap)

17 . What is problem of the following logic and how to modify it tomake it work correctly?

cpp 复制代码
void allocate_mem(char* str) {
	str = (char*)malloc(100);
}
void test() {
	char *str = NULL;
	allocate_mem(str);
	strcpy(str, "Hello, World");
	printf(str);
}

解析:

偶数长度时,p1 与 p2 的初始距离为 len-1(奇数),每次循环距离减 2,因此距离永远是奇数,不可能等于 0。循环条件 p1 != p2 永远成立,最终导致越界访问。奇数长度时,初始距离为偶数,距离最终会减到 0,循环正常终止。

18 . Implement the following macro to clear a 32 bit register's bit 4, 5 and 6.

cpp 复制代码
#define ClrRegBit456(x) ?
Example:
		ClrRegBit456(REG_A);

To generalize the implementation above, implement the following macro to clear m bits of a 32 bit register's, starting from bit n. (In the above case, m = 3, n=4).

cpp 复制代码
#define ClrRegBitFields(x,m, n)
Example:
        ClrRegBit456(REG_A, 3, 4);

解析:

第一个宏 ClrRegBit456(x)

要清除寄存器的 bit 4、5、6,核心思路是构造一个掩码:这三位为0,其余位为1,再和原寄存器值做按位与操作。

先构造这三位的位模式:0x7(二进制111)左移 4 位,得到0x7 << 4(对应 bit4-6 为1,其余为0)

对该值取反,得到目标掩码:~(0x7 << 4)(bit4-6 为0,其余为1)

用原寄存器值和掩码按位与,即可清除这三位。

cpp 复制代码
#define ClrRegBit456(x) ((x) &= ~(0x7 << 4))

解析:

第二个通用宏 ClrRegBitFields(x, m, n)

要清除从bit n开始的m位,步骤如下:

生成m个连续的1:(1 << (m)) - 1(比如m=3时,结果为0b111)

将这m个1左移n位,移动到目标位置:((1 << (m)) - 1) << (n)

取反得到掩码(目标位为0,其余为1),再和原寄存器值按位与

cpp 复制代码
#define ClrRegBitFields(x, m, n) ((x) &= ~(((1U << (m)) - 1U) << (n)))
相关推荐
Lsland..1 小时前
AI Agent到底是什么
java·人工智能·llm
Halo_tjn1 小时前
JDBC 技术的使用
java·算法
之歆1 小时前
Day23_Bootstrap 前端框架完全指南:从栅格系统到组件化开发
开发语言·前端·javascript·前端框架·bootstrap·ecmascript·less
ps酷教程9 小时前
Jackson 解决没有无参构造函数的反序列化问题
java
NiceCloud喜云9 小时前
Opus 4.8 的 Effort Control 怎么选:Low 到 Max 五档策略
android·java·大数据·前端·c++·python·spring
AI玫瑰助手10 小时前
Python函数:默认参数的定义与注意事项
开发语言·python·信息可视化
油炸自行车10 小时前
Claude Code 错误:API Error: 400 Failed to deserialize the JSON body into the
开发语言·javascript·json·trae·claude code·api error 400
肩上风骋10 小时前
C++14特性
开发语言·c++·c++14特性
_日拱一卒10 小时前
LeetCode:994腐烂的橘子
java·数据结构·算法·leetcode·深度优先