CS50 wk1 + C 學習心得和作業

筆記:

1.負數的表示方法:

這是huli大大的課程導讀裡教的。huli大大補充的非常好,因為CS50沒有教電腦怎麼顯示負數。

我理解的是:先設定好幾個bits,比如4個bite,那可以用x+(-x)=0這個公式推導出來-x。因為只有4個bite,所以進位的時候變成0000,剛好等於0。

來源:https://docs.google.com/presentation/d/1i86DfR63UzTd2pDdmmD--x9bRrg0GEyvWec1InQFIkU/edit#slide=id.g1ea064e5e0_0_99

2.overflow

當所需要表示的數超過了其相應數據類型所能表示的最大值時,會出現整數溢出。

比如說int的範圍是-2147483648~2147483647,如果超過2147483647的話,就會從頭開始循環,變成-2147483648.

3.小數的儲存方法

這個有點難,看的我似懂非懂。

只記得一點,那就是用二進制來存10進制的小數,用有限來表示無限,不可能非常精準。

小數的算法

4.command line:

  • pwd
  • ls
  • cd
  • mkdir
  • rm
  • cp
  • mv
  • man

5.data type:

C語言規定了每個數據類型可以佔用的bits不同。

n 個 bit 能表示的範圍 -2^(n-1) ~ 2^(n-1) - 1。

https://en.wikipedia.org/wiki/C_syntax#Integer_types
http://www.cs.columbia.edu/~sedwards/papers/sgi1999c.pdf

作業心得:

做完了wk1的5個作業,才有點明白前輩們為什麼都說一定要好好寫作業。

這一週寫作業除了練習loop/while/if等等,主要學到了:

1.學習程式的思考方法:一步一步的解決問題(pseudocode)

當卡關的時候,就先做些別的時候,比如喝杯茶,轉移一下注意力再回來。

2.style,視覺上的美觀度

完美的程式碼:

  • correctness,正確的解決問題
  • design,設計精巧
  • style, 外觀完美

一開始不可能寫出很簡潔完美的程式碼,但最起碼,可以從表面可以先做到的開始,比如該空格的地方就空格。就像寫作文一樣,不見得寫的多好,但是先保持卷面整潔美觀。

寫完作業的時候,可以提交檢查表面上是否好看。

下面是我第一次寫的程式碼,都窩在一起,就被提示了。

3.comment

加標註的目的是讓以後的自己或他人看的懂,也幫助自己思考這一步驟的目的。

有的時候會蒙對,如果能想清楚解釋清楚的話,可以幫助自己理解。

4.寫作業可以獲得成就感

之前學C語言一塌糊塗,現在重新學,沒想到才一週,我就解開了5道題。頓時覺得很有成就感。

我想寫作業不僅可以增進學習,更可以獲得正反饋,幫助自己堅持學下去。

下面是我寫的2個作業。

1.mario-more

#include <stdio.h>
#include <cs50.h>
int main(void)
{
//prompt user to input height
    int h;
    do
    {
        h = get_int("Height: ");
    }
    while (h < 1 || h > 8);
    //double loop to print 8 lines and 8 rows
    for (int i = 1; i <= h ; i++)
    {
        for (int j = 1; j <= h; j++)
        {
            //check whether the opposite of line number is less than the line or row number
            if ((h - i) >= j)
            {
                printf(" ");
            } 
            if ((h - i) < j)
            {
                printf("#");
            }
        }
        printf("  ");
        for (int j = 1; j <= (2 * h + 2); j++)
        {
            if (j > i + 2 && j <= (2 * i + 2))
            {
                printf("#");
            }
        }
        printf("\n");
    }
}

2.credit

這個作業雖然過關了,但是寫的很爛,我想了2天,還是怎麼用loop來解,就先這樣吧。

#include <cs50.h>
#include <stdio.h>
#include <math.h>
int main(void)
{
//prompt user to input credit card number
    long l, len;
    int d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16;
    int n2, n4, n6, n8, n10, n12, n14, n16;
    int s;
    do
    {
        l = get_long("Credit Card Number: ");
    }
    while (l < 0 || l > pow(10, 16));
    //get digit length
    len = floor(log10(l))+1;
    //get digit n
    d1 = l % 10;
    d2 = (l % 100) / 10;
    d3 = (l % 1000) / 100;
    d4 = (l % 10000) / 1000;
    d5 = (l % 100000) / 10000;
    d6 = (l / 100000) % 10;
    d7 = (l / 100000) % 100 / 10;
    d8 = (l / 100000) % 1000 / 100;
    d9 = (l / 100000) % 10000 / 1000;
    d10 = (l / 100000) % 100000 / 10000;
    d11 = ((l / 100000) / 100000) % 10;
    d12 = ((l / 100000) / 100000) % 100 / 10;
    d13 = ((l / 100000) / 100000) % 1000 / 100;
    d14 = ((l / 100000) / 100000) % 10000 / 1000;
    d15 = ((l / 100000) / 100000) % 100000 / 10000;
    d16 = (((l / 100000) / 100000)/ 100000) % 10;
    //sum up second-to-last digit
    if (d2 < 5)
    {
        n2 = 2 * d2;
    }
    else
    {
        n2 = (d2 * 2) - 9;
    }
    if (d4 < 5)
    {
        n4 = 2 * d4;
    }
    else
    {
        n4 = (d4 * 2) - 9;
    }
    if (d6 < 5)
    {
        n6 = 2 * d6;
    }
    else
    {
        n6 = (d6 * 2) - 9;
    }
    if (d8 < 5)
    {
        n8 = 2 * d8;
    }
    else
    {
        n8 = (d8 * 2) - 9;
    }
    if (d10 < 5)
    {
        n10 = 2 * d10;
    }
    else
    {
        n10 = (d10 * 2) - 9;
    }
     if (d12 < 5)
    {
        n12 = 2 * d12;
    }
    else
    {
        n12 = (d12 * 2) - 9;
    }
    if (d14 < 5)
    {
        n14 = 2 * d14;
    }
    else
    {
        n14 = (d14 * 2) - 9;
    }
    if (d16 < 5)
    {
        n16 = 2 * d16;
    }
    else
    {
        n16 = (d16 * 2) - 9;
    }
    //sum up all digits
    s = n2 + n4 + n6 + n8 + n10 + n12 + n14 + n16 + d1 + d3 + d5 + d7 + d9 + d11 + d13 + d15;
    //check which bank it is
    if ((s % 10 == 0) && (len == 15) && d15 == 3 && (d14 == 4 || d14 == 7))
    {
        printf("AMEX\n");
    }
    else if ((s % 10 == 0) && (len == 16) && ( d16 == 5) &&( d15 == 1|| d15 == 2 || d15 == 3 || d15 == 4|| d15 == 5))
    {
        printf("MASTERCARD\n");
    }
    else if ((s % 10 == 0) && (len ==13 || len ==16) && (d13 == 4))
    {
        printf("VISA\n");
    }
    else
    {
        printf("INVALID\n");
    }
}

寫完這篇文章後學了wk2,裡面有教array,就用array把我很肥大的程式碼稍微瘦身了點。

#include <cs50.h>
#include <stdio.h>
#include <math.h>
int main(void)
{
//prompt user to input credit card number
    long l;
    int len;
    int sum;
    do
    {
        l = get_long("Credit Card Number: ");
    }
    while (l < 0 || l > pow(10, 16));
    len = floor(log10(l))+1;
    //get digits
    int digit[len], change[len];
    for (int i = 1;i <= len; i++)
    {
        digit[i]= fmod(l, pow(10,i))/pow(10,(i-1));
    }
    //get the sum
    {sum = 0;
        for (int i = 1; i<= len; i++)
        {
            if (i % 2 ==1)
            {
            change[i]=digit[i];
            }
            if(i % 2 ==0 && digit[i] >= 5)
            {
            change[i] = (digit[i]*2-9);
            }
            else if(i%2==0 && digit[i] < 5)
            {
            change[i]= digit[i] * 2;
            }
        sum+=change[i];
        }
    }
//check which bank it is
    if (sum % 10 == 0 && (len == 15) && digit[15] == 3 && (digit[14] == 4 || digit[14] == 7))
    {
        printf("AMEX\n");
    }
    else if ((sum % 10 == 0) && (l>=51e14 && l<56e14))
    {
        printf("MASTERCARD\n");
    }
    else if ((sum % 10 == 0 && len ==13 && digit[13]==4) ||(sum % 10 == 0 && len ==16 && digit[16]==4))
    {
        printf("VISA\n");
    }
    else
    {
        printf("INVALID\n");
    }
}

Leave a Comment

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