プログラミング演習U 

Frequently Asked Questions (FAQ)

よく出る質問(とその答え)

1.  はじめに

 演習最初の講義はあくまで導入と課題の説明のため最小限必要なものに努めており、講義で全ての内容を教えようとはしていません。むしろ演習に多くの時間が割けるよう、なるべく30分以内に抑えようとしています。よって具体的な内容、コマンドの使い方等は教科書を各自見直してください。

 また、演習時間内に課題が完成していないのに計算機室から早々に引き上げていく人が多いですが、私やTAの板橋君がその時間帯にせっかくいるのですから、大いに活用してどんどん質問してなるべく演習時間内に課題完成を心掛けてください。

2.  {ポインタ、構造体、配列、fread、…}の使い方が分かりません

 やはりまず教科書・参考書を読みましょう(ビギナ−編では間に合わないかもしれません)。その上でもう一度プログラム例を見直してみて理解に努めましょう。それでも分からない点があれば(xxxが分からないではなく、このxxxがここでyyyなのが分からないともう少し具体的に)質問してください。

3.  期末テストの形式は?

期末テストはペーパーテストです。

期末テストは最後の週(2/3)に行なう予定です。今までカバーした内容の理解度を測ります。よってプログラムを組むことはありませんが、プログラム例のミスを指摘するぐらいのことはするかもしれません。

4.  ファイルの入出力

4.1          バイナリファイルがよく分からない

テキストファイル:表示できる文字のみ、バイナリファイル:表示できないデータを含む

テキストファイルが表示できるファイルに対して、バイナリファイルは任意の16進数で構成され、必ずしも表示できる文字は含まれません。また、テキストファイルは「行」で構成されていますが、バイナリファイルは「行」と言う概念がありません。テキストファイルの代表はCのソースファイルで、全て表示可能な文字で構成されていますが、これをコンパイルした実行ファイルはバイナリファイルの典型で、必ずしも表示できない16進数で構成されます。

たとえば以下のソースファイルを表示してみます。

$ cat test.c

#include <stdio.h>

 

void

main() {

        printf("This is a test.\n");

}

 

これを以前にも用いた表示コマンド、od(使い方はman odとしてオンラインマニュアル参照)を使って表示してみると

$ od -t x1 -c test.c

0000000 23  69  6e 63  6c  75 64  65 20  3c  73  74  64 69  6f  2e

          #   i   n   c   l   u   d   e       <   s   t   d   i   o   .

0000020 68 3e 0a 0a 76 6f 69 64 0a 6d 61 69 6e 28 29 20

          h   >  \n \n v  o   i  d  \n  m  a  i   n  (   )   

0000040 7b 0a 09 70 72 69 6e 74 66 28 22 54 68 69 73 20

          {  \n \t  p  r  i   n  t  f   (  "   T  h   i  s    

0000060 69 73 20 61 20 74 65 73 74 2e 5c 6e 22 29 3b 0a

          i   s      a      t  e  s   t  .   \  n  "   )  ;  \n

0000100 7d 0a

          }  \n

ここで、1行目は16進表示、2行目はその対応文字を表します。各16進数と文字との対応はASCII文字として標準が決まっています。以上のように、全て表示できる文字から構成されていることが分かります。一方、これをコンパイルした実行ファイルは

$ od -t x1 -c test_c.exe | head

0000000 4d 5a 90 00  03 00 00 00   04 00 00 00  ff  ff  00 00

          M  Z 220 \0 003 \0 \0 \0 004 \0 \0 \0 377 377  \0  \0

0000020 b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00

        270  \0 \0 \0 \0 \0 \0 \0 @  \0 \0 \0 \0 \0 \0 \0

0000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

         \0  \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0

と、必ずしも表示できない16進数が含まれています。

なお、以上の説明でもありましたように、表示できる文字のみで構成されているファイルも基本的にはバイナリファイルの一種とみなすことが出来ます。すなわち、テキストファイルもバイナリファイルの一種であり、全てのデータが表示可能文字で構成される特殊なバイナリファイルということが出来ます。

4.2          バイナリファイルの大きさとは何ですか(2003.1111

 バイナリファイルの大きさは通常バイト数で測ります。例えば

>ls –l ファイル名

でファイルの大きさを見ると、バイト数でファイルの大きさを教えてくれます。

4.3          ファイルのオープンでモードがrbでも”r”でも動くのは(ファイルを開けるのは)なぜですか?(2003.1111

どちらも読み出しでファイルを開くモードですが、”b”がつくとバイナリモードとなります。4. の項で述べたようにテキストファイルもバイナリファイルの一種なので、バイナリモードでも読み書きが出来ます。ただテキストモードをつけると行末の空白を自動的に取り除いてくれたり、ちょっと話が難しくなりますが、別のコンピュータから(例えばWindows Mac)持ってきたテキストファイルの改行コードを自動的に変換してくれたりします。

あえて”b”をつけて例題を挙げたのはWindowsではバイナリモードでないとうまくファイルが読み込めないためですが、Unixだけでプログラムする場合はつけなくてかまいません。

4.4          “EOF”の意味は何ですか?(2003.11.18)

EOFEnd Of Fileの意味で、例えばファイル入力関数の一部がファイルの最後まで読んでしまった場合、戻す値がEOFになります。EOFは実はstdio.hの中で、典型的には以下のように定義されています。

#define EOF (-1)

fputc, putc, fgetc, getc, fputs, fscanfなどの関数がファイル終了時にEOFを返します。他の関数はNULLを返します。どの関数がEOFを返して、どの関数がNULLを返すかは関数の仕様ですので、これらを利用する場合は必ずオンラインマニュアルかCのテキストで使い方をチェックするようにしてください。

5.  ccgccの差は(どちらを使えばよいの?)

gccでコンパイルしてください。しかし、ほとんどの場合、ccでも大丈夫なはずです。

計算機室のワークステーションで使うccはワークステーション製造元のSUN社が提供するCコンパイラで、gccはフリーソフトとしてボランティア団体が開発したコンパイラです。基本仕様は同じですが、ccは以下の特徴があります。

         1社で開発しているので、やや方言があります(他のコンパイラと微妙に違う仕様)。

         少し古くなりつつあります。(新いコンパイラを購入すれば良いわけですが)

一方、gccは以下の特徴があります。

         今でもボランティア団体が開発を続けているので、最新仕様のものがただで手に入ります(計算機室のものはやや古いですが)。

         各種の計算機用コンパイラが開発されている(各UNIXLinuxなどのPC UNIX含む、Windows他)ので、一つの計算機用に作成したプログラムは変更なしに他の計算機用に再コンパイルすれば動作する(可能性がある)。

6.  #define文で大文字の名前を使うのはなぜか?小文字はだめなの?

大文字で書く慣習になっています。

#define文は例えば

#define MAXLINE 80

と定義しておくと、コンパイラが実際実行形式に変換する前にプログラム内にMAXLINEが現れるところは”80”と数値で置き換えます。

例えば

int i = MAXLINE;

は変換前に内部で

int i = 80;

と機械的に置き換えられます。

このようにMAXLINEは変数名ではないので、変数と区別するために大文字で記述する慣習になっています。小文字でも動作しますが、変数名と区別するため大文字にする慣習に習ったほうが良いでしょう。

ちなみに#defineと同じ種類の役割をする命令に#includeがあります。

#include <ファイル名>

は実行形式に変換する前に指定したファイルをこの行の位置(通常ソースの先頭部分)に読み込んでからコンパイルします。

7.  exitについて教えてください。

7.1          exit( )はどういう関数ですか?

 プログラムの実行を強制終了する関数です。

exit(i)を実行すると、プログラムの実行が終了して、int型の変数iの値がオペレーティングシステムに戻されます。return(x)文と極めて似ていますが、return文は関数を修了して、呼び出し元にあらかじめ宣言してあった型の変数xの値を戻します。

7.2          以前の課題の例でexit( )文が#include <stdlib.h>なしで使われている

 正式には必要です。

gccだとそれでも注意だけでコンパイルできてしまうので#includeなしで使ってしまいましたが、おっしゃるとおり本当は必要です。

7.3          exit()の引数は何を基準に決めるのですか。

 exitの引数は任意のint型で、プログラマが任意に決定できます。通常は正常に終了時と以上終了時で別の値を返します。

 ちなみにstdlib.hの中では

#define EXIT_FAILURE 1

#define EXIT_SUCCESS 0

と宣言されているので、正常終了時は

exit(EXIT_SUCCESS);

異常終了時は

exit(EXIT_FAILURE);

としておくと、他の計算機に移植しやすくなります(他の計算機でもEXIT_SUCCESSなどが同じように定義されているため)。

8.  構造体を利用する利点は何ですか?(2003.11.18)

関連のあるいろいろな型のデータをひとつにまとめて扱えることです。特に大きいプログラムで、しかも複数のプログラマが共同作業で開発している場合、データの管理が大変になり、誤りの原因となります。そこで極めて関連の深いデータや、同じものに対する異なる型のデータを一まとめにして統一的に扱えれば、データ管理がしやすくなり、バグ(プログラムエラー)も減少することが期待できます。

少し話は難しくなりますが、構造体に関数(へのポインタ)も含むことが出来ます。構造体を定義するとき、その構造体を扱う関数郡も定義しておけば、その構造体を扱う関数も管理できます。つまり構造体1を扱うときは関数郡1を用い、構造体2を扱うときは関数郡2を用いる、といった管理が出来ます。これはオブジェクト指向に発展する概念で、C言語を拡張したC++でクラスとして実現されています。

9.  標準関数について

9.1    rand関数で発生する乱数列が何度実行しても毎回同じなのはなぜですか?(2003.11.25)

srand関数で設定する初期値(乱数の種)を同じすれば、毎回同じ乱数列が得られます。これはシミュレーション等で乱数を用いる場合、毎回同じ乱数列に対して異なる条件でシミュレーションを行なうことが出来るので、再現性が確保できます。乱数列を変化させたければ初期値を変更してください。ゲーム等で毎回異なる乱数列が必要なときは、システムの時計の値を実行時に読み込んで、これを適切な型に変換の上初期値として用いることがよく行なわれます。

9.2   srand関数の引数はどの様な意味があるのですか?(2003.12.2)

srand関数の引数は乱数列の初期値(乱数の種)で、これを同じすれば、rand関数で毎回同じ乱数列が得られます。これはシミュレーション等で乱数を用いる場合、毎回同じ乱数列に対して異なる条件でシミュレーションを行なうことが出来るので、再現性が確保できます。乱数列を変化させたければ初期値を変更してください。逆にゲーム等で毎回異なる乱数列が必要なときは、システムの時計の値を実行時に読み込んで、これを適切な型に変換の上初期値として用いることがよく行なわれます。

9.2    乱数はこれからの講義、実験、研究でどのように使われますか?(2003.11.25)

外来雑音をモデル化するのによく用いられます。例えば電気回路の熱雑音等のモデルによく用いられます。このほかにも音響雑音、誘導雑音、分子の揺らぎ等をモデル化するのにも用いられます。経済モデルの不確定要素のモデルにも用います。また、第10回の課題にもなりますが、乱数を用いて各種の関数値を数値計算する方法もあります。

10.   フローチャートはどのように使うのですか?フローチャートがわかりません。(2003.12.2

2年生後期までにフローチャートを見たことがないのは意外でした。フローチャートについて簡単にまとめた資料を用意しました。

11.   ソートについて

11.1     いくつかのソート方法(単純選択、バブル)を扱いましたが、違いは何ですか。2003.12.2

今回は簡単なソート方法しか扱わなかったのでそれほど大きな差はありません。それでもバブルソートはとにかく隣同士しか比較、交換しないので、極めて簡単な方法ですが、効率はソート方法の中で一番悪い方法です。単純選択法はバブルよりは若干効率は良いですが、大きな差はありません。それでもソートのデータ個数が多くなるとその差は歴然としてきます。

ソート方法はデータ処理では良く用いるので、効率の良い方法が数多く提案されています。興味のある方は、大変面白く奥の深い話題ですので、アルゴリズムの本などを参照してください。

11.2     バブルソートがわかりません(2003.12.2

バブルソートはソート方法の中では一番簡単で分かり易い方法だと思いますので、フローチャートの見方を勉強し、第9回資料に記載されているバブルソートのフローチャートをプログラムに組んでみて、その流れをたどって理解するよう試みてください。

12.   モンテカルロ法による積分について2003.12.9

12.1     なかなか理論値に近づかないのはなぜですか?乱数の数を増やせば理論値に近づくのですか?

実はモンテカルロ法の精度は乱数の精度に大きく依存します。発生した(x, y)の組が均等に範囲内に分布してくれれば良いのですが、標準関数のrand()はそれほど精度の高い乱数を発生してくれません。よって積分値の精度もある程度までで限界がきます。これ以上の精度を目指すのであれば、乱数の精度を上げる必要があります。rand()以上の精度の乱数を発生するアルゴリズムも各種存在します。興味がある方は調べてみてください。

13.   Fortranについて

13.1     FORMAT文の使い方がわかりません(2003.12.16)

かなりの方が今後Fortranを使うことがあると思いますので、やはりFortranの教則本を1冊は購入して呼んでください。

簡単に説明すればFORMAT文は入出力の書式を指定するもので、ちょうどC言語の例えばprintf文の第1引数、例えば

printf(“Answer is %d\n”,k);

の“Answer is %d\n”に相当します。上記の文をFortranで書けば

        WRITE(6, 600) K

600  FORMAT(‘Answer is`, I5)

となります。FORMAT分には通常文番号を付与し、入出力文でこの文番号を用いて参照します。上記FORMAT分の第2引き数が出力変数の書式を示し、上の例のI55桁の整数型を指定します。その他の型は第11回の資料を参照にしてください。

13.2     剰余の算出方法がわかりません(2004.1.27)

C言語では”%”演算子を使えば簡単に剰余が計算できましたが、Fortranにはこの演算子はありません。Fortranでは一般的に組み込み関数MODを使えば剰余を計算できます。例えば

INTEGER A, B, C

    C = MOD(A, B)

とすれば、ABを除算した剰余がCに代入されます。あるいは

INTEGER A, B, C

    C = A - (A / B) * B

でも剰余が計算できます。これは変数ABも整数型であるため、(A/B)は整数で行なわれ、小数点以下が切り捨てられます。これにBを乗算すると(A/B)より剰余を除いた数が得られ、これをAから減算すると剰余が得られます。検算のプログラムを組んで、試してみてください。

13.3     Fortranのオンラインマニュアルが表示できません(2004.1.27)

これはオンラインマニュアルの環境変数にFortranのオンラインマニュアルが含まれないからです。emacsを使って.cshrcファイル内のMANPATHの設定を以下のように変更してください。

変更前:

setenv MANPATH /usr/local/man:/usr/local/share/man:/usr/share/man:/usr/dt/share/man:/usr/openwin/share/man

変更後:

setenv MANPATH /usr/local/man:/usr/local/share/man:/usr/share/man:/usr/dt/share/man:/usr/openwin/share/man:/opt/SUNWspro/man

設定変更後、ログオンしなおしてください。以降、

man –s 3f intro

man –s 3f rand

などでFortranのオンラインマニュアルが表示されるはずです。

14.   課題の模範解答が欲しいのですが

 大体の方の提出が終わったところでWebに期間限定で公開しています。定期的にチェックしてください。

15.   レポートはどう評価するの?

 期限外や再提出になるとその度に減点していきます。期限外と再提出両方になったり、再提出を期限外で提出すると2点原点になります。出題後の5週間後の締め切りまでに受け付けられないと最低点の1点になり、提出しないと0点になります。再提出のチャンスは1回限りなのでプログラムを充分に見直して提出してください。

戻る

Created on    November 22, 2001

Last update on March 31, 2020