Top Banner
プププププププププ 12 プププププ ププ
31

プログラミング入門

Jan 03, 2016

Download

Documents

Lester George

プログラミング入門. 第12回. 情報工学科 篠埜 功. 今日の内容. 便利な構文を紹介 for 文 コンマ演算子 増分演算子 ++ 、 減分演算子 -- (それぞれ前置と後置がある) ファイル処理. for 文. これまでは繰り返しのための構文としては while 文のみを紹介していた。繰り返し構文は配列を扱う場合によく使われる。. 配列の処理の典型的なプログラムの形 :. i = 0; while ( 条件式 ) { … 配列の処理 … i = i + 1; }. - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: プログラミング入門

プログラミング入門

第12回

情報工学科 篠埜 功

Page 2: プログラミング入門

今日の内容• 便利な構文を紹介– for 文– コンマ演算子– 増分演算子 ++ 、減分演算子 -- (それぞれ前

置と後置がある)• ファイル処理

Page 3: プログラミング入門

for 文これまでは繰り返しのための構文としては while文のみを紹介していた。繰り返し構文は配列を扱う場合によく使われる。

i = 0; while ( 条件式 ) { … 配列の処理 … i = i + 1; }

配列の処理の典型的なプログラムの形 :

このような形のプログラムを見やすく書くための構文として for 文がある。

Page 4: プログラミング入門

for 文の例(打ち込んで確認)

#include <stdio.h>int main (void) { int i, a[5]={1,2,3,4,5}; for (i=0; i<5; i=i+1) printf ("a[%d]=%d\n", i, a[i]); return 0;}

#include <stdio.h>int main (void) { int i, a[5]={1,2,3,4,5}; i=0; while (i<5) { printf ("a[%d]=%d\n", i, a[i]); i=i+1; } return 0;}

左と右のプログラムは同じ意味である。

Page 5: プログラミング入門

for 文の構文(基本形)for 文の構文

for (式 ; 式 ; 式) 文

for 文 for (e1; e2; e3) s の意味e1;while (e2) { s e3;}と同じ意味である。

(注意) 1999 年の ISO 規格 (C99) においては e1 のところに変数宣言( for 文内部でのみ有効)が書けるように for 文の定義が拡張されている。e1 のところが変数宣言の場合は、左の置き換えはできない。

Page 6: プログラミング入門

例(打ち込んで確認)#include <stdio.h>int main (void) { int i, sum=0, a[5]={1,2,3,4,5}; for (i=0; i<5; i=i+1) { printf ("a[%d]=%d\n", i, a[i]); sum = sum + a[i]; } printf ("sum=%d\n", sum); return 0;}

配列 a の要素の和を表示するプログラムである。

この例では、 for文の本体 ( 赤字部分 ) が複合文である。

Page 7: プログラミング入門

while 文を使った場合#include <stdio.h>int main (void) { int i, sum=0, a[5]={1,2,3,4,5}; i=0; while (i<5) { { printf ("a[%d]=%d\n", i, a[i]); sum = sum + a[i]; } i=i+1; } printf ("sum=%d\n", sum); return 0;}

前ページのプログラムをさきほどの説明の通り while 文で置き換えると左のプログラムになる。

(注)赤字の複合文の中括弧 { } を取り除いてフラットにしても同じ意味である。

Page 8: プログラミング入門

for 文の構文

for (式 ; 式 ; 式) 文

さきほど for 文の構文を以下のように定義したが、括弧内の3つの式はそれぞれ省略可能である。

1番目の式がない場合は、繰り返しの実行前に何もしないということである。3番目の式がない場合は、各繰り返しにおいて、for 文の本体の実行後、何もしないということである。2番目の式がない場合は、繰り返しの条件が真という意味である。

Page 9: プログラミング入門

例(打ち込んで確認)#include <stdio.h>int main (void) { for (;;) printf ("hello\n"); return 0;}

式を3つとも省略すると、 while(1) で置き換えたプログラムと同じ意味である。(無限に hello と出力し続けるので、 Ctrl-C で終了させる。)

#include <stdio.h>int main (void) { while (1) printf ("hello\n"); return 0;}

Page 10: プログラミング入門

コンマ演算子for 文の括弧内など、式が1つしか書けないところに2つ以上の式を書きたい場合に、コンマ演算子を用いて1つの式にする。

Page 11: プログラミング入門

コンマ演算子コンマ演算子を使った式の構文

式 , 式

式 e1, e2 の意味まず式 e1 を評価し、次に e2 を評価する。式 e1,e2 の値は、式 e2 の評価結果である。

式をコンマで繋いで得られたものも式である。よって式を3つ以上コンマで区切ったものも式である。(コンマ演算子は左結合)

式 e1, e2 の型 式 e1, e2 の型は式 e2 の型である。

(補足)つまり、 e1 の値は捨てられるので、 e1 に副作用(代入など)がないと無意味である。

Page 12: プログラミング入門

例(打ち込んで確認)#include <stdio.h>int main (void) { int a, i, j; a = (i=3, j=4); printf ("a=%d, i=%d, j=%d, \n", a, i, j); return 0;}

赤字の部分がコンマ演算子を使った式である。赤字の式の値は、式 j=4 の値、すなわち 4 である。これが a に代入されるので、 a の値は 4 となる。

Page 13: プログラミング入門

for 文に入れた例(打ち込んで確認)

#include <stdio.h>int main (void) { int i, j; for (i=0, j=0; i<4; i=i+1, j=j+1) printf ("i=%d, j=%d\n", i, j); return 0;}

赤字の部分が、コンマ演算子を使った式の例である。

Page 14: プログラミング入門

増分演算子(前置)前置増分演算子を使った式の構文

++ 式

式 ++e の意味代入式 e=e+1 と( e を一度だけ評価するという点を除いて)同じ意味である。

式 ++e の型 式 ++e の型は式 e の型であ

る。

式は、アドレスを持ち、かつ値が変更可能(代入式の左辺に書ける式)でなければならない。あと、式の型は、 1 との足し算ができる型でなければならない。

減分演算子 -- も同様に定義される。

Page 15: プログラミング入門

典型例#include <stdio.h>int main (void) { int i, a[5]={1,2,3,4,5}; for (i=0; i<5; i=i+1) printf ("a[%d]=%d\n", i, a[i]); return 0;}

#include <stdio.h>int main (void) { int i, a[5]={1,2,3,4,5}; for (i=0; i<5; ++i) printf ("a[%d]=%d\n", i, a[i]); return 0;}

for 文においてよく使われる。 i=i+1 の代りに ++i あるいは i++ (後述)と書くと、キーボードを打つ回数が若干減るので便利。(この例では式 ++i の値は使われないので、 ++i でも i++ でも同じ。)

Page 16: プログラミング入門

(参考) ++e と e=e+1 の違いについて

(注意)代入式において、左辺と右辺のどちらを先に評価するかは未規定である。したがって、 *(++p)=*(++p)+1 のように、左辺、右辺に関連のある副作用のある式を書くのは避けるべき。 ++(*(++p)) については、意味は一意である。

#include<stdio.h>int main (void) { int a[5]={10,20,30,40,50}; int *p, i; p=a; *(++p) = *(++p) + 1; for (i=0; i<5; i++) printf ("a[%d]=%d\n", i, a[i]); return 0;}

#include<stdio.h>int main (void) { int a[5]={10,20,30,40,50}; int *p, i; p=a; ++(*(++p)); for (i=0; i<5; i++) printf ("a[%d]=%d\n", i, a[i]); return 0;}

赤字の部分が e 赤字の部分が e

左のプログラムでは、ポインタ p の値は1回だけ 1 足されるが、右のプログラムでは2回、 1 足される。

Page 17: プログラミング入門

増分演算子(後置)前置増分演算子を使った式の構文

式 ++

式 e++ の意味e++ 式の値は 1 を足す前の e の値であるという点を除いて ++e と同じ意味である。

式 e++ の型 式 e++ の型は式 e の型であ

る。

式は、アドレスを持ち、かつ値が変更可能(代入式の左辺に書ける式)でなければならない。あと、式の型は、 1 との足し算ができる型でなければならない。

減分演算子 -- も同様に定義される。

Page 18: プログラミング入門

ファイル処理これまでファイルの操作は emacs あるいは cp, mv などのコマンドで行っていたが、 C 言語のプログラムでファイルを操作することができる。ファイルを操作するためのライブラリ関数が提供されている。 fopen --- ファイルを開く(ファイルをプログラムから扱えるように準備する) fclose --- ファイルを閉じる(ファイルを扱える状態においては、プロセスにおけるファイル用の表のエントリを1つ分占めている。それが解放される。) fprintf --- ファイルへの書き込み fscanf --- ファイルからの読み取りなどのライブラリがある。これらのライブラリ関数を使う場合は、 stdio.h をインクルードする。( printf を使う場合と同じ)

Page 19: プログラミング入門

例(入力して確認)#include <stdio.h>int main (void) { FILE *fp; fp = fopen ("test", "r"); if (fp==NULL) { printf (“オープン失敗 \n"); return 0; } printf (" ファイルをオープンしました\n"); fclose (fp); printf (" ファイルをクローズしました\n"); return 0;}

test という名前のファイルを自分で作ってから実行してください。

test という名前のファイルをオープンしてクローズするだけのプログラム。test という名前のファイルがない場合には「ファイルをオープンできません」と出力して終了。

Page 20: プログラミング入門

FILE 型ライブラリ関数 fopen, fprintf, fscanf, fclose においては、FILE 型のオブジェクトを介してファイルへのアクセスを行う。 FILE 型のオブジェクトにファイルへのアクセスに必要な情報(現在ファイル中のどこを読んで(書いて)いるかなど)が格納されている。 FILE 型の具体的なデータ構造は処理系によって異なる。

Page 21: プログラミング入門

ライブラリ関数 fopenfopen は、ファイル名とモードを引数にとり、 FILE 型へのポインタを返り値として返す。オープンに失敗した場合は NULL ポインタを返す。

[モード ] r --- 読み取りモードでオープン w --- 指定されたファイルがない場合は、書き込みモードでファイルを新たに生成してオープン。ある場合は、ファイルをオープンして、既存の内容を全部消す。

Page 22: プログラミング入門

ライブラリ関数 fclosefopen は、 FILE 型へのポインタを引数として受け取り、そのファイルを閉じる。

Page 23: プログラミング入門

ライブラリ関数 fprintf

第1引数に FILE 型へのポインタを受け取り、そこへ書き込む。第2引数以降は printf と同じ形式である。printf 関数は、 fprintf 関数の第一引数に stdout を指定した場合と同じ意味である。( stdout は標準出力を表す FILE 型へのポインタ。)

fscanf も同様。

Page 24: プログラミング入門

例(打ち込んで確認)#include <stdio.h>int main (void) { FILE *fp; fp = fopen ("test", "w"); if (fp==NULL) { printf (" ファイルをオープンできません\n"); return 0; } fprintf (fp, "%d+%d=%d\n", 1, 1, 2); fclose (fp); return 0;}

test というファイルに 1+1=2 と書きこむプログラム。

test というファイルがあったら、その内容は消されてから 1+1=2 と書きこまれる。

test というファイルがなければ、新たに作成されてから 1+1=2 と書きこまれる。

Page 25: プログラミング入門

ライブラリ関数 fscanf第1引数に FILE 型へのポインタを受け取り、そこから読み取る。第2引数以降は fscanf と同じ形式である。scanf 関数は、 fscanf 関数の第一引数に stdin を指定した場合と同じ意味である。( stdin は標準入力を表す FILE 型へのポインタ。)

fscanf は、第2引数によって指定されるフォーマットに従ってファイルから入力を読み取って変換し、第3引数以降に受け取ったポインタの指す先に(変換指定での照合が成功したら)代入する。変換指定と合わなかった部分は読み飛ばされ、 fscanf関数の呼び出し元へ戻る。行われた代入の個数が返り値として返される。

Page 26: プログラミング入門

例(打ち込んで確認)#include <stdio.h>int main (void) { FILE * fp; int num=0; char name [100]; double height, weight; double hsum=0.0, wsum=0.0; fp = fopen ("data", "r"); if (fp==NULL) { printf ("オープン失敗 \n"); return 0; }

/* 続き */ while (fscanf (fp, "%s%lf%lf", name, &height, &weight) == 3) { num++; hsum = hsum + height; wsum = wsum + weight; } printf ("平均身長 : %5.1fcm\n", hsum / num); printf ("平均体重 : %5.1fkg\n", wsum / num); fclose (fp); return 0;}

Taro 160.0 59.3Jiro 162.0 51.6Saburo 182.0 76.5Shiro 170.0 60.7

左のような内容のファイルを dataという名前で作成し、上記プログラムを実行すると、平均身長、平均体重が表示される。

Page 27: プログラミング入門

今日の課題1さきほどのプログラムは、身長、体重データをファイルから読み取って平均値を表示するプログラムであった。同じ形式のファイルからデータを読み取り、身長、体重の最大値を表示するプログラムを作成せよ。

Page 28: プログラミング入門

今日の課題2掛け算の九九の表をファイルに書き込むプログラムを作成せよ。ファイル名は自由とする。形式は以下のようにせよ。(ヒント)2重ループで書くと簡単です。

1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 3 6 9 12 15 18 21 24 27 4 8 12 16 20 24 28 32 36 5 10 15 20 25 30 35 40 45 6 12 18 24 30 36 42 48 54 7 14 21 28 35 42 49 56 63 8 16 24 32 40 48 56 64 72 9 18 27 36 45 54 63 72 81

Page 29: プログラミング入門

チャレンジ課題さきほどのファイル(名前、身長、体重のデータ)を、名前、体重、身長の順に並べ替えて新たなファイル(ファイル名自由)に書き出すプログラムを書け。名前、身長、体重のデータ間の空白などについて、入力ファイルと同一でなくてよい。fprintf の出力形式の例(各行): "%-6s %3.1f %3.1f\n"%-6s におけるマイナスは左詰めを表す。(名前の長さ等によって、最小フィールド幅の指定を変更すればよい。)

Page 30: プログラミング入門

本演習で扱わなかった内容• 共用体(実践編 p.162-165 )• 列挙体(教科書 p.190-193 )• ビット演算(教科書 p.164-171 )• 関数へのポインタ(ポインタの極意 第9章)• switch 文(教科書 p.54-57 )• do while 文(教科書 p.60-67 )• マクロ(教科書 p.96-97 )• 不完全型(実践編 p.27 )• 変数の記憶域期間(教科書 p.142-145 )• const 型修飾子 (教科書 p.133)• 複合代入演算子(教科書 p. 66 )これらについては、各自上記の教科書、参考書を参照してください。最終的には規格書を参照することになります。

Page 31: プログラミング入門

確認事項演習の1回目にもアナウンスしましたが、これまでに解けていない課題(各回2問ずつ)がある人は14回目の 16:20 までに TA に確認してもらってください。それ以降は受け付けません。