プログラミング・テクニック集



デバッグの達人になる!(プログラムがエラーで上手く動かない人の為に・・・)

プログラミングのミスで動作がおかしくなることがよくあります。このミスを取り除く作業を専門用語でデバッグといいます。
作文の校正、間違い探しパズルみたいなものです。(後者のように捕らえるとこの作業も結構楽しいかもしれませんね(笑))

プログラムを動かすとプログラミングのミスでエラーとなり実行が中断してしまうことがあります。
この時に表示されるエラーの情報を元にすばやく原因を解明する方法を紹介します。

まず、エラーメッセージの性質を知る必要があります。

「●●の一般保護違反です。」
「●●のページ違反です。」
「メモリコアダンプ・・・」(UNIX系)

これらは共にメモリアクセスに関するエラーで、配列やポインタの扱いが間違っていると起こるものです。

配列の要素数が4つしかないはずなのに5つ目にアクセスしたりしていませんか?
ポインタがらみの間接演算子、アドレス演算子の使い方は間違っていませんか?
ポインタが移動しすぎていませんか?

このあたりを念頭にプログラムを再確認すると必ず原因がはっきりするはずです。
 

「0で除算しました。」 これは計算式が間違っています。分母に0を使ってしまった場合に起こります。
 

また、エラーは出なくても動作がおかしいときがあります。

(例)同じ文字が画面に延々と表示されつづける

 いわゆる無限ループです(同じ所をぐるぐると回る)。for文などの制御文が間違っているか、再起的に関数の呼び出しを延々と行っていることが考えられます。

(例)割り算で小数部分が切り捨てられたり、その他の計算で式は合っているのに期待通りの値にならない

 変数の型の指定に誤りがあります。計算する数値の入れ物だけでなく、結果を収める入れ物の型にも注意してください。
 また、表示関数(printf関数など)の書式指定子が間違っていることも考えられます。「型」を念頭に隅々まで調べてください。

それでも原因がわからない!!

そんな時は原始的に対処しましょう!!

プログラムのあらゆるところに printf( ) 関数を入れまくるのです。そして、変数の値の変化を画面に逐次表示するようにします。
値がおかしくなった点、それが問題のある個所になります。
また、画面にデータをビッシリ表示するプログラムでは、画面表示された情報が次々と流れていってしまい、目が追いつけなくなることがあります。
そういったときは次の一文を任意の場所に入れてみてください。

getchar( );

こうすることで、キーボードからエンターキーを入力するまではそれ以降プログラムが進まなくすることが出来ます。(一時停止です)

また、デバッグツールというものも世の中にはたくさんありまして、変数の値の変化をprintf関数などをいちいち挿入しなくても把握することができ、任意の場所で一時停止させる機能を持ったものまで存在します。プログラミングの達人を目指すならこれらのツールにも精通することはプログラミングの効率を上げることにつながります。



無駄な処理(分岐命令編)

if( flag == 1)   ・・・・・

実はこれは同じことを2回していることになります。初心者でこの事実がピンと来る人はいないでしょうが・・・。
どういう事かというと、

「if文は( )の中身が0以外の時に実行する」という決まりになっているのです。
まず、
flag == 1
この式を評価します。
ここで、==の役割ですが、右辺と左辺が等しい時は1、そうでない時は0という結果になります。

flag が1のとき、この式は正しいということになり「flag == 1」の式が1に置き換わります。
次に、if(1)の式を評価します。これも正しいですからそのあとの命令分岐に従った処理を行います。

つまり、この場合、上の条件式と

if( flag )  ・・・・・

は等価となります。よくベテランプログラマーでこういう書き方をしていて初心者が「?」となることがあります。
でも、これは「同じ事を無駄に繰り返さない」という知恵みたいなものです。
また、if( flag == 0)  と反対の意味で使いたい場合は次のようにします。

if( !flag )

!マークをつけることで「否定」を意味します。(つまりnot、flag)



無駄な処理(文字列処理編)

次のような文字列を考えてください。

char string[100];

そして、文字列の先頭から6文字目から後を画面に表示したいとします。

すると、まず違う変数に6文字目以降をいったんコピーしてそれを表示させようと普通の人は考えます。
 
char temp[95];
int i;

for(i = 0;i < 95;i++)
 temp[i] = string[i + 5]; //1文字ずつのコピー処理

printf("%s",temp);

これでめでたく6文字目から表示されます。
しかし!!このプログラムはとっても無駄なことをしています。実は、たった1行で同じことが出来るのです。
 
printf("%s",&string[5]);

printf( )関数に与えている引数は文字列の先頭アドレスであることに気が付けばすぐに分かるはずです!!
同じようなことは他の文字列処理関数にも言えます。

(例)

strcpy( temp , &string[1] ); //文字列 string の2文字目より temp にコピーする
strncmp( &string[4] , "this" , 4); //文字列 string の5文字目より4文字を "this" と等しいかどうか調べる

このことが良く理解できる人はポインタも手にとるように分かる人でしょう(^_^)



Windowsのめちゃかっこいいプログラムを作りたい!

パソコンの技術の進歩は目まぐるしいのに、教育現場ではいまだにDosをはじめとした「白黒画面の文字と格闘する」プログラミングの勉強が中心となります。
「文字との格闘」も、プログラミングの基礎の勉強ですからもちろん必要なんですけど、こればかりしか知らないと「プログラムを組むのが嫌」という学生をたくさん生む結果にもなります。
プログラミングは楽しくなくてはやっていけません!(趣味としてやるにはね)では、どういうことをやれば楽しく感じられるのでしょうか?
まぁ、これには個人個人の感性などがあり「楽しさの求め方」にもいろいろあるでしょうが、一般的には「作っても使っても楽しいアプリケーション」を作ることが「プログラミングを面白くする」秘訣だと思うわけです。

個人で作れるアプリケーションとはどういうレベルのものでしょうか?ワードみたいなアプリケーションソフトも作ろうと思えば可能でしょう。しかし、個人でやるには仕事量が膨大になるでしょう。あれぐらいのレベルのアプリケーションは何十人というプログラマーが述べ数年という単位でもって作り上げたものです。
個人レベルで作れるものといえば、メモ帳程度のものか、住所録、メールソフト、あといろいろと便利なツールくらいでしょうか。しかし、これらのものでも十分実用に耐えうるものですし、アイデアの詰まったものなら「簡単なアプリケーションでも数千万円を一人で稼いだ」人も存在するというくらい、ある意味夢のある世界なのです。複数人でグループを作って比較的大掛かりなアプリケーションを作り、「学生のうちに一儲けする」のも面白いかもしれませんね。お金儲けに限らず、自分の作ったアプリケーションを無料で配布し、みんなに使ってもらい役立ててもらうことで自己満足も得られます。

では、本題です。どういったものを作ったら楽しいのでしょうか?やはり、マウスでも簡単に操作できるWindowsアプリケーションでしょう!作り方を学びたいのなら、「猫でもわかるプログラミング」というとっても役に立つWebページがあるのでそちらでじっくり勉強してください。

Windowsアプリケーションとは?

Windowsのアプリケーションは「イベント駆動型」といって、感覚的にはプラモデルを作るような感じでアプリケーションを作ることが出来ます。では、「イベント駆動型」とは何でしょうか?
例えば,とあるアプリケーションでWindow内にボタンが1つあり、これをマウスで押したら「音を鳴らす」というものを考えてみます。このプログラムでは以下の処理を行う必要があります。

(1)Windowを作り、画面上の任意の座標に表示させる
(2)Window内にボタンを作る(描画させる?)
(3)マウスでボタンが押されるのを監視する。押されたら音を鳴らす。

この中で(3)が「イベント駆動型」と呼ばれる所以です。「ボタンを押す」という「イベント」が発生すると「音を鳴らす」という処理を行います。
Windowsアプリケーションは「メニュー」や「ボタン」「コンボボックス」「スライドバー」などの(下のイメージ参照)部品を配置して作ります。そして配置したからにはそれらの入力・選択を監視する必要があります。このアイテム類の操作に応じて動くアプリケーションを作らなくてはなりません。
ダイアログボックスとアイテムのイメージ

このダイアログの作成は数分でできます。というか、画面を見ながらデザインするだけですから。
あとは、この各アイテムに番号を割り振り、アイテムが押されたりしたときに送られてくるメッセージからアイテム番号を抽出し、そのアイテムに見合った処理を行うだけです。
通常、Windowsアプリケーションを作るときは細かい「初期化」だの「登録」だのという処理が随時必要になり、縦長のなが〜〜いプログラムになってしまいます。ソースコードの見た目も結構汚くなってしまうかもしれません。しかし、最近のパソコンは性能が良いのでどんなややこしいソースを書いてしまってもストレスを感じないほどにちゃんと動いてくれます。

あと、C++が分からない人はSDK、分かる人はSDKかMFCというものを使って開発することになります。(VisualC++の場合)個人的な意見としてはSDKを使ったほうが分かりやすいと思います。MFCの方が作る作業自体は簡略化されますけど。