kengo700のナレッジベース

誰かの役に立つと思う情報を発信するブログ

機械系の学生へ向けたプログラミング実践入門

この記事は、研究を始めた頃の機械系の学生へ向けたものです。講義では学ばないプログラミングのコツなど、昔の私が知っていたらよかったな、と思うことをまとめていきます。

背景の説明

私たちの研究室は、機械系で主にロボットの研究をしています。研究においては、ロボットや実験装置の制御、データの解析などのために、C言語またはC++を利用しています。一部の学生はPythonやJavaなども使っています。大学の他の研究室では、今でもFortranを使っているところもあるそうです。大学の講義では、確かFortranとC言語の基本を学びました。

私自身については、大学入学前の春に引っ越しバイトでパソコンを買い、C言語の入門書で勉強してみていたので、プログラミングの講義には苦労しませんでした。しかし研究でのプログラミングはかなり大変でした。最近までGitを知りませんでしたし、プログラムのテストについては今でもよく分かっていません。

プログラム作成のポイント

自分でプログラムを書くときに気を付けたほうがいいことについて、箇条書きでまとめます。

仕様を明確にして、紙やホワイトボードなどに書く

  • プログラムを書き始める前に、仕様(何を実現したいのかなど)をはっきりさせます。
    • プログラムを書きながら仕様を考えてしまうと、迷走する可能性が高いです。
    • 考える作業と、コードを書く作業を分けましょう。
  • 数式やフローチャートを、パワーポイントなどを使ってまとめます。
    • 数式やフローチャートで表せない概念は、普通はプログラムにできません。
    • 作った資料は、ミーティングで進捗報告をするときにも使えます。
    • フローチャートの書き方は毎回ググりましょう。私も覚えていません。

ライブラリや他のソフトの利用を検討する

  • 実現したい機能が、公開されているライブラリ(便利なプログラム機能のセット)や他のソフトウェアで実現できないか検討します。
    • 私たち素人が自力で作ったプログラムを使うよりも、早くて確実で速いです。
    • 自力で作ると数か月かかるものが、ライブラリを使うと一日で実現できたりします。
  • 参考までに、私たちの研究室で利用しているライブラリやソフトウェアは、下記のようなものがあります。
    • ROS
    • ODE
    • Boost
    • OpenGL
    • OpenCV
    • MATLAB
    • etc.

他の人のコードを参考にする

  • ググるとサンプルコードが書いてあるホームページが多いので、それを参考に、必要な部分を修正します。
    • 一から自分で書くよりミスが少なくなるし、楽です。
    • ただし、公開されているコードが間違っている場合もあるので注意してください。
    • 重要なプログラムの場合は、書籍や論文などで確認してください。

少しずつ機能を追加して、動作確認する

  • 最終的に実現する機能を小さな機能に分解し、それぞれの機能を実現するプログラムを書き、少しずつ動作を確認していきます。
    • 全ての機能を一度に実現しようとすると、バグやミスがあったときに、原因を特定しにくくなります。
  • 具体的な動作確認の方法は、下記の通りです。
    • コンパイルできるか確認する。
    • 計算結果や変数の値を表示してみる(C言語の場合はprintf()など)。
    • 入力値に簡単な値(例えば0.0や1.0など)を入れて計算してみて、計算結果が正しいか確かめる(手計算と比べる)。
      • いきなりセンサのデータなどを使って動作確認すると、計算結果が正しいかどうかが判断しにくくなります。
    • ※詳しくは後述
  • これはロボットの製作など、他のことにも当てはまるかもしれません。
    • ロボットの製作の場合、すべて組み立ててから動作確認すると動かなかった時に原因が特定しにくいので、各モータやセンサごとに動作確認した後に組み立てます。

こまめにプログラムを保存・バックアップをする

  • 追記したプログラムをやっぱり直したい時などに、迅速に元に戻せるようにします。
  • フォルダごとコピーするか Git(バージョン管理システム)を使います。
    • Gitについては、検索すると色々な解説ホームページが出てきます。このブログでも「機械系の学生へ向けたGit入門」という記事を書く予定です。

プログラム言語の関数などは覚えない

  • 関数は覚えずに、使うときに毎回ググります。
    • 使用頻度が高い関数は、覚えようとしなくても自然に覚えます。
    • 全ての関数は覚えきれません。
    • 一つのプログラム言語を完璧に覚えても、陳腐化する可能性があります。
  • ただし、そのプログラム言語の最低限の知識が無いと、ググって辿り着いたページに書いてあることが理解できません。

コメントを書きまくる

  • コメント(C言語の場合は「//」)を、できるだけ多く書いておきましょう。
    • 数週間たってソースコードを読み直したときに、意味が分かるように
    • 他の人が読んでも分かるように
  • 私がコメントとして残しておいた方がいいと思う情報は、下記の通りです。
    • プログラムの概要、作成者、連絡先(メールアドレス)
      • ファイルの先頭やREADMEファイルなどの目立つところに書きましょう。
    • プログラム内でやっていること
      • 機能のまとまりごとにコメントを書きましょう。
    • 変数の内容
      • 各変数が何なのかをコメントで書いておきましょう。
    • 変数の単位
      • 特に、角度がRadianかDegreeかなどを書いておかないと混乱するし、バグの元にもなります。
    • 関数の機能と引数・返り値の内容
      • 関数の中身を読まなくても使いまわせるようにしましょう。
  • 「ソースコードを見れば分かることはコメントに書かない」と言われますが、私は書いた方がいいと思います。
    • 研究室の場合は、ほとんどがプログラミングの素人なので
    • 学生によって使っているプログラム言語やライブラリがばらばらなので
  • ※ただしコメントを書きすぎると、後からプログラムを修正したときのコメントの修正が大変になるというデメリットがあります。

デバッグ能力を磨く

  • プログラム作成にかかる時間のうち、デバッグする(書いたプログラムがうまく動かなくて原因を探す)時間が一番長いです。
  • ※具体的なデバッグのコツは後述

コードをたくさん書いて、たくさん読んで、慣れる

  • プログラミングの習得には、車の運転などと同じように、反復練習が必要です。
    • ソースコードを読むことに抵抗感を感じなくなるくらいまで
  • プログラム言語でも自然言語でも、慣れてない言語を読もうとすると目が泳ぎます。

その他

  • 意味が分かりやすい変数名をつける。
  • 機能ごとに関数やクラスに分け、後から再利用しやすくする。

デバッグのポイント

プログラムがうまく動かない場合のデバッグのコツなどを、箇条書きでまとめます。

追加したコードをコメントアウトして動作確認

  • 前述の通りに少しずつ機能を追加しつつ動作確認をしていれば、バグが発生したときは追加した部分が怪しいです。この部分をコメントアウトして動作確認してみましょう。
  • 怪しい部分が絞れない場合は、大部分をコメントアウトし、動作確認しながらコメントアウトを外していきます。

コンパイラのエラー出力を見て、ググる

  • コンパイルエラーを確認しましょう。
  • エラーの意味が分からない場合は、エラーメッセージをググりましょう。
    • エラーメッセージはほとんど英語なので、検索結果のページもだいたい英語ですが、頑張って読みましょう。

変数の値を確認

  • コンパイルは通るが、計算結果が正しくない場合は、前述の通り変数や計算結果を確認します。
    • C言語の場合はprintf()で計算結果や変数の値を表示してみる
    • 入力値に簡単な値(例えば0.0や1.0など)を入れて計算してみて、計算結果が正しいか確かめる

Visual Studioのデバッグ機能

  • Visual Studioは、プログラミングを行うためのエディタ,コンパイラ,デバッガなどをまとめたソフトウェア(統合開発環境)です。多機能なためとっつきにくいですが、慣れると非常に便利です。フリーのバージョンもあるので、使える場合は使いましょう。
  • Visual Studioにはデバッグを行うための下記の機能があるため、使いこなすことができればデバッグ効率が大幅に向上します。
    • ブレークポイント
    • 変数のウォッチ
    • ステップ実行
    • etc.
  • 使い方は、下記ページなどがわかりやすいと思います。

頻度が高いバグまとめ(主にC言語の場合)

  • 「;」や「}」の書き忘れ
    • コンパイルエラーに行数が表示されるはずなので、その付近をチェックします。
  • 配列の大きさの間違い
    • ログをとるための変数など、配列数が大きいときは注意しましょう。
    • 配列の添え字が0から始まることに注意
  • =(代入)と==(等号)の混同
    • if(i=0){}等とすると、コンパイルは通るが処理がおかしくなります。
  • 角度の単位の間違い(RadianかDegreeか)
    • sin()やcos()などを使用する際に単位を間違うと、コンパイルは通るが計算結果がおかしくなります。
  • パス(パソコンにプログラムやライブラリの場所を教える設定)の間違い
    • 引き継いだプログラムがコンパイルできないときなどは、パスの設定変更が必要な場合があります。

その他

  • ベアプログラミング
  • 情報を残し、共有する
    • 自分が遭遇した問題は、他の人が遭遇する可能性も高いため、解決方法をメモしておきましょう。
    • メモを研究室のメンバーが簡単に見れるところに置き、情報を共有しましょう。
    • 数か月後の自分のためにもなります。

プログラム解読のポイント

先輩からプログラムを引き継いだ場合など、他の人が書いたプログラムを解読するときのコツについて、箇条書きでまとめます。

プログラム解読に必要なこと

  • 時間、忍耐力
    • 他の人が書いたプログラムを理解するのは、非常に時間が掛かります。
    • 場合によっては自分で一から書いた方が楽なときもあります。
  • 最低限のプログラム言語の知識
    • 全く知らない言語で書かれたプログラムを理解するのは厳しいです。
    • その言語の入門用のホームページや本などに目を通しましょう。
  • プログラム作者によるコメント、資料
    • これがあると無いのでは、掛かる時間が全く変わります。
    • 資料がないと読み取ることが難しいものの例として、角度表現の定義、座標系の定義および変数の単位があります
      • この3つは、プログラム作成者が任意の設定ができるので読み取ることが難しく、また間違えたときに計算結果が全く異なってしまいます。
      • 逆に言えば、プログラムを引き継ぐときはこれらの情報を必ず残しましょう。
    • ※残念ながら、研究室ではあまりしっかりとした資料が残っていることは少ないです。

Visual Studioの検索機能

  • Visual Studioには下記の機能があり、使いこなすことができればプログラム解読の効率が大幅に向上します。
    • 前のカーソル位置に戻る
    • 変数・関数の定義・宣言へ移動
    • 変数・関数の参照(使われている場所)の検索
    • 複数ファイル内の文字列検索
    • 複数ウィンドウの表示
    • etc.

プログラム解読の基本的な方法

  1. プログラムの計算フローの初め(C言語の場合通常はmain関数)から順番に読んでいきます。
    • 前述のVisual Studioの機能を利用してプログラムの流れを追っていきます。
    • 分からないところ、重要ではなさそうなところはスルーします。
  2. 最後まで読んだら、また初めから読みます。
  3. 「2.」を繰り返します。

そのプログラムを書いた人に問い合わせる

  • 最終手段です。ですが、残念ながら書いた本人はプログラムの内容を完全に忘れているでしょう。

参考資料

下記のホームページ、書籍などを参考にさせていただきました(昔読んだものは記録をとっていなかったので、見つけたら随時追記していきます)。

関連記事

kengo700.hatenablog.com

おわりに

「実践入門」だなんて、ちょっとカッコつけすぎですね。