CS50 wk2 + C 學習心得

註:本文是個人心得筆記,初學者能力有限,內容不保證正確,請謹慎參考。

wk2主要有下面幾個內容:

  • compiling(preprocessing, compiling, assembling, linking)
  • debug三種方法(printf,debug50,對著鴨子復述一遍步驟)
  • 數據類型:array(array就是儲存到電腦memory裡的一串連續的某種資料,比如一串數字或一串字母。string可以看成是一堆字母和符號組成的array)
  • string怎麼顯示(string沒有固定bytes,所以會用"\0"結尾,告訴電腦結束了)
  • command line argument(利用argc argv 在command line 直接輸入參數,return 1 報錯,return 0 接收輸入的參數)

本來是想通過寫筆記+寫作業來提高學習的留存率,但是光寫作業就耗費了我的絕大部分心力,實在沒有餘力更認真的寫課程筆記。

好在寫作業時就是通過寫code來實踐上課學習的內容,保證了一定的留存率。

前兩週我有看huli大的導讀,但這週沒看了,我把時間省下來再多看一遍課程的內容。

作業心得:

自己思考做出作業最重要,我要求自己在做作業前不要看別人寫出的作業code。

1.readability

光是計算letters花了睡前2個小時,還沒有解開,但是早上起來看了下walkthrough,10分鐘就解開了,然後同理很快計算出詞和句子個數。

不過在最後公式的時候,又犯了個錯誤,就是int 除以 int最後會得出int,比如6/5=1,後面的小數會自動捨棄。在計算的時候,要把int轉為float,這樣計算的結果才是正確的。

readability.總共花費3小時。

2. caesar

不看walkthrough自己解題根本不可能,看了後晚上花了2小時,早上又花了2小時,一度想要放棄,最後吃完晚飯後半個小時又突然開竅並完成了。

我卡關的原因主要在:

1)only digit 寫錯了,一直沒法有效判斷。為此,我先再一次看了教學視頻,又再一次看了TA 的short。最後再仔細閱讀psets的文字描述的步驟,重新一步一步修改我的程式,最終解決了。

2)沒有prompt。我是搜了別的同學的解法之後才發現我的get-string的位置排錯了。我原來是先判斷command line argument 是應該if (return 0) 還是else( return 1),然後get-string,最後才發現應該是包在if 裡面一起執行。

3.scrabble

這個花了2個小時,卡在字母和分數之間轉換的function好久。感覺腦中有答案,但寫出來就是不對。後來用紙筆來演算,最終解開。

4.作業難度和時間

這三個作業總共花費11個小時以上,明顯比wk1難,自己隨時都想放棄,好在想放棄的時候有再堅持一下。據說wk3/wk4更難,不知道自己會不會放棄。

5.成就感

自己成功完成作業還是很有成就感的一件事。老師在這方面拿捏的很好。太難容易放棄,太簡單容易厭倦。有些難有些挑戰努力解決後,會增加成就感,可以幫忙繼續學下去。

老師派TA錄製Walkthrough來幫忙解題也頗有心機,像是學騎車時的輔助輪。不然光靠自己解題很容易沒有頭緒,導致中途放棄。有TA的指導視頻,增加完成作業的自信心和動力。但TA也拿捏的很好,點到為止,大部分還是要靠自己想到解決方法,這樣完成作業後感覺不會打折,還是很有成就感。

(不知道貼出自己的程式碼會不會違反老師的知識版權,好像很多人都會貼,那我也先貼試看看。)

#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
int count_letters(string s);
int count_words(string s);
int count_sentences(string s);
int main(void)
{
    string s = get_string("Text: ");
    int i, index;
    //calculate letters,words and sentences
    int l = count_letters(s);
    int w = count_words(s);
    int z = count_sentences(s);
    // check index
    index = round(0.0588 * (float)l / (float)w * 100 - 0.296 * (100 / ((float)w / (float)z)) - 15.8);
    if (index < 1)
    {
        printf("Before Grade 1");
    }
    else if (index >= 16)
    {
        printf("Grade 16+");
    }
    else
    {
        printf("Grade %i", index);
    }
    printf("\n");
}
int count_letters(string s)
{
    int n = 0;
    {
        for (int j = 0; j < strlen(s); j++)
        {
            if ((isupper((char)s[j])) || (islower((char)s[j])))
            {
                n = n + 1;
            }
        }
        return n;
    }
}
int count_words(string s)
{
    int x = 0;
    {
        for (int k = 0; k < strlen(s); k++)
        {
            if (isspace((char)s[k]))
            {
                x = x + 1;
            }
        }
        return x + 1;
    }
}
int count_sentences(string s)
{
    int w = 0;
    {
        for (int p = 0; p < strlen(s); p++)
        {
            if (s[p] == 46 || s[p] == 63 || s[p] == 33)
            {
                w = w + 1;
            }
        }
        return w;
    }
}
#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
bool only_digits(string s);
char rotate(char c, int t );
int main(int argc, string argv[])
//whether command line input is correct
{
    if(argc ==2 && only_digits(argv[1])==true)
    {
    int k = atoi(argv[1]);
    string t = get_string("plaintext: ");
    printf("ciphertext: ");
    int m = strlen(t);
    for (int i = 0; i < m; i++)
        {
        char c=rotate(t[i],k);
        printf("%c",c);
        }
        printf("\n");
    }
    else
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }
    //get the key
    //get string and rotate
}
// numeric or not
bool only_digits(string s)
{
    int n = strlen(s);
    for (int x = 0; x < n; x++)
    {
        if (isdigit(s[x]) == 0)
        {
            return false;
        }
    }
    return true;
}
char rotate(char c, int t)
{
    if (isupper(c) )
    {
        c = c - 65;
        c = (c + t) % 26;
        c = c + 65;
    }
    else if (islower(c))
    {
        c = c - 97;
        c = (c + t) % 26;
        c = c + 97;
    }
    else
    {
        c = c + 0;
    }
    c = (char)c;
    return c;
}
#include <ctype.h>
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// Points assigned to each letter of the alphabet
int POINTS[] = {1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10};
int compute_score(string word);
int main(void)
{
    // Get input words from both players
    string word1 = get_string("Player 1: ");
    string word2 = get_string("Player 2: ");
    // Score both words
    int score1 = compute_score(word1);
    int score2 = compute_score(word2);
    // TODO: Print the winner
    if (score1 > score2)
    {
        printf("Player 1 wins!\n");
    }
    else if (score1 == score2)
    {
        printf("Tie!\n");
    }
    else
    {
        printf("Player 2 wins!\n");
    }
}
int compute_score(string word)
    // Compute and return score for string
{
    int score = 0;
    for(int i=0; i<strlen(word);i++)
    {
        int c = (int)word[i];
        if (isupper(c))
        {
            word[i]=POINTS[(int)word[i]-65];
        }
        else if(islower(c))
        {
            word[i]=POINTS[(int)word[i]-97];
        }
    else
        {
            word[i] = 0;
        }
    score += word[i];
    }
    return score;
}

Leave a Comment

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *