c语言 - CS50问题结果不正确,我不明白为什么



我真的很抱歉打扰你,但我有一个问题,我不知道如何解决。我一直在做CS5O,在问题集2中,我收到了错误的结果,我不明白我做错了什么。它应该给我";在1级之前;对于句子";一条鱼。两条鱼。红鱼。蓝色的鱼"但它给了我2级,它给了一个16+级的句子14级。有人能帮我吗?这是我的代码:

#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
int count_letters(string text);
int count_word(string text);
int count_sentences(string text);
int letters;
int words;
int sentences;
int main(void)
{
string text = get_string("Text: ");
printf("Text: %sn", text);
count_letters(text);
count_word(text);
count_sentences(text);
float L = 100 * (letters / words);
float S = 100 * (sentences / words);
int index = round(0.0588 * L - 0.296 * S - 15.8);
if (index < 1)
{
printf("Before Grade 1n");
} else if (index > 16)
{
printf("Grade 16+n");
} else
{
printf("Grade: %in", index);
}
}
int count_letters(string text)
{
letters = 0;
for (int i = 0; i < strlen(text); i++)
{
if ((text[i] >= 65 && text[i] <= 99) || (text[i] >= 97 && text[i] <= 122))
{
letters++;
}
}
return letters;}
int count_word(string text)
{
words = 1;
for (int i = 0; i < strlen(text); i++)
{
if (isspace(text[i]))
{
words++;
}
}
return words;}
int count_sentences(string text)
{
sentences = 0;
for (int i = 0; i < strlen(text); i++)
{
if (text[i] == 33 || text[i] == 46 || text[i] == 63)
{
sentences++;
}
}
return sentences;
}

谢谢!!

关于类型:

有一种现象有时被称为";草率打字";这基本上意味着不小心在代码中滥发任何随机变量类型,然后想知道为什么什么都不起作用。这里有一些你需要知道的事情:

  • 整数除法通过删除余数来截断结果。int是整数,诸如100之类的常数也是int。因此3/2在C.中评估为1

  • 除非您有非常好的和奇异的原因1(,否则您几乎不应该在C程序中使用类型float

    在像PC这样的高端系统上,始终使用double。所有默认的数学函数都使用double,例如round()。如果你想将它们与float一起使用,你可以使用一个特殊的函数roundf()。类似地,所有浮点常数1.0都是类型double。如果你想让它们浮动,你可以使用1.0f

  • 出于以上两个原因,养成一种习惯,永远不要在同一个表达中混合不同的类型。不要混合整数和浮点。不要混合使用floatdouble。混合类型可能导致意外的隐式转换问题、意外的截断、精度损失等

例如,像float L = 100 * (letters / words);这样的行需要重写,以便在所有地方显式使用double

double L = 100.0 * ((double)letters / (double)words);

1(类似于使用具有单精度浮点FPU但仅使用软件浮点CCD_ 19的微控制器。或者CCD_ 20的效率要低得多的FPU


关于函数和全局变量:

变量letterswordssentences本可以在main((中本地声明,因为函数返回的值无论如何都要使用。

由于多种原因,像您这样声明全局变量被认为是非常糟糕的做法。它将变量暴露给程序中不应该访问的其他部分,这反过来又增加了意外/故意滥用的机会,因为变量随处可见。它增加了命名冲突的机会。它在多线程应用程序中是不安全的。这是普遍的坏;不要这样做。

相反,通过参数和返回值将变量传递到函数或从函数传递变量。


关于";幻数":

在源代码中间丢弃诸如0.0588之类的常量,而对该数字的来源或作用的解释为零,这被称为"0";幻数";。这是一种糟糕的做法,因为代码的读者根本不知道它是什么。读者通常是你自己,一年后,当你忘记了代码的作用时,这是一种自我折磨。

因此,与其键入这样的数字,不如使用具有有意义名称的#defineconst变量,然后在等式/表达式中使用该有意义的名称。

对于符号表值,我们不必自己发明这个有意义的名称,因为C已经有了一个内置的机制。您应该键入text[i] >= 'A',而不是text[i] >= 65,它100%等效,但可读性更强。

关于符号表值的一个高级细节是,它们实际上并不能保证是adjacant。像ch >= 'A' && ch <= 'Z'这样的东西可以在经典的7位ASCII上工作,但它是不可移植的,也不能转换";区域设置"-当地语言特有的字母(如西班牙语、法语、德语等,几乎所有主要语言都使用拉丁字母(。对此,可移植的解决方案是使用ctype.h中的isupperislower,或者在您的情况下使用isalpha


关于代码格式:

不要发明一些自己的非标准格式。有一些关于代码格式的东西是主观的,但这些不是:

  • 函数体之间总是使用空行
  • 总是将函数的最后一个}放在它自己的一行

最新更新