配付資料
http://lecture.ecc.u-tokyo.ac.jp/~tohtake/1019.txt
プログラムの入力・コンパイル・実行のメモ
emacs ファイル名
gcc ファイル名
./a.out
参考
unix コマンド
| "man" | マニュアル表示 (ex. "man cp") |
| "cd" | ディレクトリ移動 |
| "cd .." | ひとつ上にディレクトリ移動 |
| "pwd" | 現在のディレクトリの場所を絶対パスで表示 |
| "ls" or "ls -a" | ファイル・ディレクトリの情報表示 |
| "mkdir" | ディレクトリ表示 |
| "cp" | ファイルのコピー |
| "rm" | ファイルの削除 |
| "rmdir" | ディレクトリの削除 |
| "emacs", "gnuplot" | それぞれの実行 |
| "fg" | 中断している仕事の復帰 |
emacsコマンドのメモ
| "Ctrl+x Ctrl+s" | ファイルセーブ |
| "Ctrl+x Ctrl+w" | 別名にしてファイルセーブ |
| "Ctrl+x Ctrl+f" | ファイルオープン |
| "Ctrl+x Ctrl+c" | エディタの終了 |
| "Ctrl+g" | 編集への復帰 |
| "Ctrl+z" | エディタの中断 (復帰は"fg") |
| 移動 "Ctrl+f" | 一つ前進 (forward) |
| 移動 "Ctrl+b" | 一つ後退 (back) |
| 移動 "Ctrl+n" | 一行下へ (next) |
| 移動 "Ctrl+p" | 一行上へ (previous) |
| 移動 "Ctrl+d" | 一つ消去 (delete) |
| "Ctrl+x Ctrl+c" | エディタの終了 |
参考
自宅からログインするためのメモ
自宅からログインする方法についてのECCSによる記述は
ここにあるが極めて不親切である。ここでも親切には解説できないので、詳しい人に聞くこと。
windowsの場合:
http://hp.vector.co.jp/authors/VA024651/download/file/putty-0.60-jp20070603.zip
をダウンロードし、解凍して、puttyjp.exeを実行する。ホスト名にux101.ecc.u-tokyo.ac.jpを入力して「開く」を押す。
MacOSXの場合:
アプリケーション:ユーティリティ:ターミナルを開く
ssh aa000000@ux101.ecc.u-tokyo.ac.jp
(aa000000の部分を自分のユーザ名で置き換えること)
と入力してリターンを押す。
第2回(10/26)
まとめ
課題
第3回(11/2)
まとめ
- 絶対覚えてほしいこと。
<for文の基本形>
for(i=1; i <= 10; i++){
print("%d\n",i);
}
<while文の基本形>
i=1;
while(i <= 10){
print("%d\n",i);
i++;
}
<do while文の基本形>
i=1;
do {
print("%d\n",i);
i++;
}while(i <= 10);
- 上記はたとえば次のように使う。どちらも1から10まで表示する。iが1ずつ増えながら、printfが10回繰り返される。
#include
int main(void)
{
int i;
for(i=1; i <= 10; i++){
print("%d\n",i);
}
}
課題1
課題2
第4回(11/9)
修正テキスト:
9. 応用: 関数のグラフ(修正gnuplot版)
(xgraphは現在のシステムでは利用できないのでgnuplotに変更したもの)
参考
課題
posix termiosを利用した例
サンプル 参考
curses ライブラリを利用した例
サンプル 参考
第5回(11/16)
まとめ:
- 関数の定義:まず関数の入力と出力を宣言する。たとえば、double func(double f,int n)は、「double型1つとint型1つの引数(入力)を持ち、double型を返す(出力)する関数func」を表す。
- 関数の中身(処理内容)はそのあとに{}でくくって記述する。
- プロトタイプ宣言:プログラム中で、関数の中身を記述する部分より前の部分で関数を利用するために、宣言の部分のみをプログラムの最初の方に書く。上の例で言えば、double func(double f,int n)の部分のみを書き、行末には;をつける。これによってコンパイラは関数の入力と出力を知ることができ、関数を呼び出している部分を適切に処理できるようになる。
- 関数の内部で宣言した変数は、その関数の外部には全く影響を与えない。複数の関数で同じ変数名を別の目的で使用してもよい。関数を使用する側は、内部で使用している変数名など、関数がどのように実現されているか(実装)については一切知る必要がない。関数を使用するには入力と出力だけを知っていればよい。このように関数同士の相互作用が無い事は、大規模なプログラムを作成する上で極めて重要な事である。
-
- 逆に言うと、関数から呼び出し側に結果を戻すには、内部で定義した変数は使えない。入力として受け取る引数もコピーが渡されるので、結果を戻すためには使えない。
-
- 関数から呼び出し側に結果を戻すには、a)返値、b)引数のアドレス(ポインタ)渡し、c)外部(global)変数の使用、の3つの方法がある。
- 返値:return(返すべき結果)。あらかじめ関数定義で出力として返す値の型を宣言しておく。1つの値しか返せない。
- アドレス渡し:結果を保存すべき変数のメモリ上のアドレスを引数として受け取る。
- 外部(global)変数の使用:(mainを含む)関数の外で定義した変数はglobal変数とよばれ、プログラムのどこからでもアクセスできる。しかしglobal変数はプログラムのどこで書き換えられるか分からないので、多用すると関数同士の相互作用が大きくなり、プログラムのデバッグが困難になる。
アドレス渡しを使う場合のポイント
- 引数の定義(下の例ではvoid neg(double *f)の2行)では受け取ったアドレスを格納するポインタ変数に*をつける。
-
- 関数を呼び出す側では、アドレス渡しする変数の実体を用意(宣言)する(double a)。これはポインタ変数では無いから*はつけない。
- 関数を呼び出す側では、当然ながら、宣言した変数は普通に(*をつけずに)使う。
- 関数の呼び出し(neg(&a))では、変数のアドレスを渡すため、変数に&をつける。
- 呼び出される関数では、アドレスを受け取るポインタ変数が引数の定義で宣言されているので、別途宣言の必要はない。
- 呼び出される関数では、アドレスはポインタ変数に格納されている。それが指し示す実体にアクセスするために、ポインタ変数名に*をつけて使う(*f=-(*f))。
- * は,掛け算を表わす演算子と,ポインタ変数の宣言と,それが指し示す実体にアクセスするときに使う間接演算子という三つの目的に使われるので、混同しないこと.
返値を使って結果を戻す例
double neg(double f);
int main(void)
{
double a;
a=1.0;
a=neg(a);
printf("%f\n",a);
}
double neg(double f)
{
return(-f);
}
アドレス(ポインタ)渡しによって結果を戻す例
void neg(double *f);
int main(void)
{
double a;
a=1.0;
neg(&a);
printf("%f\n",a);
}
void neg(double *f)
{
*f = -(*f);
}
課題:
1)図4 fahren.cを、華氏を引数として与えると、摂氏を返す関数をつかって書き直せ。
2) x=0近傍のsin(x)を5次のベキ上近似で計算する関数を作り、その動作チェックをするプログラムを作れ(scanfを使って実数を入力して、自作の関数と、C言語にもとから用意されているsin関数を使った計算結果を表示させる。sin関数を使うには#include
が必要。
3) アドレス渡しの関数を使って、2つの整数a,bを引数として与えると、aをbでわった商と余りを返す関数を作り、その動作チェックをするプログラムを作れ
4) quad2.cを改造して以下のようなプログラムquad3.cにせよ
・関数quadの仕様を次のようにする
引数: int型3つ(a,b,c)、float型ポインタ2つ(r1,r2)
戻り値: int型
a) 実数解が存在し、{重解でなければr1,r2が指すアドレスに解を代入し2を返す。重解ならば、r1,r2が指すアドレスに解(同じ値)を代入し1を返す}
b) 実数解が存在しないとき、複素数の解を求め、実部をr1が指すアドレスに、虚部の絶対値をr2が指すアドレスに代入し0を返す
c) aがゼロの場合、何もせず、-1を返す
・関数mainではquadの戻り値に応じて場合分けをして、結果をprintf文で適切に表示するようにする
5)2)のプログラムを改造して、xと近似の次数nを引数として与えると、sin(x)を計算するプログラムを作れ。sin(x)の対称性を考慮して、任意のxに対してよい近似で計算できるようにせよ。