• ベストアンサー

良いプログラムを書くためには

今回、プログラミングの上達方法に関してアドバイス頂きたく質問しました。 現在、ソフトウェア開発の仕事に就いていてCやJavaなどでプログラムを書いたりしています。主にCで書くことが多いです。与えられた課題に対して動くプログラムは作れるのですが、先輩などからプログラムが汚いとよく指摘されます。 指摘される事柄は色々ありますが、何点か挙げるとまずモジュール分割が上手く出来ていない。1000行位の動くプログラムを書き始められた頃は、共通の処理などの関数が分割されておらず、同じ処理がやたら多いなど、余計な処理が多くコードに無駄が多いと指摘されました。それを改善したところ、今度は無駄に関数の分割が多くなり、読みにくいなどの指摘を受けました。 その他にも、例えば関数の中で、for(条件式)の条件式を上手く工夫すれば、for()の中で、余計な条件分岐などが減るなどの、細かい記述に関しても指摘を受けます。 質問はプログラムを作成する上で、大きな観点からだと、どのようにすれば綺麗にモジュール化などが出来るのか、モジュール化だけではなく、ソフトウェアの設計全般に関してです。また細かいことで、いえば先ほどのfor()の様に、文法を上手く使いこなすためにはどうすればよいか。本などのサンプルコードでは、forならfor、ifならifの説明など、主に単独の説明が多いように思えます。関数の中で、各文法同士を上手く使いこなし、他人が見ても読みやすいコードなどを書きたいです。 先輩からは、他人のソースコードを見ることなどと言われますが、何か他人のソースコードを見る上でも、上で挙げた指摘を改善するための見方とか、他にも自分でプログラムを作る場合に、こういう事に注意しながら作るといいなど何か改善するアドバイスがあれば宜しくお願いします。また参考になる書籍やサイトなどもあったら教えて頂くと助かります。 長くなりましたが宜しくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
noname#88772
noname#88772
回答No.6

こんにちは。 問題の解決についてプログラミングを行うにあたって以下の流れを通ります。 [読解] → [処理の分解] → [コーディング] 質問者さんはコーディングについての上達を目標とされているようですが、 プログラミング自体の上達にあたり、 上の流れの [読解]→[処理の分解] を鍛えることをお勧めします。 これはプログラム設計にあたります。 コーディング自体を鍛えると小手先のテクニックに凝ってしまいがちになります。 プログラムの全体を捉えることが重要です。 各流れは以下のようになります。 読解: 以下のことをハッキリさせる  ・問題を解決するために必要とされるアウトプットは何か  ・問題を解決するにはどのようなもの(データ等)が必要か 処理の分解: 以下の順序で処理を細かくしていきます。  1.問題解決の大まかな処理の流れを考える  2.処理を実現するにはどのような処理の流れに分解すればいいか考える  3.分解した処理について2.の処理を繰り返し、他人でも簡単に解るレベルまで噛み砕く この段階で同じ処理が出てきたりしますので一つの関数にまとめたりできます。 コーディング:  ・分解した処理を各言語に変換する 後参考に、コーディングについて私の場合はこうします ・各関数は100行程度に収めます ・main() では処理の項目の一覧を書く程度、または一関数のみにしています ・必要と思われるコメントは必ず入れます ・各関数の先頭コメントには用途、入力、出力、返り値を書きます ・他の人が見ても解るよう、可読性を重視して書きます ・各関数は他のプログラムにも応用できるように書きます ご参考までに。

gusu123
質問者

お礼

コーディングを行う前の設計が重要だということは解っていま したが、ではどういう風に考えていけばよいのか。という点が 曖昧でした。 よってyuji_syamiさんが教えて頂いた段取りの方法はとても参 考になります。この方法で設計を仕上げて、コーディングに入 る。 そういうプログラム作りに変えてみます。 ありがとうございました。

その他の回答 (5)

回答No.5

Javaなどのオブジェクト指向系で言ったら、「デザインパターン」ですね。クラス名、メソッド名などの命名規則なども含めて、デザインパターンの本に記載されているコードを参考にしていけば、まず外れることはないでしょう。もっとも、「デザインパターン」もまた万能のツールではないのですが、それを否定する人は余程のベテラン設計者でもない限りいないはずです。(それこそ、オブジェクト指向設計者さん達の試行錯誤による集大成とも言うべき代物ですから。) >関数の中で、各文法同士を上手く使いこなし、他人が見ても読みやすいコードなどを書きたいです。 ただ、上記のようにもおっしゃっていることから、「データ構造とアルゴリズム」に関しても一通り体系的に理解しておくことが必要であるように思われます。 >先輩からは、他人のソースコードを見ることなどと言われますが、何か他人のソースコードを見る上でも、上で挙げた指摘を改善するための見方とか、他にも自分でプログラムを作る場合に、こういう事に注意しながら作るといいなど何か改善するアドバイスがあれば宜しくお願いします。 Cなどで言ったら、Linuxカーネルとか、ネット上に転がっている大規模のオープンソースソフトウェアでしょうか?(ブラウザとか。) ただ、質問者さんの場合はもう既に実務に入られているわけですから、一番に参考にすべきは「同じ開発チーム内の先輩方のソースコード」だと思います。ちなみに、どの先輩方を参考にするかは以下を元にしてください。 ・よく指摘を受ける先輩(→自分を否定することになるので、あまりとやかくは言われなくなると思います。) ・その業務に長年携わっている先輩(→ベテランの方ですから、なぜそのようなコードにしているのかなど、ちゃんと理由を持っているはずです。) ・机の上がいつも綺麗な先輩(→几帳面さは、ソースコードにも現れます。)

gusu123
質問者

お礼

Javaでプログラムを組むこともあるのですが、胸を張って オブジェクト指向を使いこなせているとは言えません。 アドバイスの通り、オブジェクト指向も勉強し直します。 社内で、先輩のソースコードを参考にする際のアドバイス も参考になります。 ありがとうございました。

  • don_go
  • ベストアンサー率31% (336/1059)
回答No.4

質問の文章はgusu123さんの先輩の方々から指摘されている のと全く同じ理由で、とても読みづらい印象を受けます。 改行が少ない文章は、区切れがどこに有るかを解り難くし それだけでも読みづらい印象を与えます。 同じ語句の繰り返しと論点のまとまりのなさは、理解を 妨げると共に、読む気を失わせる原因にもなります。 自分が質問を受ける立場になった時に、読みやすいと感じる かどうか? もしも、自身が読みづらいと感じるようであれば、他の人に とってもやはり読みづらいと思って下さい。 単に、思い付くまま単語を並べるだけではなく、何度も読み 返し推敲する事を日常的に試みる様にして下さい。 やがては読み易い文章を短時間で書ける様になります。 #プログラムを作成する場合も同様です。 先輩からいろいろ指摘を受けていて、改善してみても別の事を 指摘されるとの事ですが、不具合の方向が真逆の両端をいったり きたりして、改悪を繰り返しているだけです。 本や他人のソース等を見て、多すぎたり少なすぎたりしない 様にいろいろと試行錯誤をして適当な所を探し出して下さい。 人間が楽に認識できるのは画面上で上下に1画面分スクロール するぐらいの範囲内といった話もあります。 モジュールの大きさを決める際の参考の1つにしてみては? また、数年後の自分は他人と同じという気持ちでプログラム を書く事が必要です。 #自分自身で数年前に作成したプログラムであっても、他人 #が書いた物の様に感じる事は良くあります。

gusu123
質問者

お礼

ご指摘ありがとうございます。 確かに、私の文章と比べて、don_goさんの文章は、一瞬見ただけで、 読みやすいと思わせてくれます。 文章、プログラムともに人に見せる前に、自分自身が本当に読みに くくないか。 何度も推敲する様に心掛けます。 指摘して頂いた当り前の事が、プログラムや文章を上達させるコツ でもあると感じました。 当り前のことが、まず出来ていない点も指摘して頂き、参考になり ました。 ありがとうございました。

  • R32C
  • ベストアンサー率39% (115/290)
回答No.3

古い本ですが、Myers本のひとつですが、「ソフトウエアの複合・構造化設計」 を入手可能ならお勧めします。 オブジェクト指向どころかC言語すらメジャーでなかったころの本ですが、 モジュール分割に関して、強度、結合度というものさしを用いてモジュールの 分割方法について、説明しています。

gusu123
質問者

お礼

モジュールを分割することは、プログラムのロジックを考える過程でもかなり大きな悩みとなっています。 紹介してもらった本で、モジュールの分割を体系的に学べそうなので読んでみようと思います。 ありがとうございました。

noname#259269
noname#259269
回答No.2

とりあえず「Cプログラミング診断室」という書籍を推奨しておきます。 http://www.pro.or.jp/~fuji/mybooks/cdiag/ 頑張ってください。

gusu123
質問者

お礼

紹介してもらったサイトを一部見させてもらいました。ソースコードがあり、悪い点を修正して学習する形態となっているようですね。 人のソースコードをあまり見たことが無かったのですが、こういう書き方だと汚いソースコードになるのかと思いました。 さらに改善策も紹介されているようなので、大変参考になります。 さらに読んでいきます。ありがとうございました。

  • tgook
  • ベストアンサー率48% (96/198)
回答No.1

一応、ソフトウェア設計を仕事やプライベートでやっている者です。 参考になるかは分かりませんが、 私はソフトウェアを作成する時、いきなりコードを書くのではなく、 最初は紙に以下のようなことを箇条書きに書きます。 (1)どういう動きをするものを作るのか? (2)インプットは何? (3)アウトプットは何? (4) (2)から(3)を得るにはどういう処理が必要? -> その処理の中に共通の動きをするものはある? (あればリユース可能にする) -> 関数化を検討 (関数は処理の内容ごとに分類。関数内の処理も一連の流れを決めて、その流れを守って作る。) (5)デバッグ あとは、コーディングやって、単体テストや結合テストなどをします。 コーディング作業は、やっぱり見易さを重要視して作業します。 (特にTabキーによるインデントや一行空けるなど。コメントも分かりやすく簡単に1行にまとめる。) こんな感じです。 何が正解かはやってみないと分かりません。 ただし、私でも1つだけ言えるのは、どんなソフトウェアを作るときでも、それは仕様書で決められている通りの、正しい動作をするものでなければならないということです。 納期やコストも大切ですが、上記に関しては手を抜いてはいけません。

gusu123
質問者

お礼

プログラムを書く前に、大まかにプログラムの構成などは紙に書きますが、tgookさんが行っているような手順は踏んでいませんでした。 これからプログラムを書く前には、アドバイスを頂いた手順も参考にして作っていきます。ありがとうございました。

関連するQ&A

  • シートのコード部を後からプログラムで作成可能?

    エクセル2003で、シートにプログラム(コード)がありシートを削除すると当然プログラムがなくなります。 シートはシートの挿入で新規に作成できますが、プログラム(コード)部を後から自動的に(標準モジュールの関数からソートのコード)を追加することは可能でしょうか? シートのコード部は主にイベントですが、詳しい方教えて下さい。

  • C言語のプログラムの質問です

    C言語で負の値が入力されたときに処理を終了する条件でキーボードから繰り返し入力するためにはどのようなプログラムにしたらいいですか? (FOR文を使い、FOR文の繰り返し条件を入れないで繰り返す)

  • システムプログラム

    最近情報科学に興味があって、システムプログラムについて1から勉強している者です。いくつかの質問のある参考書で勉強していますが、答えが書かれていないので分かりません。 用語については調べたりはしてみましたが、実世界と結びついた問題にはいまいち対応できません。まだ知識不足なので深い所までは理解できないかもしれませんが、徐々に分かっていけたらと思っておりますので、もし誰か分かる方がいらっしゃったら簡潔で結構ですので教えてください。ヒントやキーワード、考える観点だけでも構いません。 宜しくお願い致します。 1、近年プロセッサやメモリの著しい速度向上に対し、ディスクの速度向上は著しくない。仮想記憶を用いているオペレーティングシステムに対して、どのような変更を施すべきか? 2、WEBブラウザや表計算ソフトウェア等のプログラムは多くのモジュールからなり、いずれかのモジュールにおいてバグが発現した場合、プログラム全体が止まってしまう。このような問題を軽減するために、システムプログラムにおいて改善できる点は何か?また、ユーザプログラムにおいて改善できる点が何か? 3、ベクトルの要素をソートするMPIのプログラムを考える。どのようなプログラムを書けば、哲学者の晩餐問題に陥るだろうか。また、そのような問題を避けるためにはどのようにプログラムを書けばよいだろうか? 3問ともでなくとも、分かる問題があるようでしたらご投稿お願い致します。

  • プログラム構造化設計の問題について

    プログラム構造化設計の問題がどうしてもわからなくて困っています…ずっと考えているのですが…。 願書データ入力→応募ファイル更新→応募登録確認処理 という一連の流れを、モジュール分割してプログラム構造図・IPO図を作成するという問題なのですが、 応募登録という全体の作業の、どこをどう分割すればいいのかわかりません。入力と参照以外に何があるのでしょうか… 無知ですみません、よろしければヒント等お願いいたします。

  • 型が一致しない でも、プログラムは止まらない

    エクセルVBAにて 型が一致しない エラーのポップが出ます。 プログラムは中断していますが、OKボタンで プログラムは止まらず、その後の処理を実行します。 コードを表示した状態で デバッグを行いたいのですが、プログラムが止まらないので、箇所が特定できません。 自作フォーム、モジュール、タイマー、何でもありの状態ですが、そのまま、継続される・・・ってことが 場所の特定できる方法って 考えられるでしょうか 

  • CGIプログラムのデバッグ

    VisualC++5.0で、CGIのモジュールを作成してます。 これからで出来上がったプログラムのテストを行おうとして気づいた点があるのですが... この処理の中では、送信されてきたパラメータを解析しようと、 環境変数の"CONTENT_LENGTH"や"QUERY_STRING"を取得する処理をやっているのですが、 実際にVC++5.0のデバッガを動かしてみると、上の環境変数が設定されてない(当たり前ですが...) ために、null値しかこなくデバッグできずにいます。 VC++5.0のデバッグ機能で上の環境変数を設定しておきたいのですが、 何か良い方法はご存知ないでしょうか?

  • C言語のプログラムについて

    C言語のプログラムについて 3桁の自然数の中で、自分自身を含めた約数が奇数になるものがいくつあるかを求めるプログラムを作りたいのですが、swich文を使って、6通りの方法で出そうとしていまして、 while 文、 for文、 do while文に加え、 for文のを、1つの関数として独立させたもの、 さらに、for文のを重ループ部分のそれぞれのループに対応して、2つの関数として独立させたもの、 そして、この2つの関数のどちらともをループを用いずに再帰呼び出しを用いたもの の6通りで出したいのですが、swich文を使うところは自力でできたのですが、あとの6つそれぞれのプログラムの組み方がわかりません。 教えていただけないでしょうか?ややこしい書き方をしてすいません・・・。

  • 2つのプログラムを結合するテクニックについて

    2つのプログラムがあり、別々に動作しているものがありますが、これらを結合して別の1つのプログラムをつくることを考えています。結合のイメージは例えば、2つのプログラムが海の計算と大気の計算であり、それらを結合して海洋・大気計算プログラムとする、というようなものです。2つの計算は海面を通じて接していることになります。海面が両計算の共通部分となります。また、それ以外に円周率とか重力加速度とかネイピア数といったユニバーサルな定数も共通になるはずです。 このようなものを作成する場合、メモリ管理(モジュール)としてどのように作りこんでいくことになるでしょうか。海モジュール、陸モジュール、共通モジュールの3モジュールにするということなのでしょうか。つまり、海は海・共通モジュールで計算し、大気は大気・共通モジュールにするとかです。他に共通部分をグローバル変数として認識させるとか、あるいは副プログラム(関数かサブルーチン)の引数として表に出すとか方法はありそうですが、1つの数字ではなく、ある程度大量の配列変数になるはずです。 そのあたりのメモリの管理の考え方についてテクニックを教えて頂きたいのですが。また、海、大気それぞれがとりあえずちゃんと走っている場合、結合する編集部分を最低限(ミスも最低限になる)にするテクニックがあると助かります。 実際はFortran95系でコードにしますが、C系での考え方を参考にできると思っています。よろしくお願いします。

  • C言語に関することについて教えてください

    学校の問題集にでてきた問題がわかりません、どうか教えてください 1 プログラムの役割、必要性について説明せよ 2 プログラムにおける変数と定数の役割を説明せよ。また、ローカル変数の有効な範囲について説明せよ。 3 C言語で使う変数が他について、宣言子と、printf関数、scanf関数それぞれにおいて対応する書式指定子を対応表にせよ。また、変数名を決める際に守るべき文法上の規則と、プログラマとして配慮すべき事項を説明せよ。 4 配列について、その役割と定義方法を説明せよ。 5 コンピュータにおける文字処理に必須なアスキーコードについて説明せよ。 6 C言語における文字列について、文字列定数、文字列変数を説明せよ。 7 C言語における繰り返し処理の文法(for,while,do~while)を、プログラムコード列を示して説明せよ。 8 C言語における条件判断の文法(if,else,else if)を、プログラム列を示して説明せよ。 9 繰り返し、条件判断において利用する論理式(等値演算子、関係演算子、論理演算子等で記迷する式)について、その記迷の方法を論理和、論理積も含めて説明せよ。 10 変数のアドレスについて説明せよ。また、ポインタについて、アドレスとの関連性を踏まえて、その役割と定義方法を説明し、具体的な使い方のプログラムコード例を示せ。 11 ポインタと配列の関係について、ポインタによる配列操作を列に説明せよ。 12 関数について、その役割と定義方法について説明せよ(戻りがた、関数名、引数リスト)。また、自作関数をそれらを利用するmain関数のプログラムコード例を示せ。 13 scanf関数の戻り値について、その内容を説明して、どのような際に利用すると便利か、プログラムコード例を示して説明せよ。 14 引数にポインタを利用する関数のプログラムコード例を示して、ポインタの必要性、重要性を説明せよ。 15 構造体について、その役割と定義方法を説明し、具体的な使い方のプログラムコード例を示せ。 16 ファイルポインタについて説明し、ファイル入出力の方法についてプログラムコード例を示して説明せよ。

  • プログラムの再利用性について。

    プログラムはPerl,PHP,VBの初心者を抜けたくらいです。 一通り自作はできるけど、辞書片手、ネットで調べ調べのレベルです。 プログラムでモジュールやコードを再利用すること視野に入れて開発する事が有能とされていますが、一般レベルでは意識する必要があるのでしょうか? 一般ではHPにアップロードするのは一つな訳だし、個人のHPではモジュールの開発まではしないし、サブルーチンで十分。 ましてや、モジュールをアップする事も少ないですし。 例えば、書き込み処理を外部ファイル化して、掲示板と日記とかから利用するのは問題があると思うのですが。 例え同じ内容でも掲示板と日記それぞれで書き込み処理するファイルを作成した方がいいと思うのですが。 あ、一つの方がサーバのアクションが減ってサーバ的には負荷が少ない?? というか、エラー処理やヘッダーやフッターは基本的にどのCGIでもあまり変わらないので、コピーして使ってますよね? これは再利用と言えるレベルではないですよね。 みんな当たり前のようにやってると思うし。 私は書き込み処理やエラー処理、タグチェックも、基本は同じですがその都度変えてます。 その方がそのスクリプトにあった処理ができるからです。 その代わり、仕様のコメントを丁寧に書いています。 メンテナンス面には面倒と思うけど、基本は同じなので、その部分を変えればいいだけだし。 皆さんは、どういうものを再利用を意識して書いてますか?

専門家に質問してみよう