\CAPTION\ |
\CAPTION\ |
ひな形は、このページからコピーしたりすれば一瞬で手に入りますが、
小中学校といろいろ覚えるときに、ひたすら繰り返しノートなどに書いて覚えたと思います。
一番最初のひらがなから。
それと同じです。意味がよくわからなくとも、打ち込み続けることで頭だけではなく指も慣れ、最後にはなかば無意識でプログラムが作れるようになると思います。<なった人
また、コピーは一瞬過ぎて、その内容を考える暇がありません。
打ち込む速度で考え、動かしてエラーが出たときにどこがおかしいのかを探し、直すことで、次第に意味が通じるようになります。
プログラムにはいろいろな形式があります。
最終的には、コンピュータが直接理解できる、01なデータの固まり(マシンコードとか、バイナリとか呼ばれます。)として実行されることには違いありませんが、たとえば、
A=B+C
と書いたり、
B+C→A
と書いたり、
BとCの合計をAに入れる
と書いたり、単に合計を求めるにもそれらしくわかる書き方がいくつかあるように、「指示の仕方」が何通りもあります。
指示の仕方の文法を取りそろえたものをプログラミング言語で、膨大な種類があります。
(すでに業界でよく使われるものがあっても、それなりに欠点があるので「俺様言語」を開発する人がたくさんいるので。その中から爆発的に広く使われるようになる言語もたまにあります。)
「プログラムをつくる」ということは
その観点からすると、プログラムの作り方を学ぶにはいろいろな言語が使えますが、ここではC言語を使います。
C言語(およびその改良版?であるC++言語)は幅広く使われています。
その特徴として、比較的「みてわかりやすい」言語でありながら、コンピュータの隅々まで指示できる「汚さ、泥くささ」をもった言語です。
情報系や計算系の立場的には、コンピュータのハードウエアにちょっかいを出すことは想定されていませんが、機械をコンピュータで動かそうというときには、ハードウエア操作も不可欠になります。
C言語の開発由来もそれ系で、いまでは、「組み込み」と呼ばれる機械に近いところで動くプログラムを書くときにはなくてはならない言語になっています。
一方、機械科のコンピュータ系演習科目で使われる頻度が高いFORTRANという言語は、主に計算向きです。機械制御などは想定されていません。
比較的文法などが(コンピュータからみて)単純で、演算の高速化(最適化=勝手に処理順序を入れ替えるなど)がしやすいとされています。
以前はスーパーコンピュータはFORTRANでなければ動かせないといわれてましたが、最近は普通にC言語も使えるようです。
たとえば、
「できること二つ」は組み合わせ次第で、いろいろな計算ができます。
ただし、実際にプログラムを作るには、言語ごとに「演算式の書き方」と「判断する対象の書き方」を覚えておく必要があります。
なお大前提として、プログラムは「半角英数記号」だけで書きます。全角はつかえません。
また、後述しますが、原則として各記述(数式など)の後ろには「;」(セミコロン)をつけます。
また、プログラムの中で 「/*」「*/」 で囲まれた部分(複数行のことあり)、1行のなかで「//」の後ろは「コメント」といって、無視されます。
メモ書きなどに使えますし、日本語もそこなら使えます。
表計算ソフトのセルにあたるものですが、あれに比べるとずっと制限がきつく、予め「○○の種類を入れる」と決めて、かつ、自分で名前をつけておかなければ使えません。
この講義で使うものは
整数や小数の変数を用意するときは
以下雑学:
今回の演習環境ではintは±20億くらい、doubleは有効桁数15桁(で10の±300乗)くらいの範囲が表せます。
蛇足ですが、いろいろな習わしの関係で、変数で「i,j,k,l,m,n」は普通は整数にします。
Σなどでもよく出てきますが。
C言語で普段使う条件による実行「もし〜なら〜する、さもなければ〜する」の系統は、大きく3種類が使われます。
関数は手順をまとめて使いやすくしたものなので、たまに(わりと)、
関数を自分で作ることもできますが、とりあえず、使い方だけ把握しておきます。
(種類を決めることで効率はよくなる。何を入れるかわからない容器よりは、わかっているほうが適切な大きさ、また、使うときに気を遣わなくなるため。名前は「自由につけられる」という利点。)
のみです。
C言語の本を見ると、いろいろありますが、実際問題、この2種類だけで各種計算はできます。
いろいろな効率を考えたり、人とやりとりするようなプログラムを作ろうしなければ、この2種でいいです。
int i,j,k,seisuu;
double a,b,c,shosu;
と書きます。複数を同時に作りたいときは「,」で区切ります。
小数に整数が含まれますが、普通はあえて、整数ですむものは整数ですませます。
一つは効率の問題です。1+1を計算したいときに、1.0000000+1.0000000と電卓を打つのは無駄です。
もう一つは、なんでも小数でやると、思わぬ失敗をすることがあるからです。
特に、直接的、間接的に回数を数えるときに小数をつかうと失敗する場合があります。
(有名どころとしては、0.1+0.1+0.1+...という計算で誤差が出る。<0.1は2進数で表現できない数:循環小数)
そこで「整数ですますべきところは整数ですませる」癖をつけておく必要があります。
使い方にもよりますが、困ることはあまりないかもしれません。
(たとえば、10の5乗に10のマイナス12乗くらいを加えると無意味、という問題が生じる)
習わしは文法でもないので、ある意味無視してもかまわないのですが、業界標準の習わしを無視すると、だれかに見せたりするときに誤解を招くことがあるので、普通は従っておきます。
習わしの重要な例で「赤と黒の電線があったらプラスは赤にする」というものもあります。
その慣例を無視して逆につなぐと、別の人が先入観で電源をつないで回路から煙があがることになります。
(俗に、iはinteger:整数のi, nはnumber of:個数のnでその周囲が使われているとか。
一般に、i,j,kは数を順番に数えるため、l,m,nは全体の個数を表したりするときによく使われます)
他にもC言語の本をみると、「演算子」という項目にいろいろありますが、とりあえず、これだけ把握しておけば、この科目はOKです。たぶん。
「=」の左辺は必ず変数でなければならない。
また、この式まで手順が進んだとき初めて計算されるので、常時この関係があるわけでもない。
※表計算では、つねにその関係が成り立つように見張っていて値の書き換えがあると自動的に計算するようになっている。
「()」で演算順序を優先できる。例:e=(a+b)*(c-d);
"%"は整数の計算で使われ、「割り算のあまり」となる。案外使い道がある。
同じく、「変数−−;」は1減らします。
※頻繁に使うので、専用の演算がある。コンピュータ固有の命令にもあることは多い。
例:1/5→0(1を5で整数の割り算すると0あまり1)、1/5.0→0.2、1.0/5→0.2
例:int i,j; i/jは整数演算、int i; double d; i/dは小数演算。
気をつけていないと、案外失敗の原因になる。連続するはずの数字がとびとびにでてきたり、比率を求めようとして常に結果がゼロにしかならないといったことを引き起こす。
一致が「==」と「=」を2回続けて書くことに注意。
「a!=b」は「等しくない」
それぞれ「成立していないとき」=「偽のとき」、「0」の値を持ち、「成立した=真」のときはゼロ以外の値になる。
これは、判断をする場合に「ゼロ以外は真、ゼロなら偽と見なす」というルールのため。
なお、代入の=ではないので、左辺が変数でなくとも(数値や式)だいじょうぶ。
それぞれの条件式は「()」でくくっておいたほうが間違いがない。
例:(a==b)&&(b==c) は「a=b=cのとき」を表す。「a==b==c」とは書けない(期待する結果にはならない)点に注意。
「!(条件式)」は真偽を反転させる。
おのおのの手順は、以下の2通りで書かれます。
と「;」で終わる一文。
数式が長くなって、複数の行に渡って書いても「;」までを一つと見なし、逆に一つの行に「;」で区切られて複数の式が書いてある場合もある。
ただ、原則として、一つの手順は1行で書く。
手順をひとまとめにしたもの。中括弧「{}」でくくる。中は空でも、1つでもかまわない。
これで一つの手順を同じ扱いになる。
いくつか{}でくくることによる利点はあるけど、主に、次の条件判断による実行時に大きな意味がある。
「
すぐ上の、手順ひとつかまとめるかという違いのみで、重要なのはifとelse。
「もし〜なら〜する」だけでおしまいなら、else以降は省略する。
なれるまでは、面倒でも後者の形式を使い、「if(){}」を基本パターンとして覚える。
「
まず、条件式をチェックして、真なら、手順を1回(1セット)実行する。
終わったら、また条件式をチェックして、真なら実行する。
チェックした段階で偽なら、実行をやめて、「手順/{手順}」のあとにすぐ移る。
(なので最初で外すと1回も実行されない)
「
この記述の場合、「i=0からn-1まで数えつつ、手順/{手順..}を繰り返し実行する」という意味。
結果的に、n回実行され。
バリエーションとして、
for(i=1;i<=n;i++) {} :i=1からnまで
for(i=n;i>0;i--) {} :i=nから1まで
がある。
while, for のなかで、これに到達すると(if(条件) break; などと使われることが多い)、強制的にwhile, forの中の処理をやめて終わってしまう。
「continue;」
while, for のなかで、これに到達すると、条件判断に強制的にもどる。
どちらも、{手順; 手順;}と複数の手順を並べているときのみ意味がある。
また、for(){}のなかにforを書くなど、多重になっているばあいは、今実行しているところで一番内側のforやwhileに作用する。
forの本来の姿。
forに付随する手順を実行する前に「開始手順」を実行、その上で「条件式」を判断して真ならば付随する手順を実行する。その後「繰り返し手順」を実行し、条件判断を再度行う。
上の項目は「開始時にi=0」「判断はi
関数には入力するもの「引数(ひきすう)」と出力の値「返値(かえりち)」があります。
b=sin(a);
は普通の数学の関数に見えますが、C言語的には「aという引数をsin()という関数に渡して、その返値をbに代入」と解釈します。
基本的に関数は、
関数(引数,引数,引数,...)
と「()」が必ずつきます。たまにある、引数のない関数は「関数()」と表記します(例としては「乱数を返す関数」とか)。
また、普通の関数は引数の数は決まっています(sin関数も値をいくつも与えない)。
関数();
とだけプログラムに書かれることがあります。
これは本当に手順だけをまとめていて、渡す値もなければ、戻ってくる値も使わないという状態です。
返値があっても、利用する必要はありません。また
b=sin(a)*cos(a);
のように、式の一部として使うことももちろんあります。
まず、cygwinのフォルダ(マイコンピュータ→Windows(Z:)→cygwin)を開きます。
ここにはすでに、makereportフォルダがあるはずです。
makereportフォルダのほかにprogramフォルダをつくります。
フォルダのウインドウで、「右クリック」→「新規作成」→「フォルダ」。
フォルダができて、「新しいフォルダ」と青く表示されていたらそのまま「program」(enter)と入力します。
青くならずに、ただ「新しいフォルダ」ができたら、フォルダを選んで「右クリック」→「名前の変更」で変更できます。
以後、作業はこのprogramフォルダで行います。
C言語でプログラムを作って動かすには、以下の3手順が必要です。
まず、先ほど作ったprogramフォルダを開きます(最初は空のはずですが)。
ここで「右クリック」→「新規作成」→「テキストドキュメント」を選びます。
すると、"新規テキストドキュメント.txt"とか、ファイル名が勝手についたファイルができるので、これを「prog1.c」に変えます。
(上のフォルダ名を変えるのと同じ操作)
変えようとすると「拡張子を変えていいんですか」的な確認を求められますが、そのままOKします。
すると、「C」と書かれたアイコンのファイルに変わります。
(中身は空のファイル、ただ、".c"をつけたことで、Windows的にはC言語用のファイルと思うことにした)
この際、もしも、"新規テキストドキュメント"に".txt"がついていない場合(右2枚目の青○の中:この例ではついている)、フォルダのウインドウのメニュー→「ツール」→「フォルダオプション」を開き(右図3枚目)、「表示」タブの「詳細設定」の下の方の「登録されている拡張子は表示しない」に「チェックが入っていたら」外してください(→適用ボタン)。もし、チェックがついていないのに表示されない場合は、相談してください。
開いたら(空ですが)、以下のプログラムを入力してください。
いれたら保存してください。
プログラムを作れるようになる、とは、成功や失敗を繰り返すことで、経験値を増やすことです。
以上で、ひとまずソースの作成は終了です。
参考:
このprog1.cファイルをダブルクリックすると(わりと時間はかかります)、VisualStudioが起動して、ファイルが編集できるようになります。
とりあえず、使い方の詳細は省きますが、Windowsの他のソフト同様、ファイルメニューで開いたり保存したりできます。
Ctrl-Sでも保存できます。
このファイルをTeraPadにドラッグアンドドロップすればTeraPadで開くこともできます。
※よってこの段々の隙間は「何文字」ということに気を遣う必要はありません。C言語対応のエディタの多くは、ある程度自動的に入れてくれます。VisualStudioでも、改行すると自動的にそれっぽい位置まで「TAB(タブ)」という空白の一種をいれてくれます。ので、それに任せるのが楽です。
文字を鉛筆で書いて覚えたように、プログラムもまた、キーボードから繰り返し打ち込むことで、なれて覚えてきます。
includeとかmainとかprintfとか、毎回出てくるようなキーワードもすぐになれます。
コピペですましてしまうと、おそらく、入力ミスなどに起因するエラーに遭遇することもありません。
それではなんのためにもなりません。今はよくても演習課題やレポートのときに、自分でできなくなる確率も上がります。
Visual Studioは本来C言語などの開発環境一式のソフトです。
そのエディタだけをつかっていますが、便利な機能として、適当なキーワード(たとえば、見慣れない printf とか)にカーソルを置いてF1キーを押すと、なんらかの解説がでることがあります。
実際には、あまりに関連する項目が多すぎて、期待するものではないかもしれませんが、使い慣れてくると、プログラムを作るときの辞書代わりに使えます。
デスクトップにコピーした「cygwinへのショートカット」を起動します(もしくはマイコン→Y:→cygwin→cygwinへのショートカット)。
(基本的にレポート提出の手順と近い)。
つぎに、$マークが出たら
そこで、
(gcc[スペース][マイナス][小文字のオー][スペース]prog1[スペース]prog1.c)
gcc がコンパイルするソフト(コンパイラ)、"-o prog1" は変換結果を "prog1"という名前で保存するように指示、"prog1.c"がコンパイル対象のソースのファイルです。
間違って、"-o prog1.c"とここで".c"をつけると、せっかく入力したソースが壊れる可能性があるので、気をつけてください。
まったく問題がなければ、何事もなかったかのように、また$がでます。
programフォルダをみると(F5を押すと)prog1.exeができています(残念ながらダブルクリックしても動きません)。
そうでない場合は、「error」とか「warning」とか書いてあるエラーが出てきます。英語で。
プログラムを作る以上、これらは避けて通れません。これになれるのも重要ですので、出たら、正面から向き合ってください。
英語ですが、よく見ると単純なことしか、普段はいってません。
必要なら、まずは単語を調べてみましょう。
→gooの辞書、
→英辞郎
ついでに、表示をみると、"line ??"と書いてあります。これはエラーが出た場所が何行目かを表しています。
エラーは直して、ソースを保存して、またコンパイルです。
この手のエラーのやっかいなところは、その行よりも前の間違いでもエラーがでることですが、まずは、指定された行をみてみましょう。
あっさりと「これじゃだめじゃん」な間違いに気づくかもしれません。
その際、cygwinのウインドウで「↑」(上矢印キー)を押すと、直前のコマンドをさかのぼって呼び出せます。覚えておくと便利です。
今回のプログラムはすぐに「$」が戻ってくるはずですが、表示が止まらないとか、なにもおこらないという場合は、プログラムが間違っていて暴走している可能性があります。
なお、それでもだめそうなときは、cygwinのウインドウごと消してしまってもかまいません。
期待通りのプログラムなら、
出力には様々な方法があります(ある意味、ロボットが動くのも「ロボットを動かすプログラムの出力の結果」)が、一番手っ取り早いのは、そのまま画面に数字等で表示してしまうことです。
ここでは、その代表格であるprintfを簡単に説明します。
本講義でも頻繁に使いますが、世の中でもよく使われています。
さて、printfは、以下のような使い方をします。
「"書式文字列"」は「"」でくくった適当な文字列(文字のつらなり)で、画面に表示される文字を決めます。
ただし、このままだと、表示はきれいにそろいません。整数は必要な桁数を表示するだけ、小数も適当な桁数表示するだけなので、桁数に応じて文字の数が変わったりします。そういうのを気にする場合は、
数値は、%dの場合は整数を、%fの場合は小数を、書式文字列内に%d,%fが出てくる順番に与えます。
この数値は、変数そのもの、ただの数値、数式などがつかえます。
次に、printfの行を
関数といっても返される値には関心はなく、もっぱら「便利な機能をまとめたもの」としての関数です。
それを端的に表す言葉として「printfデバッグ」(デバッグ=誤りによる不具合解消)という言葉があるくらいです。
プログラムは、コンパイルができれば(エラーなどがなければ)完全というわけではありません。
むしろ、たいていはそこがスタートラインで、そこから機能的に望んだものかどうかのチェックと修正という、最重要段階が始まります。
その際、動作が怪しいと思ったところで、とりあえず変数の値をかたっぱしから表示させて動作具合をみる、そもそもそこが実行されているか怪しいときに適当にaaaとか表示させてみる、ということを行います。それを称するのが「printfデバッグ」です。
ただし、一部に特殊な文字を含めることができます。
他にも多数ありますが、とりあえず、これだけは覚えておいてください。
これだけ覚えていれば、ただの計算をさせたりするには困りません。
(%d,%fがなければ、本当にただ文字を表示するだけになります)
を覚えておくといいでしょう。
小数点以下を「.0」とすれば見た目は整数になる。
例:printf("%d %f %d\n",整数,小数,整数);
間違うと、ぐちゃぐちゃな値が表示されます。
(printfに渡されるのは、あくまでゼロイチな組み合わせの値で、%dか%fかでprintfが解釈の仕方を変えるため)。
例:printf("%d %d %f\n",i,i*i,3.141592);
ただ、数式を書く場合は、整数のみの演算式だと整数に(%dに対応)、一部に小数が入ると小数に(%f)になることに注意が必要で、また、ただの数値も小数点があるかないかで変わります。
さらに、
printfの表示の意味がわかると思います。
その際、もとのprintfも参考のために残しておきたい、という場合は、
をします(右図参照、VisualStudioだと、//すると緑表示になる)。
せっかくなので、
変数jだけでは足りないので「j,k,l」もしくは「j1,j2,j3」と変数を増やす。
参考:2乗、3乗の演算をする記号はないので、単にi*iやi*i*iにしておくのが適当。
n=400あたりからマイナスが出始めるのは、「整数変数の桁数の限界」を超えるため。
sinにはラジアンを入れなければならないので、表示段階で度にしたほうがよさそう。
そのとき、わかりやすい角度単位で表示されるように工夫する。
インド式の九九は20×20らしいです。
表示を気にしつつ、つくってみましょう。
ポイント:
いろいろと小細工を考えてみた例: