[CS50x学習メモ] Week 1: C (1/2)
導入
Week 1はC言語。前回はScratchというグラフィカルな(パズルピースを組み立てるような)プログラミングを行ったが、暗号文や記号のような不可解なものに変わっていく
これからScratch、C、Pythonなど言語に関わらず、学んで書いていく物をsource codeと呼ぶが、Computerは二進数(binary digit)しかわからないため、0と1のパターンで表されたmachine codeが必要となる
つまりは人間が書いたsource codeをmachine codeにする必要がある
input → □ → output
source code → □ → machine code
この□に当てはまる部分をcompilerと呼ぶ
大事なこと
・やるべきことをする
・正しくしたい
・適切(良い)な設計 correctness, design, style
=多くの場合適切な設計だと、高速で保守しやすい
スタイル美学
VSCode(Visual Studio Code)
紙の上やメモ帳、Wordなどにもsource codeを書くこともできるが、書いて、コンパイルし、実行することができるVSCodeを使っていく
VSCode for CS50x
※課題提出のため、[Log in via GitHub]でGitHubアカウントと連携しています
※VSCodeの画面説明
右上部が実際にコードを書く場所
TERMINAL window(Command line, interface, CLI)
GUI(Graphycal User Interface)とは対称なもの
アイコンを選択しクリック…するよりもキーボード入力の方が効率的なので、TERMINALを使ってコードをコンパイルしたり実行したりします
画面左側には見慣れたファイルエクスプローラー(自分のアカウントのファイルがツリー表示で見える)や、アクティビティバーなどがあり、GUIとCLIの両方が提供されているが、CS50の授業ではCLIのTERMINAL windowを主に使いGUIは非表示にして授業を進めていく
TERMINALには$が表示されているが、これはタイプコマンドでカーソルのようなもの
準備とC言語でのHello, world
VSCodeのTERMINALに、書いて実行するのが一番簡単。
$の後にcode hello.c
を入力しEnter
を押すと、上部にhello.c
のタブが開く
#include <stdio.h>
int main(void)
{
printf("hello, world\n");
}
まずは実際に始めてのsource codeを実行してみたいが、Scratchのように緑の旗や、コンパイル・実行するアイコン・GUIはない。では、どうするか
TERMINALに戻り、2行目の$が表示されている(コマンド準備OK状態)箇所へいき、実際の動くプログラムへコンパイルします
$の後ろにmake hello
と入力し、Enter
何も起きず、次の行に$が表示されたらそれはいいこと。エラーメッセージもミスもなにもない!
次に実行をするにはどうするか、$の表示は次のコマンド待機中なので、そこに./hello
を入力し
Enter
を押す。TERMINALにhello.c
が実行され、Hello, world
が表示される
これでC言語の初めてのプログラムが完成。
Hello, worldプログラムの深堀り
VSCodeの非表示にしたエクスプローラーを見てみるとhello
,ハイライトされたhello.c
が入っている。ハイライトはタブで開いているためである。
ただのhello
がプログラムで、CLI上ではできないが、通常のPC上での作業に例えるなら、「プログラムをダブルクリックしたら実行」をTERMINALでコマンドから行った形になる
VSCodeやほかのテキストエディタには自動的に色を変えたりハイライトされたりする機能がある
この色の設定は自分で変更することができScratchのブロックのような決まりはない
Scratchのsay
コマンドに該当するC言語の関数はprintf()
。fはフォーマット済の意味
C言語として書くには、括弧の中身を「文字」として扱うための""や文末の;など必要な構文が沢山あってミスしやすい。これらがScratchから始める理由とのこと。
ミスをしたら(エラーメッセージの読み方)
ミスをしたら何が起こるのかの説明。
挙動としては、TERMINALにエラーメッセージが表示され、コンパイルされない
ファイル名:行:文字数 error: 内容
のような形で、source codeの何行目にどんなエラーがあるのか、何が必要なのかの提案が表示される(提案は必ずあるわけではない)
エラーの内容を修正し、make hello
で再コンパイルし、何も起きなければ再コンパイル完了となる
\n
の意味
構文的には不必要なコマンドですが、特殊な記号でCだけでなくPythonでも使う"escape sequences"で、次の行にカーソルを送ります
header files(libraries)の必要性
C言語ではいろいろな機能・動作をする(今回はまずprintf)時に、それがどんな機能なのかが分からない状態からスタートする。そのため、標準的な機能セットを冒頭(Header)に入れなければいけない。
この#include <stdio.h>
の部分は、コンパイラにstandard I/Oの機能を使用したいよ‼というお知らせになる
standard I/Oがなかったり、違うライブラリを入れてしまった場合は、その関数がどんな挙動をするのかが分からず、動かないので注意。
各ライブラリにどんな関数が含まれているのかは、マニュアルサイトを参照すること(使い方や引数の指定方法も記載されている)
- manual.cs50.io/#stdio.h
- printfのマニュアルページ: manual.cs50.io/3/printf
CS50用のライブラリの提供について
-
manual.cs50.io/#cs50.h
この中にはユーザーのキーボード入力から、文字列や整数、小数点、長文文字列などを取得する関数などが含まれているので、これらを使用して課題を行っていく
Practics
実際にライブラリを使ってみよう
モデル化したものを考えてみると
arguments → [function] → return value
return value(戻り値)部分がScratchでは自動的に返ってきていたが、Cでは戻り値に任意の名前を付けることができる
※戻り値は使用したり再利用できる
先週のScratchのHello, worldをCにしてみよう
ブロックでask (What's your name?) and wait
ブロックに対し、ユーザーのインプットanswer
をCにすると、文字列をユーザーに入力してもらう必要があるのでget_string
を使う。また、戻り値に任意で名前を付けることができるのでanswer
とし、この変数が文字列であることもコンパイラに伝える必要がある。
結果的に、ブロック部分のみをCに書き換えると
string answer = get_string("What's your name? ")
となる
上記を踏まえ、実際のコードも考えるとどうなるか
#include <cs50.h>
#include <stdio.h>
int main(void)
{
string answer = get_string("What's your name? ");
printf("hello, answer\n");
}
コンパイルして実行してみると、hello, answer
が表示される
answer
の内容ではなく、単なる文字のanswerが表示されてしまった
どこが間違えているのか?
Scratchのブロックを思い出してみると[say(join(hello,)(answer)]のようなブロック構造だったが、上のCではsayに該当する部分にprintfを用いている。ここで、前の行に取得したget_string
の戻り値であるstring answer
を使いたい場合、文字列(string)なので%s
を入れる必要がでてくる
#include <cs50.h>
#include <stdio.h>
int main(void)
{
string answer = get_string("What's your name? ");
printf("hello, %s\n", answer);
}
ここで一旦講義にも休憩が入ったので前編として区切ります
Discussion