簡體   English   中英

CS50問題結果不對,不明白為什么

[英]CS50 problem result is not right and I don't understand why

真的很抱歉打擾,但我有一個問題,我不知道如何解決。 我一直在做 CS5O,在問題集 2 中我收到了錯誤的結果,我不明白我做錯了什么。 “一條魚。兩條魚。紅魚。藍魚。”這句話應該給我“一年級之前”。 但是給我 2 級,它給 14 級一個 16+ 級的句子。 有人能幫我嗎? 這是我的代碼:

#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: %s\n", 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 1\n");
    } else if (index > 16)
    {
        printf("Grade 16+\n");
    } else
    {
        printf("Grade: %i\n", 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;
}

謝謝!!

關於類型:

有一種現象有時被稱為“馬虎輸入”,這基本上意味着粗心大意地在代碼中輸入任何隨機變量類型,然后想知道為什么沒有任何效果。 以下是您需要了解的一些事項:

  • Integer 除法通過刪除余數來截斷結果。 int是 integer,常量如100也是int 因此3/2在 C 中的計算結果為1

  • 除非你有非常好的和奇特的理由1) ,否則你幾乎不應該在 C 程序中使用float類型。

    在像 PC 這樣的高端系統上,總是使用double 所有默認數學函數都使用double ,例如round() 如果你想將它們與float一起使用,你可以使用特殊的 function roundf() 同樣,所有浮點常量1.0都是double類型。 如果你想讓它們浮動,你可以使用1.0f

  • 由於以上兩個原因,養成從不在同一表達式中混合不同類型的習慣。 不要混合使用 integer 和浮點數。 不要混用floatdouble 混合類型會導致意想不到的隱式轉換問題、意外截斷、精度損失等。

例如一行float L = 100 * (letters / words); 需要重寫以在任何地方顯式使用double

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

1)就像使用具有單精度浮點 FPU 的微控制器,但只有軟件浮點double精度。 或者一個 FPU,其中double的效率要低得多。


關於函數和全局變量:

變量letterswordssentences可以在 main() 內本地聲明,因為您的函數返回要使用的值。

出於多種原因,像您一樣聲明全局變量被認為是非常糟糕的做法。 它將變量暴露給不應訪問的程序的其他部分,這反過來又增加了意外/故意濫用的機會,因為變量隨處可用。 它增加了命名沖突的機會。 它在多線程應用程序中是不安全的。 這是普遍的壞事; 不要這樣做。

而是通過參數和返回值將變量傳入/傳出函數。


關於“幻數”:

在源代碼中間刪除一個常量(例如0.0588 ),零解釋該數字的來源或作用,這被稱為“幻數”。 這是不好的做法,因為代碼的讀者不知道它是什么。 讀者通常是你自己,一年后,當你完全忘記代碼的作用時,這是一種自我折磨。

因此,不要像這樣輸入一些數字,而是使用具有有意義名稱的#defineconst變量,然后在等式/表達式中使用該有意義的名稱。

在符號表值的情況下,我們不必自己發明那個有意義的名稱,因為 C 已經有一個內置的機制。 而不是text[i] >= 65你應該輸入text[i] >= 'A' ,這是 100% 等效的但更具可讀性。

關於符號表值的高級細節是它們實際上不能保證相鄰。 ch >= 'A' && ch <= 'Z'類的東西可能適用於經典的 7 位 ASCII,但它是不可移植的,也不會轉換“locale”——當地語言特定的字母(如西班牙語、法語中所見) 、德語等——幾乎所有主要語言都使用拉丁字母)。 可移植的解決方案是使用 ctype.h 中的isupperislower 或者在你的情況下更好, isalpha


關於代碼格式:

不要發明一些自己的非標准格式。 有些關於代碼格式的事情是主觀的,但這些不是:

  • 始終在 function 主體之間使用空行。
  • 始終將 function 的最后一個}單獨一行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM