- ベストアンサー
プログラミングの読み方、書き方のコツ
私はC言語を習って1年たつのですが 他人のプログラムを読んだり、自分でプログラムを書いたりするのが難しいです。 そこで私の場合、プログラムを読むときには メイン関数から読んだり、変数に数字を代入してみたりしています。 また、プログラムを書くときには わかりやすい変数を用いたり、インデントをつけたりしています。 みなさんはどんなコツを使って読んだり書いたりしていますか? いろいろ教えていただけるとありがたいです。 よろしくお願いします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
読む時: mainからざーっと読んで各関数のおおまかな処理内容を把握して何をするプログラムかを掴みます。で、注視すべき箇所のアタリを付けてそこから細かく変数や状態を追っていきます。 こねくり回した不思議な処理にぶつかると、文句を言いながら紙に状態遷移やらフローやらを図で書き留めて把握します。 書く時: 変数、定数、関数、ファイルなどの各種名称の命名方法について自分なりの規約を作り、その規約を徹底して守ります。 そうすることで他人にも読みやすいソースになります。(※半年後の自分も他人) それと同じで定義する場所などについてもルールを設けておきます。 これらのルールを決めるポイントとしては「自然かどうか」「斜め読みで把握できるか」「一般的かどうか」といった所です。(要は他人にやさしいかどうか) よく指摘される事に「関数はコンパクトに」というのがありますが、これは関数内の処理が長くなる=その関数が多機能になっている(か、鈍臭い処理になっている)という事なので、こんな状態では関数を端的に言い表せられなくなり、結果「斜め読みでは把握できない」という事になるからです。 (処理を詰め込むとバグの原因となる要素も詰め込まれる、多機能だと使い回しがしづらくなる、スクロールするうちに最初の処理を忘れてしまう!などの理由もある) あと、実際の作成手順は 1、プログラムの目的を明確にする 2、処理の概要を決める 3、必要な部品(画面、関数、クラス等)を設計する 4、コーディング 5、微調整 という感じですが、実際は一方通行ではなく1から5の間を行ったりきたりする場合が殆どです。 ホントはこれだけじゃなくて他人によるレビューやらテスト仕様の作成やらが入るんですが、大枠は上記のような感じでしょうね。
その他の回答 (3)
- matyrcry
- ベストアンサー率47% (101/213)
「同じ事では2度と悩まない」という”使い回しの美学”が重要ですよ。 ということで参考にならないかもしれないけど小技を。 ソフトを作ると使い回しのききそうな部分を部品化してファイルに残し てます。関数が多いですが、固定値なんかも。 私の場合は単位変換演算とか多いので、10のべき乗演算用に const int KETA_TBL[10] = { 1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000 }; 単にべき乗演算する以外にも数値の桁数調べたり特定の桁の数を拾った りと色々使ってます。 学生さんだとこういうのがいいのかな。 const int MONTH_DAY[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; const unsigned char HexMoji[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' }; itoa使えば済むんですが、ちょっと欲しいときにはこんなのも便利。 標準関数を覚えて使いこなすのが先かもしれませんが、自分で同じ機能 を作ってみるのもいい勉強になると思います。 // 文字列コピー(NULLまで) int ComStrcpy( char *dst,char *src ) { int cnt=0; while((*dst++ = *src++)!=0){cnt++;} return cnt; } デバッグ中でアドレス変数(たとえばint *ptr)の内容を見たいときには printf("Adrs=%08X \n",(int)ptr ); とかをよく入れてます。
お礼
どうもありがとうございます。参考になりました。
- hpsk
- ベストアンサー率40% (48/119)
「読む」 プログラム全体像を掴む場合は、mainから読む、というのは正しいと思います。 mainから順に降りていって、関数の呼び出し関係から流れを理解し、細部を知る必要があればそこも読む、という感じですね。 あと私がやっていることとは、 ・関数、大域変数の意味がわからなければ、grepを使ってそれらが使われているところを検索する。 ・あるていど大きなプログラムではcflow(関数の呼び出し関係を解析するツール)などのプログラム解析ツールも利用する。 ・できれば、gdbなどのデバッグツールを利用してプログラムを実際に走らせてみる。 というところでしょうか。 「書く」 インデントや変数名に関しては、コツというより必須事項では? という気がします。 #1の方が書かれているようなインデントのスタイルなど、細かい流儀に関しては一概にどれがいいとはいえないのですが、それでも最低限守ったほうがいいという事項はいくつかあると思います。 下記URLなどの情報も参考になりますよ。 私が重要だと思うことを一点あげておくとすれば、「コメントはサボらずにちゃんと書く」ということでしょうか。 特に、関数の外部仕様(どんな引数を受け取って何を返し、どんな副作用を引き起こすか)や、処理がテクニカルになったときの注釈は、最低限書くようにしています。 > プログラムを書いたりするのが難しい 確認ですが、「処理をどうプログラムかすればいいのかわからない」という御質問ではないですよね?
お礼
grepやcflowなどといった便利なツールがあるんですね。 どうもありがとうございます。
補足
>確認ですが 処理をどうプログラム化すればいいのかわからないというのが本音です。 その上でコツのようなものがあれば教えてほしかったという次第です。
C++ですが、私の書き方の簡単な例を挙げると //--------------------------------------------------------- //数値加算 int __fastcall TMainF::CountNum(int StCount, int EdCount) { int i, CntNum; //ループ変数・加算用変数 CntNum = 0; //開始値から終了値までの値を加算する for(i = StCount;i < EdCount; i++) { CntNum += i; } return CntNum; } //--------------------------------------------------------- になります。 構造としては 1:モジュールの上の行に簡単な処理内容を書く 2:変数設定と処理プログラムとの間は2行あける 3:「{」「}」はそれだけで一行を使う 4:「{」「}」を使った場合はインデントする。 詳細としては 1はそのモジュールでは何をしているかをわかりやすくするするため 2は変数設定と処理プログラムを識別しやすくするため 3は「{」「}」による区切りをはっきりさせるため 4は「{」「}」内の処理だというのをわかりやすくするため と言う理由です。 3に関してですが、 プログラム関係の本では「{」を関数の後ろにつけているのが多いですが、 これは別にしたほうが良いと思います。 その理由は「{」と「}」の数の不一致によるエラーが起きてもすぐに見つけられますし、 4との併用でif文等の処理がどこまでなのかも直に判別できますので。
お礼
{}をこのようなスタイルで書くのは初めて聞きました。 確かにその方法で書くほうが合理的でいいですね。私もまねしてみます。 どうもありがとうございました。
お礼
プログラミングの実際の容量が少しわかりました。 フローチャートすることで手順を明確にしてみたいと思います。ありがとうございました。