GESP 五级 · GESP 202312 C++ 五级 第 22 题

判断题 · 答案 B · 考点:字符数组与字符串处理

← 整套速查表 GESP 五级 全部真题

题目

下面的 C++ 代码能实现十进制正整数 $N$ 转换为八进制并输出。

char s[10];
int main()
{
    int N;
    cin >> N;
    string rst = "";
    while (N != 0)
    {
        s[0] = N % 8 + '0';
        rst += string(s);
        N /= 8;
    }
    cout << rst << endl;
    return 0;
}
答案:B

考点

字符数组与字符串处理 讲解 →字符数组与字符串处理 真题汇总 →

解题思维

这题考的是进制转换算法与字符串构造细节。拿到题先别急着看选项,把代码当黑盒跑一遍:循环里 N%8 取余、加'0'转字符没错,但后面 rst += string(s) 才是命门——它把整个未初始化的数组转字符串,每次循环都塞进一堆随机字符,输出自然乱码。

常见错误

最容易栽跟头的地方就是以为 s[0] 赋值对了就行,忽略了 string(s) 构造函数会把整个数组当字符串处理。另外审题时容易看漏题目问的是“能实现”还是“不能实现”,导致选项选反。

详细解析(节选)

【考点】进制转换|字符串操作|字符数组与字符串构造器

这道题属于 GESP 五级的基础算法与数据类型细节题。五级考查的核心就是那些看似简单、实则容易在细节上翻车的代码片段。命题人放这道题,目的很明确:卡住那些「以为数组局部赋值就能转字符串」的粗心选手。

咱们先拆解一下进制转换的基本逻辑。十进制转八进制,通法是反复取余:N%8 得到当前位的数字,然后除以 8 继续处理高位。得到的余数需要转为字符(加'0'),再拼接到结果字符串里。代码的前半段 s[0] = N % 8 + '0'; 这一步是完全正确的,它确实把当前余数转成了字符存进了数组的第一个位置。

但是,真正的坑在下一行:rst += string(s);。这里用到了 C++ 标准库里的 string 构造函数。这个构造函数在接收一个字符数组时,会尝试将整个数组作为字符串来构造。问题来了:char s[10]; 这个数组只有 s[0] 被我们赋值了,剩下的 s[1] 到 s[9] 都是全局变量区里的随机垃圾值(未初始化)。当你调用 string(s) 时,它会从 s[0] 一直读到数组末尾(或者遇到空字符,但这里没有),把这一串包含随机字符的内容整个塞进了 rst 里。

所以,每次循环,rst 里不仅多了正确的八进制位,还多了一堆乱码。最终输出的结果自然是错误的。题目问的是“下面的 C++ 代码能实现十进制正整数 N 转换为八进制并输出”,既然输出是错的,那答案显然是 B(错误)。

咱们再看看如果 N=0 会怎样。题目明确说了是“十进制正整数”,所以 N 至少是 1,循环一定会执行至少一次。如果 N=0,循环条件 N != 0 不成立,直接输出空行,虽然逻辑上也没错,但题目范围不涉及。

对比一下正确的写法,应该怎么做呢?要么不用数组,直接用 char c = N % 8 + '0'; 然后 rst += c;,这样每次只追加一个字符;要么用数组时只构造单个字符的字符串,比如 char s[1] = {N % 8 + '0'}; 或者 string(1, N % 8 + '0')。命题人若把 s[0] 改成 char c = N%8+'0'; rst += c; 或 char s[1] = {N%8+'0'}; rst += string(s);,代码就正确了。

刷到类似题,先问自己一句:「数组整体转换还是单个字符追加?」这题考的就是这个细节。很多学生背了「进制转换用取余」却不懂数组与字符串构造器的区别,必掉进这坑。

同考点真题

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