GESP2026年9月认证C++三级( 第一部分选择题(1~7题)精讲



第1题:原码、反码、补码

题目问:

关于计算机的数据编码,下面说法不正确的是哪一个?

选项:

  • A. 数字 5,不管采用原码、反码、补码,它的 8 位二进制形式都是 (0000 0101)₂

  • B. 计算机科学中,单位换算默认 1KB = 1024B,而非 1000B

  • C. 原码是最直观的一种有符号数表示方法

  • D. 反码运算中,最高位进位要抛掉

答案:D


一、先认识"原码"

计算机表示一个有正有负的整数时,需要解决一个问题:

"这个数字到底是正数还是负数?"

最简单的办法就是:

最高位专门当符号位。

例如 8 位:

复制代码
0 0000101
↑
符号位

最高位:

复制代码
0 → 正数
1 → 负数

所以:

复制代码
+5 = 00000101

-5 的原码:

复制代码
10000101

二、什么是反码?

对于正数:

原码 = 反码 = 补码

例如:

复制代码
+5

原码:00000101
反码:00000101
补码:00000101

但是负数就不一样了。

-5

复制代码
+5:

00000101

把每一位反过来:

复制代码
11111010

这就是 -5 的反码。

然后再加 1:

复制代码
11111010
       +1
--------
11111011

这就是 -5 的补码。


三、A为什么正确?

A说:

数字 5,不管采用原码、反码、补码,它的 8 位二进制形式都是 00000101

因为:

复制代码
5 是正数

所以:

复制代码
原码 = 反码 = 补码

因此 A 正确。


四、B为什么正确?

计算机中传统上:

复制代码
1 KB = 1024 B

所以 B 在本题语境下正确。


五、C为什么正确?

原码非常直观:

复制代码
最高位看正负
后面的位表示数值

所以它确实是比较容易理解的一种有符号数表示方法。


六、D为什么错误?

这是本题真正的陷阱!

题目说:

反码运算中,最高位进位要抛掉。

不对!

反码加法有一个非常特别的规则:

最高位产生进位时,要把这个进位"绕回来",加到最低位。

也叫:

循环进位 / 端回进位

例如:

复制代码
1111
+
0001
----
10000

最高位多出来一个 1

普通情况下可能觉得:

"扔掉!"

但反码运算:

复制代码
0000
+
0001
----
0001

所以:

❌ 最高位进位直接扔掉

✅ 最高位进位要加回最低位

🧠 小学生记忆口诀

反码进位不丢掉,绕一圈回来再加好!



第2题:进制转换

题目问:

关于进制转换,下面说法不正确的是哪一个?

答案:D 。试卷中给出的四个选项涉及 1101B42Q2BEH345Q = 0E3H 等表示。


一、先认识三个常见进制

二进制

只有:

复制代码
0、1

例如:

复制代码
1011

八进制

有:

复制代码
0~7

例如:

复制代码
345Q

其中 Q 表示八进制。


十六进制

有:

复制代码
0~9
A~F

其中:

复制代码
A = 10
B = 11
C = 12
D = 13
E = 14
F = 15

所以:

复制代码
2BEH

实际上是十六进制。


二、A为什么正确?

1101B

这是二进制。

从右往左:

复制代码
1 1 0 1

对应:

复制代码
2³  2²  2¹  2⁰

所以:

复制代码
1×2³ + 1×2² + 0×2¹ + 1×2⁰

= 8 + 4 + 0 + 1

= 13

所以:

复制代码
1101B = 13

正确。


三、B为什么正确?

42Q 是八进制。

复制代码
42Q

就是:

复制代码
4×8¹ + 2×8⁰

所以:

复制代码
4×8 + 2
= 32 + 2
= 34

正确。


四、C为什么正确?

2BEH

是十六进制。

注意:

复制代码
B = 11
E = 14

所以:

复制代码
2BEH

= 2×16² + 11×16¹ + 14×16⁰

计算:

复制代码
2×256 = 512
11×16 = 176
14×1  = 14

因此:

复制代码
512 + 176 + 14
= 702

所以 C 正确。


五、D为什么错误?

这是一个非常适合考试时检查的方法:

八进制 → 二进制

一个八进制数字对应 3位二进制

例如:

复制代码
3 → 011
4 → 100
5 → 101

所以:

复制代码
345Q

转换成二进制:

复制代码
3    4    5
011  100  101

即:

复制代码
011100101

而十六进制:

复制代码
E = 1110
3 = 0011

所以:

复制代码
E3H
=
1110 0011

显然:

复制代码
011100101

复制代码
11100011

不一样。

因此:

345Q ≠ E3H

D 错误。

🧠 三级考试非常重要的口诀

八进制一位管3个二进制位。

十六进制一位管4个二进制位。

这两个口诀一定要熟。



第3题:for循环里的"小陷阱"

题目程序:

复制代码
#include <iostream>
using namespace std;

int main() {
    int x = 1;

    for (int i = 0; i = 0; i <= 5) {
        x++;
    }

    cout << x << endl;

    return 0;
}

答案:A,1。原题程序和选项见试卷。


一、很多同学第一眼会这样想

看到:

复制代码
for (int i = 0; i = 0; i <= 5)

可能会想:

复制代码
i从0开始
i<=5
所以循环6次

但是------

❌ 错了!

因为这里不是:

复制代码
i == 0

而是:

复制代码
i = 0

二、= == 完全不同

这是 C++ 初学者必须牢记的一对兄弟。

=

叫:

赋值

例如:

复制代码
i = 0;

意思:

把 0 放进 i 这个盒子。


==

叫:

判断是否相等

例如:

复制代码
i == 0

意思:

i里面是不是0?


三、那么 i = 0 的结果是什么?

看:

复制代码
i = 0

它做两件事:

第一步:

复制代码
i变成0

第二步:

整个表达式的值就是 0

所以:

复制代码
if (i = 0)

实际上相当于:

复制代码
if (0)

而 C++ 中:

复制代码
0 → 假
非0 → 真

所以循环条件一开始就是:

复制代码

四、循环一次都没有执行

程序:

复制代码
int x = 1;

所以:

复制代码
x = 1

然后进入:

复制代码
for (...)

条件:

复制代码
i = 0

结果:

复制代码
0

即:

复制代码
false

因此:

复制代码
x++;

一次都没有执行。

最后:

复制代码
cout << x;

输出:

复制代码
1

⭐ 考试陷阱

看到:

复制代码
if (a = 0)

不要慌。

一定要问自己:

这里是 = 还是 ==

🧠 口诀

一个等号:往盒子里放东西。

两个等号:检查两个东西是不是一样。



第4题:补码

题目问:

关于计算机编码中补码,下面说法错误的是哪一个?

答案:C。原题四个选项包括正数补码、负数补码、8位补码范围和负数补码的另一种求法。


A:正确

正数的补码:与其原码、反码相同。

例如:

复制代码
+5

原码:00000101
反码:00000101
补码:00000101

所以正确。


B:正确

负数的补码:将对应正数的原码按位取反,然后加1。

例如:

-5

第一步

复制代码
+5 = 00000101

第二步:全部取反

复制代码
11111010

第三步:加1

复制代码
11111010
+       1
---------
11111011

所以:

复制代码
-5的补码 = 11111011

正确。


C:错误

题目说:

8位补码,最大表示数据是128,最小表示数据是-128。

这里最大值错了。

8位补码范围是:

复制代码
-128 ~ 127

而不是:

复制代码
-128 ~ 128

为什么?

8个二进制位一共有:

复制代码
2⁸ = 256

种组合。

补码把它们分配给:

复制代码
-128 ~ 127

一共正好:

复制代码
256个数

D:为什么正确?

还有一种很方便的求负数补码方法:

例如:

复制代码
+5 = 00000101

从右往左:

复制代码
00000101
       ↑

遇到第一个 1 后:

这个1以及右边保持不变,左边全部取反。

于是:

复制代码
00000101

变成:

复制代码
11111011

就是 -5 的补码。

🧠 口诀

求负数补码:右边找到第一个1,1和右边不动,左边全部反。



第5题:神奇的 x & (x - 1)

程序:

复制代码
int x = 2026;
int count = 0;

while (x > 0) {
    count++;
    x = x & (x - 1);
}

cout << count << endl;

答案:B,8

这道题是前7题里非常重要的一题。


一、x & (x-1)到底在干什么?

它有一个非常神奇的作用:

把 x 的二进制中最右边的那个 1 消掉。

例如:

复制代码
x = 12

二进制:

复制代码
1100

那么:

复制代码
x - 1 = 1011

进行 &

复制代码
  1100
& 1011
------
  1000

最右边那个 1

复制代码
1100
  ↑

消失了!


二、那么2026有几个1?

我们把2026拆成二进制:

复制代码
2026
= 1024 + 512 + 256 + 128 + 64 + 32 + 8 + 2

所以:

复制代码
2026
=
11111101010₂

数一数:

复制代码
11111101010
^^^^^^ ^ ^

一共有:

复制代码
8个1

三、程序到底做了什么?

第一次:

复制代码
2026
→ 消掉一个1

第二次:

复制代码
→ 再消掉一个1

......

直到:

复制代码
0

需要多少次?

答案就是:

原来有多少个二进制的 1

2026有8个1。

所以:

复制代码
count = 8

答案:

B


四、这是一条超级重要的算法

以后看到:

复制代码
while (x > 0) {
    x = x & (x - 1);
}

脑袋里应该马上蹦出:

🚨 "它在一个一个消灭二进制中的1!"

因此:

复制代码
int count = 0;

while (x > 0) {
    count++;
    x = x & (x - 1);
}

就是:

统计一个整数二进制中有多少个1。



第6题:位运算判断题

题目问:

关于位运算,下列说法错误的是?

答案:C 。题目四个选项涉及异或找唯一数、左移溢出、带符号整数左移溢出,以及二进制末两位为 00 的倍数关系。

我们逐个看。


A:异或找唯一数------正确

例如:

复制代码
5 7 9 7 5

其中:

复制代码
5出现两次
7出现两次
9出现一次

利用异或:

复制代码
5 ^ 7 ^ 9 ^ 7 ^ 5

异或有一个超级重要的性质:

复制代码
a ^ a = 0

并且:

复制代码
a ^ 0 = a

所以:

复制代码
5 ^ 5 = 0
7 ^ 7 = 0

最后:

复制代码
0 ^ 0 ^ 9 = 9

所以:

A正确。


B:左移可能溢出------正确

例如:

复制代码
int x = 1;
x = x << 30;

不断左移,相当于把二进制中的数字向左搬。

通常情况下:

复制代码
x << 1

可以理解成:

复制代码
x × 2

但是如果已经超过了数据类型能够表示的范围,就可能发生溢出。

所以:

不能无条件认为左移永远等于乘2。

B正确。


C:错误

题目说:

有符号整数左移溢出时结果确定。

这是错误的。

为什么?

因为一旦发生有符号整数溢出,就不能再简单地说:

"结果一定就是某一个固定的数学值。"

考试中看到:

复制代码
"溢出后结果一定......"
"任何情况下都一定......"

这类绝对化表述要特别警惕。

所以:

C错误。


D:为什么正确?

题目说:

一个二进制数最后两位是 00,一定是4的倍数。

例如:

复制代码
1100

最后两位:

复制代码
00

对应:

复制代码
4的倍数

因为二进制最后两位相当于:

复制代码
2¹
2⁰

如果都是0,就没有:

复制代码
2
1

这两个部分。

因此这个数一定能被:

复制代码
4

整除。

例如:

复制代码
100
= 4

1000
= 8

1100
= 12

10000
= 16

最后两位全部是:

复制代码
00

🧠 位运算四兄弟

这道题结束后,小朋友一定要记住:

运算 可以想象成
& 两个人都同意才为1
` `
^ 不一样才为1
~ 全部反过来

其中:

复制代码
a ^ a = 0
a ^ 0 = a

非常重要。



第7题:综合位运算

题目:

复制代码
3 & 7 | 15 ^ ~11

其中:

复制代码
a=3
b=7
c=15
d=11

答案:D,-5

这道题看起来很可怕,其实只要:

先搞清楚优先级,再一步一步算。


一、先记住位运算优先级

这里涉及:

复制代码
&
|
^
~

其中:

复制代码
~ 最高
&
^
|

所以:

复制代码
3 & 7 | 15 ^ ~11

应该理解成:

复制代码
(3 & 7) | (15 ^ (~11))

二、先算 3 & 7

把它们写成二进制:

复制代码
3 = 0011
7 = 0111

进行 &

复制代码
  0011
& 0111
------
  0011

所以:

复制代码
3 & 7 = 3

三、计算 ~11

这里是本题最容易出错的地方。

在 C++ 中,~ 是:

按位取反

对于有符号整数,通常要按照整数的补码形式理解。

例如:

复制代码
11

可以写成:

复制代码
00000000 00000000 00000000 00001011

取反:

复制代码
11111111 11111111 11111111 11110100

这个结果在补码中表示:

复制代码
-12

所以:

复制代码
~11 = -12

还有一个非常好用的公式:

~x = -x - 1

所以:

复制代码
~11
= -11 - 1
= -12

四、计算 15 ^ ~11

因为:

复制代码
~11 = -12

所以:

复制代码
15 ^ (-12)

这里可以利用:

复制代码
~11 = -12

并且:

复制代码
15 = 000...01111
-12 = 111...10100

异或:

复制代码
000...01111
111...10100
-------------
111...11011

这个补码表示:

复制代码
-5

所以:

复制代码
15 ^ ~11 = -5

五、最后别忘了最左边的 |

原式:

复制代码
3 & 7 | 15 ^ ~11

现在:

复制代码
3 & 7 = 3

以及:

复制代码
15 ^ ~11 = -5

所以:

复制代码
3 | (-5)

结果仍然是:

复制代码
-5

因此:

答案 D:-5


为什么 3 | (-5)还是 -5

用补码看:

复制代码
-5 = 11111111 11111111 11111111 11111011

而:

复制代码
3 = 00000000 00000000 00000000 00000011

进行 |

复制代码
11111111 11111111 11111111 11111011
00000000 00000000 00000000 00000011
---------------------------------------
11111111 11111111 11111111 11111011

还是:

复制代码
-5

所以答案:

复制代码
D

🌟 1~7题,知识总结

题号 核心知识 答案
1 原码、反码 D
2 二进制、八进制、十六进制 D
3 ===、for循环 A
4 补码与表示范围 C
5 x & (x-1) B
6 位运算性质、溢出 C
7 `& ^ ~`综合运算

⭐ 最后给大家一张"必背卡"

① 原码、反码、补码

正数:

复制代码
原码 = 反码 = 补码

负数补码:

复制代码
正数原码
→ 全部取反
→ +1

或者:

复制代码
从右往左找到第一个1
这个1和右边不动
左边全部取反

② 8位补码范围

复制代码
-128 ~ 127

千万不要写成:

复制代码
-128 ~ 128

③ 进制转换

复制代码
二进制:0、1

八进制:0~7

十六进制:0~9、A~F

口诀:

八进制一位 = 二进制3位

十六进制一位 = 二进制4位


④ C++中的两个等号兄弟

复制代码
a = b;

是:

赋值

复制代码
a == b

是:

比较是否相等

特别注意:

复制代码
if (x = 0)

条件是:

复制代码

x & (x-1)

看到:

复制代码
x = x & (x - 1);

马上想到:

🪄 消灭二进制中最右边的一个1!

所以:

复制代码
while (x) {
    count++;
    x = x & (x - 1);
}

就是:

数一个整数的二进制里面有多少个1。


⑥ 异或 ^

最重要的两个:

复制代码
a ^ a = 0
a ^ 0 = a

所以:

复制代码
5 ^ 7 ^ 9 ^ 7 ^ 5

重复出现的:

复制代码
5、5
7、7

全部消失,最后留下:

复制代码
9

~

一定要记:

复制代码
~x = -x - 1

例如:

复制代码
~11 = -12
~5  = -6
~0  = -1

相关推荐
小小龙学IT2 小时前
Qt QPainter 2D 绘图系统深度解析:从画笔到渲染引擎适
c++·qt
wabs6662 小时前
关于二叉树【力扣100.相同的树的思考】
数据结构·c++·算法·leetcode·二叉树·递归法
小小龙学IT2 小时前
Boost.PFR 开源结构体字段反射库深度解析
c++·开源
程序猿编码2 小时前
零依赖纯手写:C++ 实现完整神经网络,张量反向传播全打通
c++·神经网络·transformer·大模型推理
码匠许师傅2 小时前
【C++三方组件】utfcpp:UTF-8 字符串处理避坑
c++
蒸蒸yyyyzwd3 小时前
八股学习 MVCC 慢查询优化和 read 过程
c++·八股
APEX真好玩3 小时前
把高频传感器(IMU)数据封装进 MP4:FFmpeg 私有数据轨实践
c++
晴天的雨.9923 小时前
[C++算法]盛最多水的容器(双指针算法)
开发语言·c++·算法
布莱克6053 小时前
理解内存泄漏:成因、发现方法与解决策略(C++ 举例)
c语言·c++·内存泄漏