Онлайн компилятор C

#include <stdio.h> int main() { char s[1001] = {0}; fgets(s, sizeof(s), stdin); int count = 0, i, j; for (i = 0; s[i] != '\0'; i++) { char first; if (s[i] != ' ') { if (i == 0 || s[i - 1] == ' ') { first = s[i]; for (j = i; s[j] != ' '; j++) { if (s[j] == '\0') break; } if (first == s[j - 1] + 32 || first == s[j - 1] - 32) count++; } } } printf("%d", count); return 0; }
这段代码的功能是统计输入字符串中,首字母和尾字母大小写互为转换(即一个是大写,另一个是小写)的单词个数。它遍历每个单词,检查单词的第一个字符和最后一个字符是否相差32(ASCII码中大小写字母的差值)。

- 代码中判断首尾字母是否大小写对应的条件 `first == s[j-1] + 32 || first == s[j-1] - 32` 只考虑了字母大小写差32的情况,但忽略了首尾字母本身可能已经是相同大小写的情况。例如单词 "Hello" 首字母H和尾字母o,H和o的ASCII差不是32,但代码不会错误计数,不过对于 "AbcA" 这种首尾相同字母但大小写不同的情况,条件会正确触发。但更关键的问题是,当单词只有一个字母时,`j-1` 等于 `i`,此时比较的是同一个字符,条件可能错误触发。

- 另外,代码在找到单词结尾时,用 `for (j = i; s[j] != ' '; j++)` 循环,但遇到字符串结束符 `\0` 时只用了 `break` 跳出内层循环,之后 `j` 的值指向了 `\0` 的位置,此时 `s[j-1]` 是最后一个字母,逻辑上正确。但需要注意,如果字符串末尾没有空格,最后一个单词的结尾就是 `\0`,这个处理是可行的。不过,当单词只有一个字符时,`j` 初始等于 `i`,内层循环条件 `s[j] != ' '` 如果该字符不是空格,则 `j` 会自增到下一个位置,导致 `j-1` 指向原字符,但此时比较的是同一个字符,会错误地认为首尾字母大小写不同(因为同一个字符的ASCII差为0,不满足±32),所以不会误判。但若单词只有一个字符且该字符是空格?实际上空格会被外层 `if` 跳过。所以单字符单词不会触发计数,这符合预期吗?题目要求首尾字母,单字符单词首尾相同,不应计数。所以这里没问题。

主要问题在于:代码只检查了首字母与尾字母相差32的情况,但忽略了首字母和尾字母本身可能已经相同(如 "aba" 首尾都是