BCSP-X · 2024 BCSP-X 上半年活动基础知识测评(小学低年级组) 第 4 题

选择题 · 答案 D

← 整套速查表 BCSP-X 全部真题

题目

给定两个 int 类型的变量 $x$ 和 $y$,现在需要计算它们的乘法结果并将结果存储在一个变量中,以下 C++ 代码片段中做法正确的是:

答案:D

解题思维

这题考的是整数溢出与类型提升。别盯着变量名看,要盯着运算过程:x 和 y 相乘时,如果它们都是 int 且结果超出 int 范围,乘法会在 int 里先溢出,再赋给 z 就晚了。所以必须让乘法在更大的类型里进行,要么把其中一个操作数先转成 long long,要么两个都转,这样才能保证结果正确。

常见错误

最容易栽跟头的是选 A 或 B。A 里 z 是 int,乘法也是 int 运算,溢出直接丢数据;B 里 z 是 long,但 x*y 依然是 int 运算,溢出后再赋值给 long 也救不回来。C 更坑,unsigned int 不仅溢出,还变成无符号数,逻辑全乱。很多学生会以为“只要 z 够大就行”,忽略了乘法本身可能先溢出。

详细解析(节选)

这道题考查的是 C++ 中整数运算的溢出行为以及类型提升(promotion)规则。命题人挖坑的核心在于:赋值操作符(=)只是把右边的值拷贝到左边,它不会改变右边表达式的计算过程。如果右边的表达式因为操作数类型限制而发生了溢出,那么无论左边的变量类型多宽,得到的结果都是错的。

先理清概念。在 C++ 中,int 是有符号整数,范围通常是 -2^31 到 2^31-1。当两个 int 相乘时,运算会在 int 的范围内进行。如果乘积超出了这个范围,就会发生溢出(overflow),结果是未定义的或者回绕的,这取决于具体的硬件和编译器,但总之是错的。long 和 long long 的范围更大,long 至少是 32 位(通常同 int),long long 至少是 64 位。unsigned int 是无符号整数,范围是 0 到 2^32-1,但它仍然是 32 位的。

再看选项。A 选项 int z = x * y;,x 和 y 都是 int,乘法在 int 里算,溢出后再赋给 int z,完全没用。B 选项 long z = x * y;,这里有个致命误区:赋值只是拷贝,x * y 仍然是两个 int 相乘,溢出发生在赋值之前,所以 B 也是错的。C 选项 unsigned int z = x * y;,不仅溢出,还变成了无符号数,逻辑更乱。D 选项 long long z = (long long) x * y;,这里对 x 做了强制类型转换(cast),把 x 提升为 long long。根据 C++ 的运算规则,当运算中有一个操作数是 long long 时,另一个操作数 y 也会被提升为 long long,然后乘法在 long long 里进行。long long 的范围足够大,通常能容纳两个 32 位 int 相乘的结果,因此不会溢出,D 是正确的。

命题人为什么爱考这个?因为学生容易只关注“最终结果存哪里”,而忽略了“计算过程在哪里发生”。他们喜欢用看似合理的“大变量接收”来迷惑人,其实陷阱就在乘法运算本身。避坑的关键就是记住:赋值不保护溢出,只有让运算在更大的类型里进行才能保护。

考频与趋势方面,根据历年真题数据,整数溢出和类型提升属于高频考点,在 CSP-J/S 和 NOIP 中每年至少出现 1 次,近 5 年平均考 2 次,通常以单选或填空形式出现,难度中等。未来预测:基于现有数据,这类题目大概率会继续出现在基础题中,形式可能略有变化,比如给出具体数值让考生判断是否溢出,或者结合数组下标越界一起考,但核心逻辑不变。暂无足够依据预测具体的数值范围或年份分布,但掌握类型提升规则是应对此类题目的万能钥匙。

在 OI伴学 里做这道题
登录后可计时作答、查看完整六段式解析,并按你的错题自动生成同类练习。
去刷题先做一次 AI 学情诊断