|
・今日はプログラミングしてないから、告知だけ。皆さん予想されてるとは思いますが、プログラミング辞書の新規単語受け付け休止期間を延長します(泣)。いやもーマジやばいって<説得力ない。とりあえず休止を7月一杯までということにします。まだ就職先が決まってないし、ゼミの宿題があるし、そしてテストがある! これ落とすとシャレになんないんで、そこんとこよろしくです、はい。
・でわまたっ! |
・今日はお休み。
|
・今日の授業は情報理論。当初は「プログラミングと平行してしてこー」とか言ってたんだけど、結局できずじまいですな。まー忙しいからなー、とりあえず今度のテストだけでも取れてないとやばいとゆー。マジヤバイよ。
・でわまたっ! |
・今日はお便りがふたつあるのでちょっと助かったり(爆)。ではひとつめ!
|
|
・どうもですー。で、ゲームって言ってもどんな機種のどんなゲームか分かんないと方法は色々ですよ(汗)。とりあえず機種はウィンドウズ、言語は C++ として話を進めてくと、基本的には DirectX とゆーものを使ってプログラムを組みます。 goo で「DirectX ゲーム プログラミング」で検索するといっぱい見つかるんで、そんなかの初心者向けっぽいのを手当たり次第みてくとサンプルコード含めていろいろ見つかってくとおもうです。
・実際には DirectX を間接的に使って簡単にゲームを作れるライブラリもあるし、 C++ を使わなくていいんなら HSP でもいいしさらにフラッシュムービーでもいいと思うんだよね。実際フラッシュなんてプログラム知らなくていいしマルチプラットフォームだし、ビジュアルノベルや恋愛シミュレーションならこのほうがいいと思うです。まーその辺は目的にあわせて考えてみるのがいいんじゃないかな。 ・では次のお便り! |
|
・初めましてー。まず一番考えられるのは、 ASSERT() 。 ASSERT() の中に式を入れていると、デバッグでは呼ばれて、リリースだと ASSERT() ごと中の式も削除されちゃうんで、それでエラーが出るってことがあります。なんで、 ASSERT() を取り除いたり、 VERIFY() に置き換えたりしてみてください。コンパイラのバグって可能性もなくはないです。「プロジェクトの設定」で最適化を「無効化」してみると動くとかあったりします。
・あと、リリースビルドでもコードデバッグすることができます。同じく「プロジェクトの設定」で最適化を「無効化」して「デバッグ情報」を「エディット・コンティニュー用のプログラムデータベース」に切り替えれば、リリースビルドでステップインとかできるはず(ややうろ覚えあり(汗)。間違ってたらごめん)。その辺は尺八郎さんのページとか「金菜さんの憂鬱」過去ログの1997年7月20日前後のを見た方がいいかも。その辺から原因を探してみてください。 ・でわまたっ! |
・今日もお便りがふたつ〜。ではひとつめ。
|
|
・うまくいきましたか、よかったです。やっぱし変数の初期化は必須ですかねー。基本的に C は「プログラマにできることはコンパイラがしない」スタンスだから自動初期化されないんですよねー。そー考えると new や delete の方がうまくできるのかもなー。ちなみに確か C# は自動的に0で初期化されるはず(笑)。
・もうひとつお便り。 |
|
・ gcc のヘッダー見てたら __GNUC__ ってのがあったんで、これで検索したらこのページが見つかりました。どうやら前者は __GNUC__ 、後者は __linux__ みたいです。これをフラグにできそうですね。試してみてくださいー。
・でわまたっ! |
・今日はお休み〜。
|
・今日もお休みです。むぅ。
|
・今日は久々にぷらとわ書いてました。いやーホント久々だ。ってゆーか土曜の休みが久々だ(汗)。今日は Ver 5.01 。新章突入ってところです。実はあさって配信分の次の回だったり(汗)。まさかストックが切れても決まってないとはなぁ……。で、新章ですが、この前のを題材にしようと思ってます。このくらいが一番いいレベルかな。
・つってもフツーには進めません(汗)。普通の本だとただやり方だけを紹介するんだろうけど、それじゃあかんかなー思うんです。ちゃんとした実力を着けることの方が重要かなと。なんで、ウィンドウズの仕組みとか、 MFC の中身とか、 API と C 標準ライブラリとの違いとか、そーゆー部分をしっかり見てきたいと思います。……だからこんなにゆっくりなんだな(汗)。 ・でわまたっ! |
・今日はお休み……。
|
・今日もお休みだよーん。
|
・今日はプログラミングしてないけどお便りが来てるから紹介しましょう。
|
|
・どうもですー。でも、背景ってなんのでしょう(汗)。ウィンドウだったら、 Win9x と NT は簡単にはできません。 WS_EX_TRANSPARENT は効かないってことですね。透明化するアプリあるけど、あれはたぶん、一瞬ウィンドウを非表示にして、スクリーンキャプチャして、再び表示させて、んでキャプチャしたのを貼り付ける、って仕組みだと思うです。 Win2000 なら簡単。 SetLayeredWindowAttributes() ってゆー API を使えばOK。詳しくはまぐろさんとこのを。
・ビットマップの背景を透明化するのは結構難しいんじゃないかなー。その辺はわては詳しくないんで。とりあえずイメージとしては、ビットマップと背景のふたつを用意して、透明度マスクを使って背景を表示するところだけに切り取って、重ね合わせる、って感じだと思うけど、実際に実装するのは大変そう。そーゆーのの解説してるページとかあるかもしんないんで探してみて。 ・でわまたっ! |
・今日もお便りが来てるからそれを紹介だぁ!!
|
|
・むむー、実はプリンタまわりは詳しくないのです、ごめんなさい。ただ「プリンタ出力ダイアログ」がプリンタドライバから表示されるものなら、それを表示せずにすますのはちょっと難しいかも。プリンタによって違うだろうし。ガッコのページプリンタはなんも出ないなぁ……。ページ設定関係のダイアログなら何とかなるんじゃないかな。 SDK 見ると「 CreateDC() を直接使えばいい」みたいなこと書かれてるから。うーん、でもよく分かんない……。
・もうひとつお便り。 |
|
・「スレッド処理」ってマルチスレッドのことかな? もしかしたら、アクティブなビューを操作するときに CView 派生クラスへのポインタを使ってるのかも。 MFC のハンドルラッパークラスはスレッドごとに情報を持ってるんで、スレッドを越えて使えないんです。だからこの場合にはアクティブなビューのクラスが持つハンドルを使って直接操作するのがいいんじゃないかな。
・あーあと「落ち方」とかどこで落ちるのかとか調べるのも重要かな。単純にアクセス違反で落ちるのと ASSERT() で止まるのとじゃまったく違うし。ただやっぱ、マルチスレッド関係はバグの原因を見つけにくいです。特に MFC はマルチスレッドに弱いんで意味不明のバグとか出てきそう(汗)。うまく「バグの出る部分」を囲い込んで原因を地道に絞るしかないかな。 ・でわまたっ! |
・今日もお便りが来てるっ!
|
|
・情報ありがとうですー! そいや MFC について触れてませんでしたな。って、まー知らないから触れらんないけど(汗)。 MSDN 見る限り、簡単そうだなー。でも解像度とかどうなんだろう。って、その辺調べ始めるとまた時間ないからよそう(汗)。
・でわまたっ! |
・今日もお便りを紹介っ!
|
|
・んでソースコード。
|
#include <stdio.h> void BinTreeSort(int Root); void DisplayData(int Root); #define MAXNUM 5 typedef struct{ char Name[64]; /* 名前 */ int Age; /* 年齢 */ float Height; /* 身長 */ float Weight; /* 体重 */ }STUDENT; STUDENT Stu[MAXNUM]={ {"太郎",19,162.5,65.4}, {"四郎",14,158.0,48.4}, {"五郎",18,182.0,82.5}, {"三郎",12,148.0,46.8}, {"次郎",16,178.5,70.0}}; int Upper[MAXNUM],Lower[MAXNUM]; main() { int Index; for(Index=0;Index<MAXNUM;Index++){ Upper[Index]=Index+1; /* Upper[0]=1,Upper[1]=2,Upper[2]=... */ Lower[Index]=-1; /* Lower[0]〜Lower[4]=-1 */ } Upper[MAXNUM-1]=-1; /* BinTreeSortの繰り返し終了用にUpper[4]=-1 */ BinTreeSort(0); DisplayData(0); } void BinTreeSort(int Root) { int Data,Next; /* ここにもう一行必要でしょうか? /* Data=Upper[Root]; if (Data==-1)return; Upper[Root]=-1; while(Data!=-1){ Next=Upper[Data]; /* この部分は間違っているかもしれません /* if(Stu[Data].Height>=Stu[Root].Height){ Upper[Data]=●●; Upper[Root]=●●; /* =Data かとも思ったのですが・・・ /* } else{ Upper[Data]=●●; Lower[Root]=●●; /* =Data かとも思ったのですが・・・ /* } Data=Next; } Data=Upper[Root]; if (Data!=-1)BinTreeSort(Data); Data=Lower[Root]; if (Data!=-1)BinTreeSort(Data); } void DisplayData(int Root) { if(Root==-1)return; ●● printf("%s %d %f %f\n", Stu[Root].Name,Stu[Root].Age, Stu[Root].Height,Stu[Root].Weight); ●●; }
・うみゃうー、分かりにくいー!!(爆) もちっとシンプルにした方が問題点が分かりやすそうです。それとも課題とかなのかな? だったら答を友達に見せてもらいましょう、こんなの解けても間違ったこと憶えるだけ(爆)。とっとと単位取って、授業は信じずに地道に勉強してかないとヤバイです。
・ふぅ、落ち着こう。えっとまず、 Upper と Lower をどんな風に使うのかがいまいち分かんないかな。たぶん配列の要素ナンバーを入れるんだと思うんだけど。 Upper と Lower は昇順と降順ってことなのかな。ってことは両方いっぺんに求めるってこと? 昇順で配列の要素ナンバーを入れるってことは、 2, 4, 0, 1, 3 みたいな感じに入るのかな。もしそうなら、まず昇順だけのプログラムとして作った方が見通しよくなるはず。あーでも、この構造だと2分木と全然関係なくなっちゃうね。それともこの構造を2分木にする必要はないのかな? ・とにかく BinTreeSort() は Upper と Lower が鬼門。特に Upper は操作に使う要素ナンバーまで格納してるから、この辺がかなり分かりにくいかな。●●にはたぶん、上から Data Root Root Data って入れるんじゃないかなぁ。たぶん(汗)。このあたりで、 Root と Data が何指してるのかがいまいち分かんないから、その辺をはっきり分かるように変数名を変えるといいかもしんない。特に、変数は「必要最小限のものを使い回す」んじゃなく、「意味が違ったら別に変数を用意する」ことが大事。つまりコードの読みやすさ重視ね。 ・ DisplayData() は printf() で出力してるから、この関数が Stu の中身を出力する関数だって事が分かります。さらに、要素ナンバーらしき引数を受け取って、さらにその引数をチェックして関数から抜けてることを考えると、この関数は再帰呼び出しすることが分かります。ってゆーかホントは再帰呼び出ししない方がいいと思うんだけど(汗)。ここは for で十分だろうなー。 ・で、単純に printf() 呼び出すと、単に Stu の中身表示するだけなんで意味なし。ここでは「ソートした結果」を表示する必要があります。 main() は DisplayData() に 0 を渡して呼び出してる、ってことは、この 0 を Upper の要素ナンバーとして使って、その要素を Stu の要素ナンバーとして使う、そうすれば「一番背の高いの」がまず表示されるはず。最初 Root には 0 、でたぶん Upper[Root] には 2 が入ってて、これを Root に入れて Stu[Root] ってすれば一番背の高い五郎君が最初に出るでしょ。 ・あとは 1 ずつ増やして DisplayData() を再帰呼び出ししてけばOK。ってゆーか、ここで Root の値を変えるのが混乱の元なんですね。だからホントは変数を新しく作った方がいいと思うです。可読性重視ね。あと、プログラムが分からなくなったら、細分化して小さな部分をまずクリアしていって、それを積み重ねていく、そういうプロセスが大事。たとえば Upper にダミーの値を入れて、 DisplayData() だけ先に完成させちゃうとかね。 ・うむ、まぁそんな感じ(汗)。とりあえずこっちには情報がないんで、出せるヒントはこんくらいかな。とりあえず余分なとこ落として、こつこつクリアしてく方が確実だと思うです。 ・でわまたっ! |
・今日もお便り〜。ここ最近ばしばし送ってくれるからネタ不足解消で大助かり(笑)。
|
|
|
//// プログラム //////////////////////////////////////////////////// #include <iostream.h> class Integer { private: int value; public: Integer() : value( 0 ) { } Integer( int a ) : value( a ) { } ~Integer() { } operator int() { return ( value ); } Integer &operator=( Integer &a ) { return ( operator=( (int)a ) ); } Integer &operator=( int a ) { value = a; return ( *this ); } }; int main() { Integer i; i = Integer( 456 ); // <== この書式は、特に問題ないのでしょうか? cout << i << endl; return ( 0 ); }
・どうもですー。さてこの問題だけど、これは正しい記述です。えっと、この例だと Integer( 456 ) に Integer 型のテンポラリ変数が作られて、 Integer( int a ) コンストラクタが明示的に呼び出されます。んで次の行で露と消えてしまうわけです。ただ、基本的にこーゆー使い方はあんましないです。クラスを関数みたく使いたいときかな(でもそしたら operator()() をオーバーロードするか)。
・通常このシステムは、関数に渡す時に使います。コンストラクタが explicit だったりコンストラクタの引数が2つ以上だったりすると、暗黙的変換ができないからこの方法でコンストラクタを明示的に呼び出す必要があります。他にテンプレート引数を明示するために使ったり、 const 参照にテンポラリ変数を作ってもらうために使ったりと、これも関数の引数に渡すときですね。要するに「クラスのコンストラクタを明示的に呼び出したい」ときに使う文法ってことですねー。 ・ MSDN だと「明示的に呼び出されたコンストラクタ」ってページに載ってます。あーあと、これはクラスに限らず使えます。 int( 100 ) とかできるってこと。デフォルトコンストラクタでも使えます。あと、どーっかで「テンポラリ変数を作らずに引数だけを作ることができる」ってゆーのを読んだことがあるような気がするんだけど、気のせいだったらしい(汗)。試したらそんなことなかったなー。謎だ。 ・でわまたっ! |
(C)KAB-studio 2000 ALL RIGHTS RESERVED. |