今日はプログラミングがあんまり、進んでない。
なんでかなーと思ったので、ここに、自分なりの考えを書いておく。
1.僕は全体像を捉える前に動いてしまうことが多い。後から、やってみて、出来なかったことに気付いて、手戻りが多く発生してしまっている。
→何故、そのやり方で上手くいくのか。自分の中で、納得のいく答えを出すようにしよう。
注意点としては、考えすぎて、思考が止まっていると感じることもあること。思考が進んでないなと感じたら、紙に書くようにして、前に進めるか。わからない所を小規模なコードを書いて、動作を確認するなどしよう。
2.理解できない現象が発生した時は、その対応策を自分なりに決めて持っておく。そうすると、迷わないので早い。
→以下、対応策
2-1.表示されているエラー文を読む。
意外と出来ていない。特に初めて見るエラーで数が多いと見ないことがある。その時は、最初に発生したエラーだけを熟読しよう。
2-2.以前、成功した事例を知らないか考える。
意外と、前回成功したパターンというのがある。闇雲に修正するよりも、前回を踏襲するのが安定して早いし、同じ失敗をしない。もし、パターンが無いのなら、まずWebで調べて、それでもなければ、自分で小規模なコードを書いてみると良い。それでも無理なら、知識不足なので、壁にぶち合っていることを周りの人にも言って、しっかりと知識を深めよう。
2014年8月27日水曜日
2014年8月11日月曜日
モダンC言語プログラミング
モダンC言語プログラミングを読んで、アウトップとしないと忘れそうなのでブログに書く
継承について
C言語で継承の機能を疑似的に使用することが出来る。これは構造体の先頭に宣言した変数はその内包されている構造体に変換することが出来る機能を利用している。
例えば、
struct Data {
int common;
int unique;
};
という構造体が会ったときに、commonのアドレスを知っていれば、そのアドレスを利用して、Dataのアドレスと認識させることが出来るということ。
これにより、先頭に宣言した変数に共用で使用するデータを定義し、2番目以降にそれぞれの処理に必要なデータを定義して、処理することが可能になる。これはC#のインターフェース機能とほぼ同等のことが出来ることを意味している。(ここの説明が難しい。。。)
この手法を利用して、様々なデザインパターンを利用することが可能になる。
デザインパターンについて
以下の5つのパターンがある
継承について
C言語で継承の機能を疑似的に使用することが出来る。これは構造体の先頭に宣言した変数はその内包されている構造体に変換することが出来る機能を利用している。
例えば、
struct Data {
int common;
int unique;
};
という構造体が会ったときに、commonのアドレスを知っていれば、そのアドレスを利用して、Dataのアドレスと認識させることが出来るということ。
これにより、先頭に宣言した変数に共用で使用するデータを定義し、2番目以降にそれぞれの処理に必要なデータを定義して、処理することが可能になる。これはC#のインターフェース機能とほぼ同等のことが出来ることを意味している。(ここの説明が難しい。。。)
この手法を利用して、様々なデザインパターンを利用することが可能になる。
デザインパターンについて
以下の5つのパターンがある
- Stateパターン
- テンプレートパターン
- オブザーバーパターン
- チェインオブレスポンシビリティパターン
- ビジターパターン
それぞれを簡単に説明すると
- Stateパターン → スイッチ文の代わりに状態のクラス₍構造体₎を使う。そうすると、状態遷移表がそのままプログラミング出来るので、バグが少ないし、実装しやすいし、網羅性も大丈夫だよ。というすごい組み込みで便利なパターン
- テンプレートパターン → メモリ確保と解放のようなセットで必要な処理を、必ず実施させる。コールバックを使った機能で、どんな時でも、メモリの開放を忘れないので、不要で不毛で無駄に時間のかかるバグを追いかけなくて済む涙が出るくらいありがたいパターン。ファイルのオープン、クローズ等何にでも使える。
- オブザーバーパターン →エラー処理などを呼び出すクラスと呼び出されるクラスで依存関係を分離出来る。コールバックを使っていて、呼び出されるクラスを不要に変更する必要を失くし、ファイルの肥大化を抑えるパターン
- チェインオブレスポンシビリティパターン→変数チェックなどの処理が複数ある場合に、呼び出すクラス側で簡単に順番を変えられるようにするパターン。配列のリスト構造に似ている。変数チェック等と同じ形式の関数で変数チェックをオーバーラップする感じのパターン(説明しにくいですね。。。)
- ビジターパターン → 二つの機能を一つのクラス₍構造体₎に持たせるときに、お互いに疎結合な状態にさせることが出来るパターン。それにより、拡張性、バグが減る、ファイルの肥大化を防ぐ、ソースが読みやすくなる等の様々なメリットが生まれる。コード量は少し増えそう。
まとめ
上記の機能を利用することで、様々なバグを減らし、無駄なデバッグ時間を減らし、ファイルの肥大化を防ぐことで、コードの可読性を上げることが出来る。デザインパターン最高!
以上が、自分なりにまとめてみた結果。忘れたころにまず、これを読み返そう♪
参考文献
本 モダンC言語プログラミング
本 モダンC言語プログラミング
2014年8月8日金曜日
eclipse CDT + googleTestでの開発環境
今日はeclipse CDTでの開発環境構築についてメモ
中々に時間がかかったので備忘録もかねて。
今まで、eclipse関係は最終的に失敗で終わっていたので少し嬉しい。
環境
windows 8.1
eclipse pledias fulledition 4.4
googletest 1.70
モダンC言語プログラミングのサンプルコードをテストした。
テストコードは何でもいいと思われる。
やったことは
中々に時間がかかったので備忘録もかねて。
今まで、eclipse関係は最終的に失敗で終わっていたので少し嬉しい。
環境
windows 8.1
eclipse pledias fulledition 4.4
googletest 1.70
モダンC言語プログラミングのサンプルコードをテストした。
テストコードは何でもいいと思われる。
やったことは
- eclipseのインストール
- MinGWのパスを通す(例 C:\Development\eclipse\eclipse\mingw\bin)
- 新規プロジェクト作成(ファイル→新規→C++プロジェクト)
- プロジェクト名を入力後、空のプロジェクト MINGCC を選択して、完了
- googletestのtopフォルダをコマンドプロンプトで開く(パス例 C:\Development\gtest-1.7.0)
- g++ -isystem include -I. -c src/gtestall.ccコマンドを実行 ※ -pthreadをつければ、マルチスレッドになるみたいだけど、POSIXの別ライブラリをインストールする必要があるのでやっていない。
- mkdir lib コマンドを実行
- ar -rv libgtest.a gtest-all.oコマンドを実行
- eclipseの作成したプロジェクトを選択して、プロジェクト→プロパディ の中の ツール設定→C/C++ビルド→設定→GCC C++ Compiler→インクルード に googletestのパスを通す(例 "C:\Development\gtest-1.7.0\include")
- 同じツール設定内の GCC C Compiler→Dialect→Language standardをISOC99(-std=c99)にする。
- 同じツール設定内の MinGW C++ Linker→ライブラリ ライブラリの検索パスにlibgtest.aのパスを通す(例 "C:\Development\gtest-1.7.0\lib\")
- 同じツール設定内の MinGW C++ Linker→ライブラリ ライブラリにgtestを登録する。これは先ほど作成したlibgtest.aのlibとaを抜いたもの。僕のようなwindowsしかさわったことない人間には意味不明だったが、linux系ではわりと普通のことみたい。
- 同プロパディ内のC/C++ 一般→パスおよびシンボル→ライブラリー・パスにgoogletestのincludeパスを通す(例 C:\Development\gtest-1.7.0\lib\)
- 同パスおよびシンボル→ソース・ロケーション→リンク・フォルダ で ファイルシステム内のフォルダーにリンクをチェックし、対象となるテストコードを選択(例 D:\data\study\modanCsamples\chapter04\chainOfResponsibility01)
- 以上で設定は終了
- 後はコンパイルが通るはずなので、コンパイルして実行してみてちょ。
実行結果画面
考察
・googletestはコンパイルして使う。必要なパス、インクルード、ライブラリを設定すると、コンパイルして実行できる。まとめると、それだけで、当たり前のことですね。それが中々、初めての時は落ち着かないと、道を見失ってしまっていけないですね(>_<)
・コンソール画面を見ながら、エラーを推察するのが非常に大切だと感じた☆
・後、googletestのreadmeをきちんと読んだら、答えのってました。英語はつい避けてしまうが、英語を忌避せずまずreadmeを読むようにしていこうーと思う♪
参考になったページ
http://blog.myspoon.info/2013/08/eclipse-cdtgoogle-test.html
参考にした本
モダンC言語プログラミング
2014年8月4日月曜日
VC++の共有メモリについて
共有メモリについて
1. 共有メモリで共有時のメモリ容量について
大容量のデータをコピーする際は書込先と読込元と2箇所でデータを展開する必要が有るため、必要なメモリ容量は3倍になるかもしれない。(検証要)
共有メモリを作成時に、書込側でデータをコピーする必要が生じるため、同じプログラム内で、2倍必要になる(検証済み)
※もちろん、コピー元のデータを最初から、共有メモリで宣言していれば、データのコピーが不要になるため、メモリ容量が増えることはないが、その場合、共有メモリの増減(バイナリデータのnew deleteに当たる)は排他制御の絡みで、制御が非常に難解になると考えられる。
2.共有メモリで共有できるデータについて
バイナリデータ、構造体、どちらも可能。
同じデータを共有する場合、dll内でメモリマッピングを利用して、データを両方から読みだすのが一般的みたい。先輩が言ってた。
3.C++とC#間のメモリ共有について
ネットを調べた限りは可能。基本機能はC++、C#共にWindowsAPIを利用しており、問題はない。但し、C#はメモリポインタを扱う概念が無いため、unsafeでポインタを利用する必要がある。もし、.net4.5を利用するならば、専用のクラスが実装されているので、そちらを使えば良さそう(検証要)
参考になったページ
http://devlights.hatenablog.com/entry/20101123/p1
まとめ
いろいろ考えたが、メモリ容量が大きいデータを扱う場合は、そのデータの3倍近いデータを扱えるメモリ容量がないと、共有メモリを利用するのは止めておいたほうが良さそう。
・構造体の共有は一般的に可能なようだ。
以上です!
1. 共有メモリで共有時のメモリ容量について
大容量のデータをコピーする際は書込先と読込元と2箇所でデータを展開する必要が有るため、必要なメモリ容量は3倍になるかもしれない。(検証要)
共有メモリを作成時に、書込側でデータをコピーする必要が生じるため、同じプログラム内で、2倍必要になる(検証済み)
※もちろん、コピー元のデータを最初から、共有メモリで宣言していれば、データのコピーが不要になるため、メモリ容量が増えることはないが、その場合、共有メモリの増減(バイナリデータのnew deleteに当たる)は排他制御の絡みで、制御が非常に難解になると考えられる。
2.共有メモリで共有できるデータについて
バイナリデータ、構造体、どちらも可能。
同じデータを共有する場合、dll内でメモリマッピングを利用して、データを両方から読みだすのが一般的みたい。先輩が言ってた。
3.C++とC#間のメモリ共有について
ネットを調べた限りは可能。基本機能はC++、C#共にWindowsAPIを利用しており、問題はない。但し、C#はメモリポインタを扱う概念が無いため、unsafeでポインタを利用する必要がある。もし、.net4.5を利用するならば、専用のクラスが実装されているので、そちらを使えば良さそう(検証要)
参考になったページ
http://devlights.hatenablog.com/entry/20101123/p1
まとめ
いろいろ考えたが、メモリ容量が大きいデータを扱う場合は、そのデータの3倍近いデータを扱えるメモリ容量がないと、共有メモリを利用するのは止めておいたほうが良さそう。
・構造体の共有は一般的に可能なようだ。
以上です!
登録:
投稿 (Atom)