Онлайн компилятор 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 || first == s[j - 1]) count++; } } } printf("%d", count); return 0; }
这段代码的功能是统计输入字符串中,首字母和尾字母相同(忽略大小写)的单词个数。它逐字符遍历字符串,遇到单词开头时记录首字母,然后找到单词结尾,比较首尾字母是否相等(考虑大小写差异)。

- 代码中判断单词结尾的方式可能有问题。当单词后面紧跟空格时,`s[j] != ' '` 循环会在遇到空格时停止,此时 `j` 指向空格,`s[j-1]` 是单词最后一个字母,这是正确的。但如果单词是字符串的最后一个词,后面没有空格,循环会一直走到字符串末尾的 `'\0'`,此时 `j` 指向 `'\0'`,`s[j-1]` 仍然是最后一个字母,看起来也正确。但注意循环内部有一个 `if (s[j] == '\0') break;`,这个 break 是在检查 `s[j]` 是否为 `'\0'` 后立即跳出,此时 `j` 没有递增,所以 `s[j-1]` 仍然是最后一个字母,逻辑上似乎没问题。不过更简洁的方式是直接让循环条件包含 `'\0'` 的判断。

- 比较首尾字母时,使用了 `first == s[j-1] + 32` 和 `first == s[j-1] - 32` 来处理大小写。这种方法假设 ASCII 编码,且只处理了字母大小写相差 32 的情况。但更可靠的方式是使用 `tolower` 或 `toupper` 函数,或者直接比较忽略大小写。另外,如果首字母是大写、尾字母是小写,或者反过来,你的加减 32 逻辑可能在某些情况下不准确,比如首字母是 'A'(65),尾字母是 'a'(97),差 32 正确;但首字母是 'a'(97),尾字母是 'A'(65),差 -32 也正确。不过如果首字母和尾字母都是大写或都是小写,你的第三个条件 `first == s[j-1]` 能处理。整体逻辑可行,但不够通用。