見出し画像

CS50 2023 - Week1 C


概要

Week1では、C言語の基礎を学びます。
講義の主な内容は、ソースコード、コンパイラ、Visual Studios、エスケープシーケンス、ヘッダーファイル、ライブラリ、条件分岐、変数、ループ、定数、コメント、擬似コードについてです。

基本的には、これまでにScratchでやってきたことを、今度はC言語を用いてコードで実行していくというイメージです。


Lab 1

Population

C言語を用いて、ラマの人口増加を予測するプログラムを作成します。
以下は、実際に私が提出したコードです。

#include <cs50.h>
#include <stdio.h>

int main(void)
{
    int s;
    int e;
    int i;

    // TODO: Prompt for start size
    do
    {
        s = get_int("Start size: ");
    }
    while (s < 9);

    // TODO: Prompt for end size
    do
    {
        e = get_int("End size: ");
    }
    while (e < s);

    // TODO: Calculate number of years until we reach threshold
    for (i = 0;; i++)
    {
        if (s >= e)
        {
            break;
        }
        s = s + (s / 3) - (s / 4);
    }

    // TODO: Print number of years
    printf("Years: %i\n", i);
}

初回なので少し細かく解説していきます。

コードの解説

#include <cs50.h>
#include <stdio.h>

プログラムで使うためのツールを読み込んでいます。

cs50.hstdio.hがツールです。これらを読み込むことで、プログラム内で様々な操作ができるようになります。例えば、数値を入力したり、画面に文字を表示したりするための命令などです。

具体的な例としては、get_intcs50.hをincluedeしないと使用することができません。

int main(void)

メイン関数です。
プログラムが実行されると最初にこの関数が呼び出されます。

int s;
int e;
int i;

整数型変数の宣言です。
講義でも説明されていますが、これらの変数は後で値を格納するために使用します。

do
{
    s = get_int("Start size: ");
}
while (s < 9);

do-whileループです。
このループは、開始サイズStart sizeを入力値として受け取り、入力された値が9未満である限り繰り返すというものです。

for (i = 0; ; i++)
{
    if (s >= e)
    {
        break;
    }
    s = s + (s / 3) - (s / 4);
}

forループです。
ループは無限に続くように設定されていますが、ifステートメントで条件をチェックしてループから抜け出します。

このループは、開始サイズが終了サイズ以上になるまで、開始サイズを増加させ続けます。開始サイズは、(開始サイズ / 3)の値を加え、(開始サイズ / 4)の値を減算することで増加します。

printf("Years: %i\n", i);

ここではprintf関数を使用して、forループが繰り返された回数(年数)を出力します。


Problem Set 1

Week1のProblem Setでは、3つの課題があります。

  • Hello

  • Mario

  • Cash/Credit

このうち、Hello以外の2つには、less comfortable(易しいバージョン)と、more comfortable(難しいバージョン)の選択肢があります。

後者はやりがいを求める方向けですが、どちらを提出しても評価に差は生じません。
両方提出した場合は、評価点が高い方がそのコースのスコアとしてカウントされます。

本noteでは、以降すべてless comfortableの方を記載していきます(more comfortableに挑戦するのは、ここの情報がなくても問題ない方々だと思いますので…)。


Hello

ユーザーから名前(文字列)を取得して、”Hello, XX”と表示するプログラムを作成します。XXの箇所には、ユーザーが入力した文字列が表示されます。

以下は私が提出したコードです。

// Standard input and output
#include <stdio.h>
// To use get_string
#include <cs50.h>

int main(void)
{
    string name = get_string("What's your name? ");
    printf("hello, %s\n", name);
}

cs50.hget_stringで文字列を取得します。
シンプルなプログラムなのでコメントは要らないくらいなのですが、課題提出の際にある程度のコメント数が求められるため、入れられそうな箇所に入れてみました。


Mario(less comfortable)

"#"を使って、マリオに出てくるブロックを作るプログラムを作成します。
必要なことはほとんど講義やWalkthroughで説明されているのですが、ブロックの向きに関してだけは少々わかりづらいかもしれません。
コード内のコメントにヒントを入れていますので、もし躓いた場合は参考にしてください。

// To use get_int
#include <cs50.h>
#include <stdio.h>

int main(void)
{
    int x;

    do
    {
        x = get_int("Size: ");
    }
    while (x < 1 || x > 8);
    // Vertival
    for (int i = 0; i < x; i++)
    {
        // Horizontal
        for (int j = 0; j < x; j++)
        {
            if (j > x - i - 2)
            {
                printf("#");
            }
            else
            {
                // " " = Left-Aligning, "" = Right-Aligning
                printf(" ");
            }
        }
        printf("\n");
    }
}

Cash

お釣りに必要なコインの最初枚数を算出するプログラムを作成します。
…と書くと、難しそうに思えるかもしれませんが、複雑な部分は予め用意されています。実際に書く必要があるのは、TODOのコメントが入っている箇所のみです。

#include <cs50.h>
#include <stdio.h>

int get_cents(void);
int calculate_quarters(int cents);
int calculate_dimes(int cents);
int calculate_nickels(int cents);
int calculate_pennies(int cents);

int main(void)
{
    // Ask how many cents the customer is owed
    int cents = get_cents();

    // Calculate the number of quarters to give the customer
    int quarters = calculate_quarters(cents);
    cents = cents - quarters * 25;

    // Calculate the number of dimes to give the customer
    int dimes = calculate_dimes(cents);
    cents = cents - dimes * 10;

    // Calculate the number of nickels to give the customer
    int nickels = calculate_nickels(cents);
    cents = cents - nickels * 5;

    // Calculate the number of pennies to give the customer
    int pennies = calculate_pennies(cents);
    cents = cents - pennies * 1;

    // Sum coins
    int coins = quarters + dimes + nickels + pennies;

    // Print total number of coins to give the customer
    printf("%i\n", coins);
}

int get_cents(void)
{
    // TODO
    int x;
    do
    {
        x = get_int("Change owed: ");
    }
    while (x < 0);
    return x;
}

int calculate_quarters(int cents)
{
    // TODO
    return cents / 25;
}

int calculate_dimes(int cents)
{
    // TODO
    return cents / 10;
}

int calculate_nickels(int cents)
{
    // TODO
    return cents / 5;
}

int calculate_pennies(int cents)
{
    // TODO
    return cents / 1;
}

終わりに

C言語は最初から最後まで苦手で、洗練されたコードだとはとても言えませんが、ひとつの解答例として参考にしていただければ幸いです。

この記事が気に入ったらサポートをしてみませんか?