2026年9月GESP三级C++真题解析:位运算专项|异或加密、权限掩码与移位陷阱

四季读书网 8 0
2026年9月GESP三级C++真题解析:位运算专项|异或加密、权限掩码与移位陷阱

2026年9月份 GESP 三级 C++真题 位运算专项习题集,精选 4 道高频典型考题,覆盖异或加密、位掩码权限管理、移位运算特性、位运算符功能辨析四大模块。 包含完整原题、代码片段、选项、标准答案;每道题目配有详细题解,结合代码逻辑、二进制推演、逐项对错辨析、运行实例拆解知识点。重点讲解:异或 “两次运算还原数据” 的加密解密原理;位掩码中按位或添加权限、按位取反 + 按位与清除权限的标准写法;正整数右移的适用边界,移位位数超限带来的行为差异;区分&、|、^、>>各自作用与使用场景。

第8题

下面函数是一个加密解密的函数,横线处应该填入的程序段是()。

#include<iostream>#include<string>usingnamespacestd;intmain(){int key;cin >> key;string msg = "Hello GESP";cout << msg << endl;for (int i = 0; i < msg.size(); i++) {        msg[i] = msg[i] ^ key;    }cout << msg << endl;// --------横线位置--------cout << msg << endl;return0;}

A.

for (int i = 0; i < msg.size(); i++) {    msg[i] = msg[i] | key;}

B.

for (int i = 0; i < msg.size(); i++) {    msg[i] = msg[i] >> key;}

C.

for (int i = 0; i < msg.size(); i++) {    msg[i] = msg[i] ^ key;}

D.

for (int i = 0; i < msg.size(); i++) {    msg[i] = msg[i] & key;}

答案:C

详细题解

核心原理:异或^的性质

异或运算有一个非常关键特点:

若 ,那么 同一个数,连续两次和同一个key异或,会还原回原来的值。

  1. 第一次 msg[i] ^ key:加密,原文 → 密文
  2. 再做一次 msg[i] ^ key:解密,密文 → 原文

这就是异或加密的经典原理,加密和解密使用完全相同的操作。

逐项分析

  • A:按位或 |,再执行 ,结果仍然是B,无法还原原始字符,不能解密。

  • B:右移 >>右移运算属于除法类移位,移位之后丢失低位信息,无法恢复原来字符,不能解密。

  • C:按位异或 ^ ✅ 密文 msg[i] ^ key 运算后,变回最初的原始字符,完成解密,正确。

  • D:按位与 &,再执行 ,结果依旧是B,丢失高位信息,无法还原。

程序执行流程演示

  1. 输出原始字符串:Hello GESP
  2. 循环msg[i] ^ key:加密,输出乱码密文
  3. 横线填入同样的异或循环:解密,字符串变回Hello GESP
  4. 再次输出,得到原始文字。

考点小结(GESP位运算经典应用)

异或加密:加密和解密操作完全一样,使用同一个key,两次异或复原。

记忆口诀:异或两次,还原本身。

第10题

下面的程序是位掩码技术实现权限的组合管理。首先定义四个权限常量,分别对应读、写、修改、删除,每个权限占用整数的一个独立二进制位。初始化权限掩码 mask 为 0,代表没有任何权限。如果想实现如下的操作:添加读权限;添加写权限;清除读权限,其他位不变;添加删除权限。 则横线处应该填入的是()。

#include<iostream>usingnamespacestd;intmain(){constint READ = 1 << 0;constint WRITE = 1 << 1;constint MODIFY = 1 << 2;constint DELETE_ = 1 << 3;int mask = 0;// --------横线位置--------return0;}

A.

mask = mask | READ;mask = mask | WRITE;mask = mask & (~READ);mask = mask | DELETE_;

B.

mask = mask & READ;mask = mask & WRITE;mask = mask | (~READ);mask = mask & DELETE_;

C.

mask = mask | READ;mask = mask & WRITE;mask = mask & (~READ);mask = mask | DELETE_;

D.

mask = mask | READ;mask = mask | WRITE;mask = mask | (~READ);mask = mask | DELETE_;

答案:A

详细题解

核心知识点:位掩码权限操作

  1. 添加权限(置1某一位,其他位保持不变):mask = mask | 权限值按位或|,目标位和1做或运算 → 变成1;其余位和0或,保持原样。
  2. 清除权限(置0某一位,其他位保持不变):mask = mask & (~权限值)~权限:把权限对应的那一位变成0,其余所有位变成1。&运算:目标位和0相与 → 清零;其他位和1相与,保持不变。

权限定义:

  • READ = 1 << 0,二进制 0001
  • WRITE = 1 << 1,二进制 0010
  • MODIFY = 1 << 2,二进制 0100
  • DELETE_ = 1 << 3,二进制 1000

题目要求的4步操作

  1. ✅ 添加读权限:mask = mask | READ;
  2. ✅ 添加写权限:mask = mask | WRITE;
  3. ✅ 清除读权限,其他不变:mask = mask & (~READ);
  4. ✅ 添加删除权限:mask = mask | DELETE_;

逐项分析

A

mask = mask | READ;     // 添加读权限 ✔mask = mask | WRITE;    // 添加写权限 ✔mask = mask & (~READ);  // 清除读权限 ✔mask = mask | DELETE_;  // 添加删除权限 ✔

完全匹配题目四个操作,正确。

B

mask = mask & READ;     // &是取交集,不是添加权限mask = mask & WRITE;mask = mask | (~READ);  // |(~READ)会把很多位变成1,不能清除读权限mask = mask & DELETE_;  // &不是添加删除权限

全部操作错误。

C

mask = mask | READ;mask = mask & WRITE;    // &不能添加写权限,错误mask = mask & (~READ);mask = mask | DELETE_;

第二步错误。

D

mask = mask | READ;mask = mask | WRITE;mask = mask | (~READ);  // |(~READ) 不能清除读权限!或运算无法清零位,错误mask = mask | DELETE_;

第三步错误。

过程演示(A选项)

初始 mask = 0,二进制 0000

  1. mask | READ → 0000 | 0001 = 0001(拥有读权限)
  2. mask | WRITE → 0001 | 0010 = 0011(读+写权限)
  3. mask & (~READ) → 0011 & 1110 = 0010(读权限清除,只剩写权限)
  4. mask | DELETE_ → 0010 | 1000 = 1010(写+删除权限)

考点小结(GESP高频)

位掩码权限三板斧:

  • 增加权限:mask |= perm (按位或)
  • 删除权限:mask &= ~perm(按位取反后按位与)
  • 判断是否拥有权限:if(mask & perm)

第11题

下面选项中提到的变量都是正整数,关于位运算,下面说法错误的是()。

A. num >> 1,对于正整数,等价于对 num 做整数除以2,向下取整

B. num | 0x0F,可以把 num 的低4位全部置为 1,高位保持不变

C. num ^ num 的结果一定等于 0

D. 若 num 右移时低位被移出丢弃,结果一定符合除法数学规律

答案:D

详细题解

选项A ✅ 正确

正整数的右移 >>1,就是二进制整体右移一位,低位丢弃,等价于整数除以2、向下取整。

示例:,。

选项B ✅ 正确

0x0F 十六进制,等于二进制 00001111。

按位或 | 的特点:和1或,结果为1;和0或,保持原值。

num | 0x0F:低4位全部和1做或运算 → 低4位强制变成1;高位和0做或运算 → 高位不变。

选项C ✅ 正确

异或^规则:相同为0,不同为1。

num的每一位和自己本身异或,每一位都是相同,所以全部变成0,num ^ num = 0。

选项D ❌ 错误

题干限定num是正整数,正整数在C++中是无符号或者有符号正数,右移是逻辑右移,高位补0。 这句话的陷阱:右移丢弃低位,只在移位位数不超过有效位数时等价除以。一旦移位位数过大(例如移位超过该数字二进制总位数),结果直接变成0,不再满足除法规律。

举例子:char型正整数 num=8(1000),num >> 5。

数学上 ;

移位运算:1000右移5位,全部bit被移出,结果=0。

整数除法向下取整应该得到0.25向下取整是0,这个例子看着一样;换个角度理解核心考点: 移位运算最多把所有bit移出去变成0;而除法是数学运算。

另一个关键点:移位运算符的右移位数不能是负数,同时移位位数大于等于类型的总bit数,属于C++未定义行为,此时移位结果不一定符合除法数学规律。

简单总结:不能无条件说“右移丢弃低位,结果一定符合除法数学规律”,这个“一定”太绝对,所以D说法错误。

考点小结(GESP)

  1. 正整数右移 >>k:等价除以向下取整(移位位数合法的前提下);
  2. |用来置1;&用来清0;^相同为0;
  3. 移位操作有边界限制,移位位数过大时,行为不一定符合数学除法。

抱歉,评论功能暂时关闭!