[英]CS50 CAESAR - Different output depending on position of statement, but I don't understand why
[英]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 和浮點數。 不要混用float
和double
。 混合類型會導致意想不到的隱式轉換問題、意外截斷、精度損失等。
例如一行float L = 100 * (letters / words);
需要重寫以在任何地方顯式使用double
:
double L = 100.0 * ((double)letters / (double)words);
1)就像使用具有單精度浮點 FPU 的微控制器,但只有軟件浮點double
精度。 或者一個 FPU,其中double
的效率要低得多。
關於函數和全局變量:
變量letters
、 words
和sentences
可以在 main() 內本地聲明,因為您的函數返回要使用的值。
出於多種原因,像您一樣聲明全局變量被認為是非常糟糕的做法。 它將變量暴露給不應訪問的程序的其他部分,這反過來又增加了意外/故意濫用的機會,因為變量隨處可用。 它增加了命名沖突的機會。 它在多線程應用程序中是不安全的。 這是普遍的壞事; 不要這樣做。
而是通過參數和返回值將變量傳入/傳出函數。
關於“幻數”:
在源代碼中間刪除一個常量(例如0.0588
),零解釋該數字的來源或作用,這被稱為“幻數”。 這是不好的做法,因為代碼的讀者不知道它是什么。 讀者通常是你自己,一年后,當你完全忘記代碼的作用時,這是一種自我折磨。
因此,不要像這樣輸入一些數字,而是使用具有有意義名稱的#define
或const
變量,然后在等式/表達式中使用該有意義的名稱。
在符號表值的情況下,我們不必自己發明那個有意義的名稱,因為 C 已經有一個內置的機制。 而不是text[i] >= 65
你應該輸入text[i] >= 'A'
,這是 100% 等效的但更具可讀性。
關於符號表值的高級細節是它們實際上不能保證相鄰。 ch >= 'A' && ch <= 'Z'
類的東西可能適用於經典的 7 位 ASCII,但它是不可移植的,也不會轉換“locale”——當地語言特定的字母(如西班牙語、法語中所見) 、德語等——幾乎所有主要語言都使用拉丁字母)。 可移植的解決方案是使用 ctype.h 中的isupper
或islower
。 或者在你的情況下更好, isalpha
。
關於代碼格式:
不要發明一些自己的非標准格式。 有些關於代碼格式的事情是主觀的,但這些不是:
}
單獨一行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.