关于字符串和字符数组,下列说法正确的是( )。
答案C。考点: 数组/字符串的基本操作。
数组下标从0开始,a[n]访问的是第n+1个元素。越界不报编译错但结果不可预测。
【考点】字符数组初始化|sizeof 与 strlen 区别|字符串越界风险
解题思维:看到「sizeof」先反应数组总长度(含 '\0'),「strlen」只到 '\0' 为止。选项 A 看似正确,但命题人把「能够正确执行」和「相等」两个陈述绑在一起,若考生只背结论,会忽略 A 中 len1=len2 是事实,却误以为存在陷阱,反而不敢选。选项 B 的数组长度 4 刚好容纳 4 个字符,字符串常量 "GESP" 末尾 '\0' 会被截断,但 C++ 允许这种初始化,程序能跑,只是 str1 不再是合法字符串。选项 C 是唯一准确描述 strcpy 行为的:strcpy 会按源字符串长度复制,目标数组只有 4 字节,必然越界覆盖堆栈内存。选项 D 的 strcat 同样越界,因为 dest 末尾没有预留 '\0' 位置,且 src 长度远超剩余空间。
陷阱拆解:A 的阴险点在「len1 与 len2 相等」——实际上确实相等,但命题人故意把「能够正确执行」和「相等」合并,让考生怀疑 A 有隐藏错误。B 的陷阱是「固定大小数组能否容纳字符串常量」,多数学生误以为必须严格匹配,但 C++ 允许截断。C 的核心陷阱是 strcpy 不检查边界,这是 C 语言典型漏洞,命题人用「即使能够运行」暗示程序可执行,但强调越界风险,考查对内存安全的理解。D 的错误在于 strcat 同样不检查目标空间,且 dest 已包含 '\0',但 strcat 会从末尾开始复制,导致覆盖 dest 末尾的 '\0' 并继续写入,造成更严重的越界。
反命题思维:如果把 C 改成「char str2[12] = ...」,strcpy 就安全了;或者把 D 的 dest 改成「char dest[20] = ...」,strcat 也不会越界。这类题本质是考「字符串操作函数是否自带长度检查」,命题人总爱用 strcpy/strcat 搭配小数组制造越界。刷到类似题时,先问自己「这个函数会不会自动加 '\0' 或检查长度?」——答案几乎总是「不会」。