C言語の復習 コンパイルと実行 エディタでソースファイル hello.c を作成 #include <stdio.h> int main() { test.c printf("Hello!\n"); return 0; } コンパイラ コンパイル $ cc hello.c 実行 $ ./a.out Hello! a.out 実行可能ファイルの名前を指定する場合: $ cc -o hello hello.c $ ./hello ソースファイル 実行可能ファイル 画面へ出力 printf(書式,変数,変数,..); #include <stdio.h> %f %d %s double int char* (文字列) int main() \n { \t double x; int n; x = 1.234; n = 987; printf("x = %f\tn = %d\n", x, n); return 0; } 改行 タブ 書式の詳しい指定 #include <stdio.h> int main() { int n = 12345; double x = 12.12345678; printf("%d\n",n); 12345 printf("%8d\n",n); 12345 printf("%f\n",x); 12.123457 printf("%.3f\n",x); 12.123 printf("%9.3f\n",x); 12.123 return 0; } メモリと変数 番地 データ 1000 1001 1002 1003 1004 1005 1006 1007 … 番地 データ 23 int x; int y; 56 x = 23; y = 56; x 1000 y 1004 変数とポインタ 番地 データ x 1000 y 1004 z 1008 23 int *p; 56 99 x = 23; y = 56; z = x; 23 p = &x; … p 2000 int x, y, z; &x : 変数 x の「番地」 printf("%d\n",*p); 1004 1000 23 *p : ポインタ p の指す番地に 記憶されているデータの値 p = &y; printf("%d\n",*p); 56 *p = 99; printf("%d\n",y); 99 キーボードから入力 scanf(”書式”, &変数, &変数, ..); #include <stdio.h> %lf double int main() %d int { %s char* (文字列) double x; int n; printf("Enter double and int: "); scanf("%lf %d", &x, &n); %f ではだめ! printf("x = %f\tn = %d\n", x, n); return 0; } scanf() には変数の値ではなく変数のアドレス(番地) を渡す double を入力する際はかならず書式に %lf を使う 加減乗除 + - #include <stdio.h> int main() { int n, m; printf("Enter n,m: scanf("%d %d", &n, printf("%d waru %d n, m, n/m, return 0; } * / % "); &m); = %d amari %d\n", n%m); 整数 / 整数 は少数点以下を切り捨てた整数 整数 % 整数 は割り算の「余り」 インチをセンチメートルに変換 キーボードからインチ単位の数値を入力し センチメートルに換算して出力する プログラムを作成せよ。 1 inch = 2.54 cm 実行例 $ ./a.out inch ? 3.3 3.30 inch = 8.38 cm $ $ はシェルのプロンプト 太字がキーボードからの入力 if 文 #include <stdio.h> int main() { int m; printf("Enter m: "); scanf("%d", &m); if( m % 2 == 0 ) { printf("%d is even.\n", m); } else { printf("%d is odd.\n", m); } return 0; } m % 2 は m を2で割った余り 比較と条件式 等しいか? == != 大小比較 > >= < かつ、または && || #include <stdio.h> int main() { int m; printf("Enter month: "); scanf("%d", &m); if( m >= 1 && m <= 12 ) { printf("OK.\n"); } else { printf("error! no month: %d\n", m); } return 0; } <= if … else if … else … if(条件1) { 条件1が成り立てばここを実行 } else if(条件2) { 条件1は成り立たないが、条件2は成り立つ場合 } else { それ以外(条件1も条件2も成り立たない場合) } else if() { else { } は2つ以上あっても良い。 } は無くても良い。 西暦 --> 和暦変換 #include <stdio.h> 平成元年 = 1989 年 int main() 昭和元年 = 1926 年 { int seireki; printf("seireki?: "); scanf("%d", &seireki); if( seireki > 1988 ) { printf("Heisei %d nen\n", seireki-1988); } else if( seireki > 1925 ){ printf("Showa %d nen", seireki-1925); } else { printf("Wakarimasen\n"); } return 0; } 西暦 --> 和暦 大正、明治まで対応出来るように拡張してみよ。 大正元年 = 1912 年 明治元年 = 1868 年 うるう年 グレゴリオ歴 •4で割り切れれば原則うるう年(それ以外は平年)だが、 •100でも割り切れる年は平年 •さらに400でも割り切れる年はうるう年 1900 2000 2100 1904 2004 2104 1908 2008 2106 .. .. .. 1996 2096 2196 言い換えると •西暦が400で割り切れる年はうるう年 •それ以外で100で割り切れる年は平年 •それ以外で4で割り切れる年はうるう年 •それ以外(4で割り切れない年)は平年 キーボードから西暦を入力し、うるう年かどうかを 判定するプログラムを作成せよ。 コメント /* */ で囲った部分はコメント #include <stdio.h> /* comment test */ int main() { /* comments can span two or more lines */ return 0; } /* no error */ for 文による繰り返し for(初期化; 条件; 更新処理) { 文1; 文2; .. .. } 初期化を実行 条件が成り立つ限り 文1 文2 .... 更新処理 を繰り返し実行 #include <stdio.h> int main() { int j; for(j=0; j<10; ++j) { printf("%3d %6d\n", j, j*j); } return 0; } x += 3, ++j など x x x x = = = = x + a; x - a; x*a; x/a; x += 1; x -= 1; を を x x x x += -= *= /= a; a; a; a; と略記出来る ++x; x++; --x; あるいは x--; と略記出来る x = 3; y = ++x; x = 3; y = x++; x = 4; y = 4; x = 4; y = 3; x を増やしてから y に代入 x をy に代入してから x を増やす 出力のリダイレクト printf() は "標準出力" への出力。 通常は端末の画面に出力されるが、 リダイレクトにより出力先をファイルに変更できる。 $ command > filename $ ./a.out 2ページ前のプログラムを実行 0 0 1 1 出力は画面に出る ... 9 81 $ ./a.out > out.txt 出力を out.txt へリダイレクト $ cat out.txt 0 0 1 1 ... 9 81 1 から n までの和を計算 #include <stdio.h> int main() { int n, k, sum; printf("Enter n: "); scanf("%d", &n); 最初に 0 にするのを 忘れずに! sum = sum + k sum = 0; と同じ for(k=1; k<=n; ++k) { sum += k; printf("%4d %6d\n", k, sum); } return 0; } fprintf() 標準出力以外への出力 fprintf(出力先, 書式, 変数, 変数, ..); printf() と全く同じ 出力先として使えるのは stdout stderr 標準出力 標準エラー出力 リダイレクトしなければ どちらも画面へ出力される fprintf(stdout,...); は printf(...); と同じ fprintf(stderr,...); はエラーメッセージ等の出力に使う プログラム中から特定のファイルを開いてそれを出力先に指定することも可能。 (この講義では扱わない。興味があればfopen() の使い方を参照して下さい。) 出力先を使い分ける #include <stdio.h> int main() { int n, k, sum; fprintf(stderr, "Enter n: "); scanf("%d", &n); stderr へ出力 sum = 0; for(k=1; k<=n; ++k) { sum += k; printf("%4d %6d\n", k, sum); } stdout へ出力 return 0; } 標準出力だけリダイレクトする $ ./a.out > sum.txt Enter n: 10 $ cat sum.txt 1 1 2 3 3 6 4 10 5 15 6 21 7 28 8 36 9 45 10 55 $ stdout をリダイレクト stderr に出力した Enter n: は画面に出力される stdout に出力したものは ファイルに保存されている while 文 while(条件) { 条件が成り立つ限りこの部分を繰り返し実行 } #include <stdio.h> #include <unistd.h> int main() { int k; k = 10; while( k > 0 ) { printf("%3d\n", k); sleep(1); --k; } printf("%3d Go!\n", k); return 0; } sleep() を使うのに必要 1秒間待つ 銀行預金 #include <stdio.h> int main() { double yokin, riritsu, mokuhyo; int nen; fprintf(stderr, "Enter riritsu: "); scanf("%lf", &riritsu); 100万円が200万円以上に yokin = 100.0; なるには何年かかるか? mokuhyo = 2.0*yokin; nen = 0; while( yokin < mokuhyo ) { yokin += yokin*riritsu; 1年複利 ++nen; printf("%6d %10.2f\n",nen, yokin); } return 0; } 不定個数のデータの入力 データの個数があらかじめ解っていない場合どうするか #include <stdio.h> int main() データの読み込みを試み、 { 正しく読める限り繰り返す double x, sum; sum = 0.0; while( scanf("%lf", &x) == 1 ) { sum += x; } printf("total = %f\n",sum); return 0; } scanf() の戻り値は正しく読み込めたデータの個数 実行してみる ctrl-D を入力 $ ./a.out 1.1 3.3 2.2 total = 6.600000 $ 最後に ctrl-D を入力すると、最後の入力データまで 読んだと見なされて終了する。 入力のリダイレクト scanf() は "標準入力" からの入力。 通常は端末のキーボードから入力するが、 リダイレクトにより入力元をファイルに変更できる。 $ command < filename data.txt というファイルにデータを入力しておく $ cat data.txt 1.1 3.3 2.2 $ ./a.out < data.txt total = 6.600000 $ 演習 標準入力からデータを読み込み、 •データの個数 •データの総合計 •データの平均 を出力するプログラムを作る。 数学ライブラリ 平方根 べき乗 xy 三角関数 立方根 cbrt(x) sqrt(x) pow(x,y) sin(x) cos(x) tan(x) 逆三角関数 asin(x) acos(x) atan(x) atan2(y,x) 指数関数 絶対値 exp(x) 自然対数 log(x) fabs(x) #include <math.h> が必要 コンパイル時(正確にはリンク時)にオプション -lm が必要 $ cc xxxx.c -lm 例 #include <stdio.h> #include <math.h> int main() { double x; printf("Enter x: "); scanf("%lf", &x); printf("%f\n", sqrt(x)); return 0; } $ cc root.c -lm $ ./a.out Enter x: 2 1.414214 平均と標準偏差 x1, x2 , x3 ,..., xN N 個のデータ があるとする N 平均 1 M x xk N k 1 分散 x x V 2 1 N xk x N k 1 2 1 N 2 2 xk 2 x xk x N k 1 1 N 2 1 N xk 2 x xk x N k 1 N k 1 2 x x 2 x 2 x 2 平均と標準偏差 あるいは V x x x 分散 2 2 x x x 2 V x x 2 x x x 2 2 x 2 2 標準偏差 x 2 2 x 2 V プログラムでは まず 次いで S x1 x2 x3 ... xN T x x x ... x 2 1 S M N 平均 2 2 2 3 2 N T V M2 N 分散 を求め V 標準偏差 を求める
© Copyright 2024 ExpyDoc