異質なプログラミング言語への適応をサポートしたい
関数型のSchemeから,手続き型のC言語へ
単位取得のための実験でなく,理解のための実験にしたい
〆切りまでに課題をこなすことは重要
理解しながら課題をこなすことはさらに重要
理解を伴って実験1を遂行するのはとても重要
実験3(コンパイラの作成)に響きます
プログラミング言語の多様性を認識できます
Scheme C Java ML Scala X10 C++ Object-oriented Programming Functional Programming Prolog Declarative Lang. Procedural Lang. Multi-paradigm Programming Python Haskell KL1
オープンソース開発の代表的成果
学生だったLinus Torvaldsを中心に開発されたUNIXライク
のOS
ディストリビューションも豊富 (Fedora, OpenSUSE, Ubuntu,
etc)
企業・自治体での導入事例も増え,オフィススイート,
ドローイングソフトなどソフトウェアも充実
当初はCUI(Character User Interface)による操作が普通(
本
演習ではCUIによる利用に習熟して欲しい
)
cd(ディレクトリの移動)
使い方:cd ディレクトリ名 ( cd .. (ピリオド2つ)で
一つ上のディレクトリへ移動)
cd [リターン] でホームディレクトリに戻る
ls(ファイル・ディレクトリ一覧の表示)
使い方:ls [リターン] で現在のディレクトリの一覧表示
mkdir(ディレクトリの作成)
使い方:mkdir ディレクトリ名
touch(ファイルの作成)
使い方:touch ファイル名
cp(ファイル・ディレクトリの複製)
使い方:cp コピー元 コピー先
mv(ファイル・ディレクトリの移動・名前変更)
使い方:mv 移動対象 移動先(新しい名前)
rm(ファイル・ディレクトリの削除)
使い方:rm 削除対象
less または lv(ファイル内容の閲覧)
使い方:less 閲覧したいファイル名
閲覧中はスペースキーで進み,bキーで戻る
ファイル・ディレクトリをツリー構造で管理
/(ルート)が基点
cd はツリーのノードを移動する
ためのコマンド
「そのディレクトリの上に行って…」
というのはこの構造イメージがあるから
..(連続する二つのピリオド) は親
ノード, .(ピリオド一つ) は現在の
ノードを意味する
e.g., cd .. で親ノードに移動
論理的構造を表しているに過ぎない
別々のサーバや記憶装置に存在する情報
を一つのツリー構造に表現できる
/ (root)bin home lib 09 08 lab7 hatto ユーザhattoの ホームディレクトリ 一般ユーザである hattoが操作できる 領域
C言語は実行するためにコンパイラを必要とする言語
人間が理解可能なプログラム(ソースコード)を計算機
が理解可能なコードに変換する
コンパイル プログラムの記述 プログラムの実行 • “.c”の拡張子が付いた ファイルにプログラム を記述する 例: program.c • emacsが拡張子を見 て編集モードを勝手に 判断してくれる • 作成したソースファイ ルを,コンパイラで処 理させる 例: cc program.c • オブジェクトファイルが 出来上がる(陽には見 えない) • デフォルトでは a.out という実行形式ファイ ルが出来上がる • “./a.out”と打ち込んで 実行できる
以下のコードを入力した prog1.c というファイルを作成
して,実行せよ
#include <stdio.h> main() { printf("Hello World!\n"); }
以下のコードを入力した prog1.c というファイルを作成
して,実行せよ
#include <stdio.h> main() { printf("Hello World!\n"); } Hello World! 実行結果
以下のコードを入力した prog1.c というファイルを作成
して,実行せよ
#include <stdio.h> main() { printf("Hello World!\n"); } 文字列はダブルクオーテーション で挟む \nは改行を表す 文の区切り 文字列を表示する命令
以下の出力が得られるよう prog1.c を書き換え,実行
せよ
Hello Japan! Hello Asia! Hello World! 期待する出力
以下の出力が得られるよう prog1.c を書き換え,実行
せよ
#include <stdio.h> main()
{
printf("Hello Japan!\nHello Asia!\nHello World!"); } #include <stdio.h> main() { printf("Hello Japan!\n"); printf("Hello Asia!\n"); printf("Hello World!\n"); }
以下の出力が得られるよう prog1.c を書き換え,実行
せよ
#include <stdio.h> main() { printf("Hello Japan! Hello Asia! Hello World!"); }
以下のコードを入力した prog2.c というファイルを作成
して,実行せよ
#include <stdio.h> main() { printf(“計算結果は %d\n”, 2+3); }
prog2.c を以下のように書き換えて,実行せよ
#include <stdio.h> main() { printf(“計算結果は %d と %d\n”, 2+3, 3+4); }
C言語のソースファイルは以下の要素から成る
プリプロセッサのコマンド
関数の宣言(定義)
main関数は必ず含まれる(無いとコンパイルできません)
変数の宣言・定義
コメント
プログラムに関する説明.無くてもプログラムは動くが,あった
方が嬉しい
C言語のソースファイルは以下の要素から成る
プリプロセッサのコマンド
関数の宣言(定義)
main関数は必ず含まれる(無いとコンパイルできません)
変数の宣言・定義
コメント
プログラムに関する説明.無くてもプログラムは動くが,あった
方が嬉しい
空白と空行
以下のコードを入力した prog3.c というファイルを作成
して,実行せよ
#include <stdio.h> float tax(int x); main() { float z; z = tax(1000); printf("消費税は%.0f円です\n", z); } float tax(int x) { return(x * 0.05); }#include <stdio.h> float tax(int x); main() { float z; z = tax(1000); printf("消費税は%.0f円です\n", z); } float tax(int x) { return(x * 0.05); } プリプロセッサのコマンド コンパイルの前にヘッダファイルを読み込ま せるための命令 ヘッダファイルとは? 拡張子が .h のファイル. 複数のソースファイルに共通する情報(関数 や変数の宣言)が記述されている
#include <stdio.h> float tax(int x); main() { float z; z = tax(1000); printf("消費税は%.0f円です\n", z); } float tax(int x) { return(x * 0.05); } プリプロセッサのコマンド コンパイルの前にヘッダファイルを読み込ま せるための命令 ヘッダファイルとは? 拡張子が .h のファイル. 複数のソースファイルに共通する情報(関数 や変数の宣言)が記述されている ヘッダファイル 何回も書きたくない 情報が書いてある stdio.hではprintfが 宣言されている ソースファイル ・・・・ printf(“….”); ・・・・
#include <stdio.h> float tax(int x); main() { float z; z = tax(1000); printf("消費税は%.0f円です\n", z); } float tax(int x) { return(x * 0.05); } プリプロセッサのコマンド コンパイルの前にヘッダファイルを読み込ま せるための命令 ヘッダファイルとは? 拡張子が .h のファイル. 複数のソースファイルに共通する情報(関数 や変数の宣言)が記述されている ヘッダファイル 何回も書きたくない 情報が書いてある stdio.hではprintfが 宣言されている ソースファイル ・・・・ printf(“….”); ・・・・ コンパイルしたいプログラム コンパイラ
#include <stdio.h> float tax(int x); main() { float z; z = tax(1000); printf("消費税は%.0f円です\n", z); } float tax(int x) { return(x * 0.05); } 関数の宣言 関数が返す値の型 関数名(引数)
#include <stdio.h> float tax(int x); main() { float z; z = tax(1000); printf("消費税は%.0f円です\n", z); } float tax(int x) { return(x * 0.05); } 関数の定義 返り値がある場合は return で返す セミコロンはない
#include <stdio.h> float tax(int x); main() { float z; z = tax(1000); printf("消費税は%.0f円です\n", z); } float tax(int x) { return(x * 0.05); } 変数の宣言(定義) 変数の型 変数名(= 初期値)
#include <stdio.h> float tax(int x); main() { float z; z = tax(1000); printf("消費税は%.0f円です\n", z); } float tax(int x) { return(x * 0.05); } 自作の関数taxの返り値を,宣言した変数zに代入 変数の型と,関数の返り値の型は同じ
C言語のソースファイルは以下の要素から成る
プリプロセッサのコマンド
関数の宣言(定義)
main関数は必ず含まれる(無いとコンパイルできません)
変数の宣言・定義
コメント
プログラムに関する説明.無くてもプログラムは動くが,あった
方が嬉しい
prog3.c の main と tax を逆順にして実行の可否を確認せよ
prog3.c の main を改名してコンパイルの可否を確認せよ
#include <stdio.h> float tax(int x); float tax(int x) { return(x * 0.05); } main() { float z; z = tax(1000); printf("消費税は%.0f円です\n", z); }
/* */で囲む(複数行にまたがる時に有効) or 先頭に//を
付ける
#include <stdio.h> float tax(int x); main() { float z; z = tax(1000); printf("消費税は%.0f円です\n", z); } float tax(int x) { // この税率がいつ上がるかで,このスライドの有効期間も決まる return(x * 0.05); }
C言語では変数の型(タイプ)を宣言する必要がある
Schemeには無かった特徴
型の種類
数値型
整数型(int,long,etc...) 実数型(float,double) C言語が型を適切に変換してくれる.以下の例では 15.0 と表示される 文字型(char)
C言語での「文字」の定義は「半角文字1個」のため以下の定義は不可 char a = string ; char a = あ ;(※ 全角文字は内部的には複数の文字になるため不可) z = 15;
if で もしも の処理を記述する
「条件」の真偽によって処理を分岐させる事ができる
条件の記述には「比較演算子」「論理演算子」が利用できる
論理和は¦¦,論理積は&&など 演算子の優先順位には注意が必要 if (条件) { 条件が成立する時の処理 }int total = 14; int absence = 3; if (absence <= (total / 4)) { printf(“You made it!¥n”);}
int total = 14; int absence = 3; int report = 7; if ((absence <= (total / 4)) && (report >= 7)) { printf(“You made it!¥n”);}
if...else で もしも...さもなければ の処理を記述する
「条件」の真偽によって二者択一の処理を記述できる
if (条件) { 条件が成立する時の処理} else { 条件が成立しない時の処理}int total = 14; int absence = 3; if (absence <= (total / 4)) { printf(“You made it!¥n”);} else {
現在時刻によって出力する挨拶を変えるプログラムを完
成させよ
#include <stdio.h> main() { int currentTime = 18; if(currentTime < 12) { printf("Good morning!\n"); } else if (currentTime < 18) { printf("Good afternoon!\n"); } else { printf("Good evening!\n"); } }?
現在時刻によって出力する挨拶を変えるプログラムを完
成させよ
#include <stdio.h> main() { int currentTime = 18; if(currentTime < 12) { printf("Good morning!\n"); } else if (currentTime < 18) { printf("Good afternoon!\n"); } else {printf("Good evening!\n"); }
for による繰り返し処理の効率的な実行
「処理続行の条件」は処理を実行する
前
に確認される
カウンタは処理を実行した
後
に確認される
e.g. 階乗計算
for (カウンタの初期化; 処理続行の条件; カウンタの増減指定) { 繰り返す処理の内容} main() {int seed = 5; int fact = 1; int i; for(i = seed; 0 < i; i-‐-‐) {
fact = fact * i; }
printf("Result: %d\n", fact); }
SchemeとC言語の比較
Schemeによる階乗計算のコード
(define fact (lambda (n) (if (= n 0) 1 (* (fact (-‐ n 1)) n)))) C言語による階乗計算のコード
int factorial(int x); int main(){ int seed = 5; printf("Result: %d\n", factorial(seed)); } int factorial(int x) { if (x == 0) {return 1; } else { return (factorial(x-‐1)*x); } }
Case-sensitiveである(大文字と小文字は区別する事)
mainとMAINは別ものとして処理される
(演習室の環境では)日本語を利用できるが全角スペー
スには注意すること
ダブルクオーテーション外に全角スペースがあるとエラーになる
main関数は必須でありmain関数から処理が始まる点に留意
空行・インデントを用いてコードを見やすくする事
エラーメッセージに手掛かりがある
メッセージを読んで原因を探る
エラーメッセージが示す行だけでなく,その前のコードを確認
1: #include <stdio.h> 2: 3: main() 4: {5: int total = 14; int absence = 3; int report = 6; 6:
7: if ((absence <= (total / 4)) && (report >= 7)) { 8: printf("you made it!");
9: } else {
10: printf("see you next year!"); 11: {
12: }
prog6.c: In function ‘main’:
prog6.c:12: error: expected declaration or statement at end of input prog6.c:12: error: expected declaration or statement at end of input コンパイル時のエラーメッセージ