在线编译器 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]) count++; } } } printf("%d", count); return 0; }
这段代码的功能是统计输入字符串中首尾字母相同的单词个数。它遍历字符串,找到每个单词的开头,记录首字母,然后找到单词结尾,比较首尾字母是否相同。

- 内层循环 `for (j = i; s[j] != ' '; j++)` 在遇到空格时停止,但如果单词是最后一个单词,后面没有空格,循环会一直走到字符串末尾。这里 `if (s[j] == '\0') break;` 虽然能跳出循环,但此时 `j` 指向的是 `'\0'`,而不是最后一个字符,所以 `s[j - 1]` 才是单词的最后一个字母。这个逻辑是正确的,但可以思考一下:如果单词后面直接是字符串结束符,循环条件 `s[j] != ' '` 会一直为真,直到遇到 `'\0'`,然后通过 `break` 退出。此时 `j` 指向 `'\0'`,`j-1` 是最后一个字母。这个处理是可行的。

- 主要问题可能出现在输入包含多个连续空格或开头空格时。例如,如果字符串以空格开头,`i=0` 时 `s[0]` 是空格,会跳过。但后续遇到单词时,`s[i-1]` 是空格,条件成立。不过,如果字符串开头有多个空格,第一个非空格字符会被正确识别为单词开头。但考虑一种情况:如果字符串末尾有空格,最后一个单词后面有空格,内层循环遇到空格会正常停止,`j` 指向空格,`j-1` 是最后一个字母,没问题。

- 一个潜在的错误:当单词只有一个字母时,例如 "a",首字母和尾字母相同,应该计数。但代码中 `first = s[i]`,然后内层循环 `for (j = i; s[j] != ' '; j++)`,如果单词只有一个字母,`j` 从 `i` 开始,`s[i]` 不是空格,循环继续,`j` 变成 `i+1`,此时 `s[i+1]` 可能是空格或 `'\0'`,循环停止。然后比较 `first` 和 `s[j-1]`,即 `s[i]` 和 `s[i]`,相同,所以计数正确