プログラミング所感 - 前へ 目次 次へ


01/01/11(木)

新年おめでとうございます。
21世紀からは「C++プログラミング所感」改め 「プログラミング所感」として新装開店します。
プログラミング関連では、次々と新しい話題が提供されてきます。 そこで、これからは C++ に限らないテーマも取り上げていこうと思います。

テーマは特定しませんが、C++、Ruby、C#、Java、XML、UML、XP、PSP、 データベース、Windows2000、CGI などになるでしょう。
(但し、基本的にスタンスは日記のままです。)


01/01/12(金)

「XPエクストリーム・プログラミング入門」 ケント・べック著 を読んだ。
お勧めである。最初の 5ページを読むだけで、 うならせるものがある。チームメンバ全員に読ませることにしよう。

XP の思想には、PSP(パーソナルソフトウェアプロセス) と通じるものがある。

「自分のプロセスを確立せよ。それを改善し続けろ」
ということである。また、共にはっきりと助言していることがある。
「一度に多くを変えるな。少しづつ変えていけ」
私も少しづつ XP を取り入れるようにしていきたい。
まず、「コミュニケーション」「シンプル」「フィードバック」「勇気」を紙に書いて貼るか。

01/01/15(月)

ブックマークについて。
ブラウザを使用していると、ブックマークに入れることも多いだろう。 私も結構すぐブックマークに入れてしまう。そのため、ブックマーク数が 多すぎて分かりにくくなってしまう。そこで、ブックマークをより使いやすい ようにリンク情報にコメントとキーワードを追加してデータベースとし、 キーワードで検索できるようにしてしている。 (具体的な使い方
今の所、リンク数は 1400 ぐらいになる。実際によく使うのは、5,6 個しかない。 しかし、「そう言えば、前、こんなのあったよな」と探すこともあるので たまには役に立つ。

便利であるが、キーワードの登録が面倒であった。そこで、今は、 ツールを作って簡単に登録できるようにしている。
具体的には、

  • ブックマークに入れたい。
  • タスクバーに登録しているツールを起動。
  • 自動的に、URL、タイトルが入っている。
  • キーワードは、いくつかの候補がチェックボックスになっているので、 それをチェックする。候補にないものもエディットボックスに入力できる。
  • OK ボタンを押す。
これだけで、検索が可能になるようにしている。 (ちなみに既に同じリンクがあるかどうかのチェックもできる。 チェックは包含関係も見ている。)
出力は、XML にしようと思った。 具体的には、
<?xml version="1.0"?>
<data version="1.00">
  <link title="" url="" date="" comment="" keyword="" />
  ...
</data>

を考えたが、わざわざ XML にするほどのことでもないと思いやめた。 もし、他に流用することがあればそのときに考えることにしよう。

とはいえ、実際には Yahoo 等の検索サイトの方が便利で、メリットも多い。 ブックマークは、どちらかといえば過去の履歴みたいのものである。


01/01/16(火)

SVG について。 Scalable Vector Graphics は、 Adobe が中心に策定した XML ベースの仕様である。なかなか、面白い。 (デモ)

驚いたのは、美しさとスピードと多彩さである。 デモを見るとアニメーション関係にも強そうである。 フラッシュなんかいらなくなりそうである。 見ていると自分でも作りたくなってしまう。
<?xml version="1.0"?>
<svg>
 <text y="10">
  test
 </text>
</svg>

で、作ってみた。何かボケているけどできた。簡単。
SVG もそうだが、これからはやはり XML が標準になりそうな気がする。 そうそう、XML 関連のリンクを作ってみた。


01/01/17(水)

ウィルスが記録的に流行しているらしい。
昨日、私の所にも来た。といっても、会社のウィルスチェッカーに引っかかって、 実際には、「ウィルスの添付されたメールが送られてきましたのでご注意下さい」 という案内しか来なかった。
また、そのメールが ML だったので、「ウィルスが付いてましたよ」という会員からの メールもいっぱい来た。 最近のウィルスはメールで来るものが殆どらしい。みなさん気をつけましょう。

01/01/18(木)

VC++6.0 に必要な DLL を ちょっと調べてみた。 「MFC(DLL) アプリ」を開発するのに必要なもの。
OLEPRO32.LIB
COMCTL32.LIB
COMDLG32.LIB
GDI32.LIB
KERNEL32.LIB
MSVCPRT.LIB
MSVCRT.LIB
OLDNAMES.LIB
OLE32.LIB
OLEAUT32.LIB
OLEDLG.LIB
ADVAPI32.LIB
SHELL32.LIB
URLMON.LIB
USER32.LIB
UUID.LIB
WINSPOOL.LIB

「MFC(スタティックリンク) アプリ」を開発するのに必要なもの。

LIBCPMT.LIB
LIBCMT.LIB
CTL3D32S.LIB
WININET.LIB
OLEPRO32.LIB
COMCTL32.LIB
COMDLG32.LIB
GDI32.LIB
KERNEL32.LIB
OLDNAMES.LIB
OLE32.LIB
OLEAUT32.LIB
OLEDLG.LIB
ADVAPI32.LIB
SHELL32.LIB
URLMON.LIB
USER32.LIB
UUID.LIB
WINSPOOL.LIB


01/01/19(金)

雑誌の広告を見てたら、 指紋認証付きマウスというのがあった。なんか未来的だ。
「ガタカ」という映画では、会社内に入るたびに血を抜き取って DNA を調べているようだったが、 それはちょっと嫌だな。プログラミングと関係ない話だ。

01/01/22(月)

最近、携帯電話が凄い。 とはいえ、私は持っていない。i-mode もやったことはない。
マイラインというので、電話会社の競争も激化している。 そこに加えて、インターネット電話も始まったらしい。 どうなるんですかね。また、プログラミングと関係ない話だ。

01/01/23(火)

ネットワーク型のアプリケーションを よく作る。そこで、テンプレートを作った。

VC++6.0 のインストール先が "C:\Program Files" ならば、 "C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Template" に解凍するだけでよい。 新規作成のプロジェクトの中に「Custom Network Application」 ができている筈だ。それを選んでビルドするだけで簡単なネットワークアプリができる。
デフォルトでノードの作成やアークの作成ができるようになっている。 無限アンドゥもできる。(デフォルトでは、20回までになっているけど)
例によって、graph.h を使っているが、まだ有向グラフにはきちんと対応していない。

誰かもっと良くしてくれると嬉しいのだが。
(参考:カスタムアプリの作り方)


01/01/24(水)

グラフクラスを直した。 (汎用グラフクラス)
昨日のやつに、graph.h をそのまま差し替えて使えるはずだ。たぶん。

今回の修正では、有向グラフを基本としたが、無向グラフでも使える。 使い方は殆ど変わらない。違いは、頂点反復子から接続しているアークを 取り出すときに使用するメソッドだけだ。有向グラフでは、i系(ibegin,iend,isize)と o系(obegin,oend,osize)を使う。無向グラフでは、無印系(begin,end,size)を使う。 実は、無印系は i系と同じなので間違って使ってもエラーにはならない。
無向グラフの違いでは、全てを i系で管理しているのだ。アークA を頂点 N1 から N2 に 引いたとしよう。有向グラフでは、N1 の o系に A を入れ、N2 の i系に A を入れる。 無向グラフでは、N1 と N2 共に、i系に A を入れる。

要はこういうことである。有向グラフでも、アークの向きを無視すれば無向グラフと 思って使える。但し、ノードに接続している全アークを走査するのに、無向グラフなのに i系と o系を見なければいけないのは判りにくい。そこで、無向グラフでは、 全てを i系にいれてしまい、無印系(実は i系)で走査できるようにしてある。
注意点は、有向グラフのときに無印系を使ってもエラーにならないが、 全アークを走査できないということである。使えないようにした方が親切なんだろうな。 (直すかな)


01/01/25(木)

デマルコの「デッドライン」を読んだ。 非常に面白い。お勧めである。ちなみに、一見、技術書のようだが中身は小説である。 アリストテレスの言葉はそれらしく響く。 考えさせられる点もいくつかある。
  • プレッシャーをかけてもアウトプットは増えない。
  • 残業を増やしてもアウトプットは増えない。
「闘うプログラマ」は実際の話だったが面白くなかった。 「デッドライン」の方が面白くてためになると思う。
億万長者のビルが出てくるが、このビルはなかなか好い奴そうだ。

01/01/26(金)

PSP 7A について。 Personal Software Process も 7A まで来た。ここで、ちょっとつまづいた。 「相関係数、t分布の値、確率」を求めなければいけないのだが、 確率(2*(1-p))が 1.80e-5 にならなければいけないのにならなかった。 ちなみに、Excel なら =TINV(1.8e-5,10-2) とすると、 9.052 になり、ほぼ t分布の値 9.0355 に合う。
同じプログラムでも g++ だと 1.80e-5 になる。VC++6.0 だと 2.05e-5 となる。 原因は、計算誤差のためである。g++ は double の計算中では 96ビットで計算しているようだ。 VC++ は 64ビットだ。このため同じプログラムでも差が出てくるのだ。
結局、VC++ でもシンプソン法の計算時の分割数の初期値を倍の20 にしたら、 1.80e-5 の値を求めることができた。

PSP 全体の注意点をまとめておいた方がいいかもしれない。
とりあえず。

  • 全課題
    基本的に、作成したプログラムは以降の課題でも繰り返し使用される。 従って、なるべく汎用的に書くこと。 (例えば、 main に全部記述したりしないで、関数に分けるとか。) また、全課題に言えることだが、「データ数の前提」に注意すること。 (幾つかの課題では、データ数は3以上必要である。)
  • 1A
    特になし。
  • 2A
    簡潔にするなら、コメントと文字列内を除いて「;」などをカウントすればよい。
  • 3A
    Ruby のスクリプトを参考にされたし。
  • 4A
    A7.1 節と A7.2 節を読めば分かる筈。
  • 5A
    A5.1 節を読めば分かる筈。
    必要ならば、
      const double pi = 3.141592653589793;
    

    を使用してよい。

  • 6A
    必ず、A8.1 節、A8.2 節、A5.4 節を読むこと。 参考として、A1.6 節、A1.7 節も読んだ方がいい。 6A では、4A と 5A で作成したプログラムを利用すること。
    また、必要ならば以下の関数を利用しても構わない。 (利用しなくてもいい。)
            #include <cmath>
            // Γ(x) = exp(lngamma(x))
            double lngamma(double xx)
            {
                    static double cof[6]={76.18009173,-86.50532033,24.01409822,
                    -1.231739516,0.120858003e-2,-0.536382e-5};
                    double x=xx-1.0; double tmp=x+5.5;
                    tmp -= (x+0.5)*log(tmp); double ser=1.0;
                    for (int j=0;j<=5;j++) { x += 1.0; ser += cof[j]/x; }
                    return -tmp+log(2.50662827465*ser);
            }
    

    追加や削除のLOC 計算には LOCViewer.exe を使用するとよい。

    • PSP6A と PSP6AOld フォルダを作成する。
    • 両方のフォルダに gamma.cpp, PSP4A.cpp, PSP5A.cpp をコピーする。 (gamma.cpp は上の関数だけを含む。)
    • PSP6A で、6A の課題を作成する。 このとき、PSP4A.cpp や PSP5A.cpp を編集してもよい。
    • LOCViewer で旧フォルダに PSP6AOld を、新フォルダに PSP6A を指定し、 再計測する。下の Total 欄を確認する。
    • 全てのファイルを PSP6A.cpp としてまとめる。
    6A で注意すべきなのは、 t(α/2,n-2) を求める必要があるのだが、 325ページの (A8) の g(x) の式とは異なるということである。
    具体的には、70 % の信頼区間を求めるためには、 n = 10 の場合、t(0.85,8) = 1.108 を求める必要がある。 しかし、 (A8) の式は、 g(1.108) = 0.85 が成り立つだけである。 つまり、逆関数を求める必要がある。 簡単な方法としては「2分法」(アルゴリズム事典 210ページ) などが利用できる。
  • 7A
    2*(1-p) が 1.8e-5 にならない場合は、シンプソン法のステップを細かくするなど工夫すること。

    参考:4/9 の話


01/01/31(水)

達人プログラマーという本を買った。 お勧めである。2000年12月出版なので内容は新しいが、 書いてあることは本質的なことである。ずっと使えるだろう。 しかも真実である。ということで、室員全員に買って読んでもらうことにした。
この本では、今までプログラマーの中に暗黙知としてあったものを 本という形で形式知にしたところが評価できるだろう。 特に効果的なものは「DRY原則」「直交化」「テスト自動化」などだろうか。 XP と重なる部分も多い。

PSP も今やっているが、基本的に重要なのは「自分のスタイルを確立し改善し続ける」 というところであろう。そのためには、ダメなところを客観的に知る必要がある。 そこで、定量的にデータを蓄積するというところに PSP の意味がある。 (但し、現状では C++ 演習になりつつある。)

話は変わるが、今後猛烈に忙しくなるため、更新は殆どできないだろう。


01/03/30(金)

2ヶ月ぶりの更新。 いやーやっと一段落つきました。まだまだ忙しいんだけど。
ここんとこ、子供とも遊ばないので、子供にも嫌われている。

さて、今日気づいたこと。CFont::CreateFont でフォントを作るとき、 傾けて作れるが、プレビューでは問題ないのに印刷すると角度が逆になる。 しかも、NT/2000 では問題ないのに、9X 系でそうなってしまう。

OSVERSIONINFO ov;
ov.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&ov);
bNT200 = ov.dwPlatformId == VER_PLATFORM_WIN32_NT;
しょうがないので、こんな感じで、OS のバージョンを見て対応することにした。

また、話は変わるけど、消費税上がるのかな 確かに、うまい方法だと思うが。(まず、要らない所を捨てないとね)


01/04/02(月)

15000個のファイルを フォルダーを開いて捨てると、10分ぐらいかかるんだけど、 フォルダー毎、捨ててしまうと早い。

01/04/09(月)

前にPSP7A の結果が合わない と書いたが、原因はプログラムの誤りだった。 err = abs(prev - cur); if (err < eps) ... みたいに収束判定を していた。しかし、abs の返り値が int なので 0.5 未満で 0 になって収束したとしてしまっていた。 (fabs を使わないといけない) このバグは、後輩に指摘してもらった。Thank you。

01/04/10(火)

WindowsXP なるものが 今年中に出るそうだ。

ふと思い出したのが、アメリカのシェパード・ミードの SF に 「X・Pで幸福を!」という小説がある。X・P装置は、安楽いすに座ったまま あらゆることを経験できる装置である。その結果、人類は総白痴化になっていく。

PC が使いにくいのは、人類をダメにしないための深謀遠慮であった。
なんてわけはないね。
話を WindowsXP に戻して、私は当分 Windows2000 でいいや。Win9X のときより、 OS が落ちることは格段に少なくなった。アプリはよく落ちるけど。 (特に MS-Word 何とかしてくれ。仕事にならん。)

でも、最近の個人向け PC は WindowsMe ばっかりだな。 Windows2000 の方がいいのに。
あと、あらゆる GUI のアプリもコンソールから同等の機能が使えるようにしておいて欲しいな。 (誰に言ってるんだか)


01/04/12(木)

2次方程式を解くプログラム。 (Numerical Recipes より)
#include <cstdio>
#include <cmath>

int main(int argc,char** argv)
{
	if (argc < 4) {
		fprintf(stderr,"usage: %s a b c\n  Solve a*x*x + b*x + c = 0\n",*argv);
		return 1;
	}
	double	a,b,c,d,q,x1,x2;
	a = atof(argv[1]);
	b = atof(argv[2]);
	c = atof(argv[3]);
	d = b*b - 4*a*c;
	if (a == 0) {
		if (b == 0) {
			if (c == 0) printf("Any number\n");
			else printf("No answer\n");
		} else printf("%g\n",c/b);
		return 0;
	}
	if (d < 0) {
		printf("No answer\n");
		return 0;
	} else if (d == 0) {
		printf("%g\n",-b/a/2);
		return 0;
	}
	d = sqrt(d);
	q = -(b + (b > 0 ? d : -d)) / 2;
	x1 = a/q;
	x2 = c/q;
	printf("%g %g",x1,x2);
	return 0;
}

大学の課題でやったときは、解が整数か分数か無理数で表示を分けたりしていた。


01/04/17(火)

テレビで電池の液漏れの話を聞いて、 早速、自作の ECirc でも対応した。 (電池が充電状態の時に赤く危険と表示するようにした。)
ちなみに、電池を並列に使用すると、片方の電池がちょっと古くなると 充電状態になってしまうようだ。

電池について検索したら ミニ四駆関係のマシン研究所なる所のページに詳しい説明があった。

ちなみに私は、別に電気とか得意じゃない。 それでも、昔は電子ブロックというのでよく遊んだ。 それを再現しようとして作ったのが ECirc だが、全然似ていない。


01/04/18(水)

VC++6.0SP5 の STL::list のバグを見つけた。
#include <cstdio>
#include <list>
using namespace std;

int main()
{
	list<int> l;
	int	i, n = 32768;
	for (i=0;i<n;++i) l.push_back(0);
	printf("%d\n",l.size());
	l.sort();
	printf("%d\n",l.size());
	return 0;
}

実行すると、ソート後にリストのサイズが減ってしまう。 サイズが 32767以下なら大丈夫。
プローガさん頼むよ。こんなんじゃ怖くて list 使えませんよ。
というか、今まで書いたプログラムどうすんだ。 (もしかして、SP5 当てたせいとか言わないよね。)

(ちなみに、g++ では大丈夫だった。)


01/04/19(木)

RGB と HSV の変換 用の関数を他の人が作った奴を参考にして作成した。
// RGB<->HSV変換(色調、彩度、明度)
void Rgb2Hsv(int r,int g,int b,int& h,int& s,int& v)
{
	v = r;
	if (v < g) v = g;
	if (v < b) v = b;
	int	m = r;
	if (m > g) m = g;
	if (m > b) m = b;
	double	d = v-m;
	s = h = 0;
	if (!d) return;
	s = int(d*255/v + .5);
	if (v == r)		 d = (g-b)/d;
	else if (v == g) d = (b-r)/d+2;
	else			 d = (r-g)/d+4;
	h = int(d/6*256 + 256 + .5) % 256;
}
void Hsv2Rgb(int h,int s,int v,int& r,int& g,int& b)
{
	h *= 6;
	int w = h/256, u = w%3, t = w/2;
	int& R = (w+1)%6 < 2 ? r : (w < 3 ? g : b);
	int& G = u == 0 ? g : (u == 1 ? r : b);
	int& B = t == 0 ? b : (t == 1 ? r : g);
	R = B = v;
	v *= s;
	B -= v/255;
	h -= int((w+1)/2)*512;
	if (w%2) h = -h;
	G = B + h*v/255/256;
}
void Color2Hsv(COLORREF col,int& h,int& s,int& v)
{
	int	r,g,b;
	r = col&0xff;
	g = (col>>8)&0xff;
	b = col>>16;
	Rgb2Hsv(r,g,b,h,s,v);
}
void Hsv2Color(int h,int s,int v,COLORREF& col)
{
	int	r,g,b;
	Hsv2Rgb(h,s,v,r,g,b);
	col = RGB(r,g,b);
}

SIS(Spatial Information System) で色の設定が、色調、明度、彩度なので 必要に迫られて作った。しかし、彩度と明度を取り違えていて、しばらく悩んだ。


01/04/20(金)

ファイルがディレクトリの階層内に分散して 存在している。これを(1つのディレクトリに)フラットにしたい。 1つの方法として、圧縮して解凍することでできる。 例えば WinZip だと、解凍するときのオプションで、「フォルダを有効にする」を オフにしておけばいい。

01/04/24(火)

やっと PSP 10題終わった。 10題でちょうど12時間かかっている。 しかし、始める前に解き方を読んで理解するなどの事前準備の時間は測定していないので、 実際にはもっとかかっているといってもいい。
10A では、PSP3 を行うはずであったが、結局、PSP1 相当のものしか帳票は作成しなかった。 (そのため、早く終わっている。テキストには、1題、1,2週間となっている。) 結局、1番時間がかかったのが 3A、次が 6A、次が 10A であった。 この辺がヤマと言えるだろう。(とはいえ、3A でメンバイニシャライザまで見たのは、やりすぎだったかも。 6A も、テストを始めるまで、何をすべきか正確に理解していなかったのも問題か。)
ちなみに、課題の簡単な説明を書いておいた。

01/04/26(木)

ディレクトリ内のファイルを調べる。 よく使うのに、忘れることが多いので、メモとして書いておく。
#include <cstdio>
#include <io.h>
int main()
{
	_finddata_t	fd;
	long		h;
	if ((h = _findfirst("*.*",&fd)) == -1L)
		return 0;
	do {
		printf("%s\n",fd.name);
	} while (_findnext(h,&fd) == 0);
	_findclose(h);
	return 0;
}

拡張子などを取り出すには、Windows では、_tsplitpath が使える。


01/04/27(金)

ある点が、多角形内に入っているかどうかの判定を しているところがある。現状は、多角形内をメッシュ分割して set<int> で持って、set::find で調べている。
これを、面情報で持つのではなく、線情報(すなわち輪郭)で 持つようにデータファイルを変更した。輪郭に対して、 ある点が内外かどうかの判定は、ここの方法3 を用いた。適当なサンプル(面情報では、2万2千メッシュ、線情報では 650点)で 計測したところ、線情報の方が面情報より 5倍ほど遅くなってしまった。
データファイルを変更するにあたって、「線情報の方がデータ量は少ないから、 検索は速くなるはずだ」と顧客に説明していたのだが間違っていた。(ショック)
面情報での set::find は2分探索だから、2万2千とはいっても 14回ぐらいで終わるから 速いのかもしれない。ううむ、どうするか。
とりあえず、多少遅くなったが、実際上、問題ないと説明するか。(1秒以内だし)

01/05/01(火)

Java の強みはバイナリ互換である。 とはいえ、これはインタプリタだからだ。 従って、デメリットは実行速度の遅さである。 これは、殆どの(スクリプト言語と言われる)インタプリタ言語でも同じだ。
しかし、両方のメリットを享受することもできる。 すなわち、実行直前に毎回コンパイルするのだ。これなら、(コンパイラさえあれば) どこでも動くし、実行速度も速い。10数年前なら、実行するたびにコンパイルするなど 時間の無駄でしかなかったが、現在なら(簡易な文法なら)どうと言うことはないだろう。 コンパイル済みの実行モジュールをストック(あるいはキャッシュ)して置けば、 コンパイル時間も殆ど気にならないだろう。
(但し、本当に単純な実行だったら、コンパイル時間のオーバヘッドが効いてくる こともあるだろう。それに、バイナリでは互換性がない)

C++ では残念ながら、文法は簡単と言えないので、この方法には無理があるかもしれない。
この方法として有望なのは C だろうか。最もコンパイラが普及しているだろうし。 ストックの仕方とかいろいろ整備したら、C も Write Once, Run Anywhere という日が 来るかもしれない。私は、C にはもう戻れないが。C で STL 動けばいいんだけど。 そうしたらコンパイル時間は長くなるか。 (Java はネイティブにコンパイルしても遅そうだ)

今日からジオシティーズ用のアップロードソフトを使用するので、 簡単に更新できる。(ファイルをドラッグするだけ)
このソフトは、 ここで公開予定。


01/05/02(水)

NTTソフトウェアで ナレッジデータベースができたらしい。 日経コンピュータにでてたのだが、 分野別に登録してある回答者にメールがいくらしい。 なんかよさそうである。うちも欲しいなぁ。 大手じゃないから社員数は少ないけど、 70人くらいいるんじゃなかろうか。 いや、300人いるかもしれない。(NTTソフトウェアでの回答者が70人) 取りあえず、私の登録分野は、C++プログラミング、OR、最適化、 シミュレーション関係かな。

01/05/07(月)

面情報より線情報の方が遅い という話を書いたが、線情報でも持ち方を工夫して 2分探索すれば速くなることに気が付いた。 点の数を n とすると、現状だと O(n) だが、高速版では O(ln(n)) ぐらいになるだろう。円に近ければ 2回方向を みればいいが、複雑な図形だと何回も見ないといけないが。 (手を横にした形だと 5往復)
データは list<pair<multimap<T,T> >, pair<multimap<T,T> > > 見たいな感じか。 多角形内の調査を垂直線で行うとすると、最初の pair の first が 右向きの一連、second が左向きの一連とすればいい。multimap なので、 2分探索は自前で書く必要がないと思ったけどダメかな。
こうすれば、おそらく線情報の方が面情報より速くなるだろう。 でも、作る余裕がない。

01/05/08(火)

WinDiff を使っていて 不便だと思ったので、過去に比較したものを 覚えておくようにするツールを作った。 ところが、 ほぼ同じものが既にベクターにあった。 探せばよかった。まぁいいか。 探しても見つからないことも多いけど。

01/05/09(水)

避難訓練というのがある。 そのうち、「ウィルスばらまき訓練」とか「メールアドレス漏洩訓練」とか できるかもしれない。ウィルスばらまき訓練では、ML(メーリングリスト)に ウィルスをばらまいてしまった時の事後処理の仕方をする。 具体的には、ウィルスの駆除方法の連絡とお詫びだろうか?
お詫びしてもしょうがないんだけど。 漏洩した場合は、リストの破棄と新規募集ということをした企業もあるらしい。 日経コンピュータに詳しい記事が出ていた。 (ワコールの話にはこの事件の怖さが出ている)
効果があるのは、むしろ予防訓練だろう。 新人研修ではメールの使用方法は必須といえるじゃないだろうか。 とはいえ、最近は小学生向けの雑誌(子供の科学)に、CC と BCC の 使い方の説明があるくらいだから、新人の方が詳しかったりして。

参考:3/22の記事


01/05/10(木)

Yahoo!路線情報で 四谷と入れると、四谷三丁目になってしまう。
「なんだ、バグか」と思いつつ、他のサイトでも同じになってしまう。
「なんだ、同じエンジン使ってるのか」と思いつつ、ふと気づいた。
「四谷」でなく「四ツ谷」と入れればよかったのだ。
(プログラミングの話じゃないけど。)

01/06/01(金)

昨日でやっと納品終わった。 とはいえ、あと3週間ぐらいは、全国行脚や研修がある。
5月中、入院していた妻と子供もやっと帰ってくる。 フローリングも、やっと昨日最後のピースをはめた。 手にノコギリの傷が3箇所とマメができた。最初から業者に頼めばよかった。

01/06/02(土)

フリーのハードディスク消去ソフトないかな。 誰か作らないかな。

01/06/05(火)

2ch のプログラム技術板で7行プログラミング というスレッドがある。「砂の嵐」と「ゆれる画面」が凄いね。 最後に 7行に納まってしまうのには感心。 (でも中味はよくわからん。)
#include <Windows.h> 
char*k,y[1<<20];int a=640,b=400,c,r,m[8];BITMAPINFO t={40,a,b,1,24};HWND g;WI\ 
NAPI WinMain(HINSTANCE i,HINSTANCE,LPSTR,int){WNDCLASS w={67,DefWindowProc,0,0 
,i,0,0,0,0,"T"};RegisterClass(&w);HDC v=GetDC(g=CreateWindow("T","2ch",513<<19 
,99,99,a,b,0,0,i,0));while(GetMessage((MSG*)m,g,0,0)!=-1){if(m[1]==15){for(k=y 
;k<y+a*b*3;k+=3)*k=*(k+1)=*(k+2)=(r=r*9+5)>>16;SetDIBitsToDevice(v,0,0,a,b,0,0 
,0,b,y,&t,0);}else DispatchMessage((MSG*)m);InvalidateRect(g,0,0);}return 0;} 

#include <windows.h> 
#include <math.h> 
WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){HDC d,e;int x=GetSystemMetrics( 
0),y=GetSystemMetrics(1),n,f;d=GetDC(0);SelectObject(e=CreateCompatibleDC(d), 
CreateCompatibleBitmap(d,x,y));BitBlt(e,0,0,x,y,d,0,0,SRCCOPY);while(!( 
GetKeyState(1)&(1<<31))){for(n=0;n<y;n++)BitBlt(d,sin((n)*3.0/y)*sin((f++)/ 
40.0)*60,n,x,1,e,0,n,SRCCOPY);Sleep(1);}InvalidateRect(0,0,1);return 0;} 


01/06/07(木)

本を買った。
  • ライティングソリッドコード
  • 憂鬱なプログラマのためのオブジェクト指向開発講座
  • リファクタリング(プログラミングの体質改善テクニック)
「ライティング」は、MS の本だったので最初は買う気になれなかったが、 なかなかよさそうである。(Word の開発部隊も読めばいいのに)
「憂鬱な」は立ち読みで面白くなかったので避けていたのだが、 買って読んでみると入門書として結構よい。若干古いけどお勧め。
「リファクタリング」は、読んでみるとリファクタリングを誤解していることに気づいた。 これもお勧め。
とはいえ、どれもまだ読み終わっていない。
旅行に持っていくにはでかいし。通勤でも読むのも何だし。

01/06/15(金)

やっと一段落ついた。 昨日は午前中、子供の保育参観に行った。女性ばっかりなので疲れる。
午後は、小島研の特別ゼミで講演をした。学生は 15人くらい。
終わってから、小島先生に夕食をおごってもらった。 そのとき、一緒にいた学生が、なんとこのページを見ていることに気づいた。 (公開して3年、始めて、このページを見ている人に会った。) まだ、読んでいるかな。

01/06/21(木)

2日間出張に行ってきた。 旅の窓口で宿を予約したが、なかなかよかった。
また、本を買った。
  • SE を極める50の鉄則
  • ソフトウェアの未来
  • XML Press
「SE ...」は旅先で時間が余った時のために買った。 悪くはないが、自分は SE と思ってないので、参考として読む。 「...の未来」は、豪華な顔ぶれをみるとすごいが、もっと校正しろよといいたい。 XML Press は仕事の参考に。

あと、SEのための財務なんとか入門やデジタル辞典も買いたいが、読む時間はないだろうな。 というか、読むと寝てしまいそうだ。会社員なら財務諸表が読めるように なった方がいいだろう。ということで、チームのメンバにもセミナに行って欲しいのだが。


01/06/22(金)

2ch で西氏が登場している。 通しで読むと面白い。かなりの量があるけど。

01/06/25(月)

便利と思ったフリーソフト。
圧縮・解凍、自己解凍作成できるもの。RGB を読み取るもの。 Window サイズを読み取るもの。単位変換できるもの。 マウス操作を記録編集できるもの。 ソフトをキーに登録できるもの。Windows の最小化をキーでできるもの。

欲しいもの。C++用のリファクタリングツール。 VC++ のアドインを自分で作るか。いい参考書はないかな。


01/06/28(木)

STL ライクな汎用のツリークラスを作った。 それを使って、テストクラスを作った。 ツリーは、ノードもリーフも同じクラスである。 従って、テストスートは作らなかった。(あるいは、テストスートに テストランナーなどの役割を持たせたいうべきか。)
いろいろやっているうちに、どんどんでかくなってしまった。

今度、部内で説明する。


01/07/02(月)

日経コンピュータの7/2号の45ページの 最新の「バグつぶし手法」が気になる。何だろう。

01/07/04(水)

Visual Studio のアドインを作った。 DevStudio Add-in Wizard で作って CCommands::AddinCommandMethod() を下のように 修正。
void CCommands::DoIt()
{
	CComPtr<IDispatch> pActiveDocumentDisp;
	m_pApplication->get_ActiveDocument(&pActiveDocumentDisp);
	CComQIPtr<ITextDocument, &IID_ITextDocument> pActiveDocument(pActiveDocumentDisp);
	if (!pActiveDocument) return;
	CComBSTR s;
	CComVariant fn = s, b = TRUE;
	pActiveDocument->get_FullName(&s);
	CString ss = s;
	if (ss.IsEmpty()) return;
	DsSaveStatus	ds;
	if (pActiveDocument->Save(fn,b,&ds) != S_OK) return;
	FILE*	f = fopen(ss,"r");
	if (!f) return;
	CComPtr<IDispatch> pTextSelectionDisp;
	pActiveDocument->get_Selection(&pTextSelectionDisp);
	CComQIPtr<ITextSelection, &IID_ITextSelection> pTextSelection(pTextSelectionDisp);
	long	i,l,c,n,d;
	pTextSelection->get_CurrentLine(&l); 
	pTextSelection->get_CurrentColumn(&c); 
	char	buf[1024],tag[20][80];
	for (i=1;i<l;++i)
		if (!fgets(buf,sizeof(buf),f)) break;
	if (!fgets(buf,c,f)) return;
	n = ftell(f);
	rewind(f);
	int		ch, pos = -1;
	*tag[d = 0] = 0;
	while ((ch = getc(f)) != EOF && --n >= 0) {
		if (ch == '<') {
			pos = 0;
		} else if (ch == '>') {
			buf[pos] = 0;
			if (buf[0] == '/') {
				if (d > 0 && !strcmp(tag[d-1],buf+1)) --d;
			} else if (buf[pos-1] != '/') {
				pos = 0;
				while (iscsym(buf[pos]) && pos < sizeof(tag)-1) {
					tag[d][pos] = buf[pos];
					++pos;
				}
				tag[d++][pos] = 0;
			}
			pos = -1;
		} else if (pos >= 0) {
			buf[pos++] = ch;
		}
	}
	fclose(f);
	if (d > 0 && *tag[d-1]) {
		ss.Format("</%s>",tag[d-1]);
		s = ss;
		pTextSelection->put_Text(s);
	}
}

STDMETHODIMP CCommands::AddinCommandMethod() 
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	VERIFY_OK(m_pApplication->EnableModeless(VARIANT_FALSE));
	DoIt();
	VERIFY_OK(m_pApplication->EnableModeless(VARIANT_TRUE));
	return S_OK;
}

後は、コンパイルして登録して実行。 XML の閉じタグの自動挿入ができる。かなり、無駄なことしている気もするが、 ヘルプもろくにないし、ようわからん。それにデバッグが大変。


01/07/06(金)

ダイアログベースのアプリにスタートアップ画面を追加する方法 を紹介する。(SDI, MDI は単に、コンポーネントギャラリーの スプラッシュスクリーンを使えばいい。)
  • ダミーのプロジェクトを AppWizard(exe) SDI で作成。
  • コンポーネントギャラリのスプラッシュスクリーンを挿入。
  • スタートアップを追加したいプロジェクトを開く。
  • ダミーから Splash.h, Splash.cpp をコピーして、プロジェクトに挿入。
  • ダミーのリソースを開き、ビットマップのリソース IDB_SPLASH をターゲット プロジェクトにコピー。ビットマップのファイル名は、適宜変更する。 パレットも変更したいときは、Visual Studio のリソースエディタで編集するのではなく、 ファイルそのものを置き換えてしまえばいい。但し、256色以下でないといけない。 うまくリプレースされないときは、*.aps ファイルを削除して VC++ を立ち上げなおす。
  • CXXXApp に ClassWizard で PreTranslateMessage を追加し、中味を以下にする。
    	if (CSplashWnd::PreTranslateAppMessage(pMsg))
    		return TRUE;
    	return CWinApp::PreTranslateMessage(pMsg);
    

  • CXXXDlg::OnInitDialog の一番最初に、CSplashWnd::ShowSplashScreen(this); を追加する。
  • Splash.h も適宜インクルードする。
  • Splash.cpp の最初の方で、 BOOL CSplashWnd::c_bShowSplashWnd = TRUE; と修正。
  • コンパイルして実行。
  • ダミープロジェクトの削除

01/07/07(土)

気になったもの。 紙に埋め込めるチップ。携帯で切符要らずに電車に乗れる。(広告)

01/07/09(月)

面白いものを見つけた。
struct X {
	int		dummy;
	void f(int dumy) {this->dummy = dummy;}
};

上のプログラムのバグはどこか?

.

.

.

答え
 int dumy ではなくて、int dummy

引数の変数が dumy だと、関数 f は何もしていない。 しかも、コンパイルエラーにもならず、分かりにくい。 メンバ変数とローカル変数(引数)の名前が同じ例が、平鍋さんの Javaコーディング標準では、良い例として出ているが、 はっきり言って良くない書き方です。

問題は、メンバ変数とローカル変数(引数)の名前が同じことである。 それを避けるために、私のコーディング規約では、メンバ変数に m_ をつけることにしている。

「m_ をつけると、ソースが見にくいので嫌だ」ということも言われるが、 それは間違っている。目立たせて注意を引かせることが目的なのだから、 見にくくていいのだ。大域変数に g_ を付けるのも一緒である。 (m_ はクラスの名前空間での大域変数と同じだ)
「使っているのとは、別のところで宣言していますよ。 だから注意しましょう」ということをはっきりさせるのを目的としているのだ。

そういえば、昔、新人でローカル変数にも m_ 付けていた人がいたなぁ。


01/07/11(水)

「全ファイルから単語を逐次検索」する DevStudio Add-in を作っている。(欲しい人いたら公開します)
やっていると、Visula Studio のプロセスが残るようになってしまった。 調べてみると、IDocuments の Open を使うとおかしくなる。 そういえば、この関数はヘルプがちゃんとしていないのでよくわからない。 とりあえず、最後の引数の変数を使いまわしていたのを、 使いまわすのをやめたら直った。

01/07/12(木)

メーラの表示フォントを大きくした。 印刷して読むことも多い。年か?ビタミン不足か?

すると、IE のフォントも大きくなってしまった。 メーラは Eudora だが、IEコンポーネントを使用して表示している ということか。何年かすると、「メーラ、何それ?」ということになるかも。 (統合ブラウザみたいなものだけ生き残って)


01/07/18(水)

C++ は難しい。C++ は簡単である。 などと言われるが、当然、これらは一面しか見ていない。
C++ は C より抽象概念を扱いやすい。それ故、作業を難しい所と簡単な所に 分けることができる。難しい所は、共通で使えるようにすれば生産性があがる。
共通で使えるようにする作業は難しい。便利なライブラリを使って作成するのは 簡単である。

言語仕様としてみた場合、Java よりは難しいだろう。全く知らない人に 教えるのは大変である。(私の場合、大抵「本読んどいて」となるけど)


01/07/23(月)

本を買った。 Java によるデザインパターン2冊、物理数学の直感的方法、技術士問題集である。
デザインパターンは、勉強会でもやりたい。GoF の本よりはわかりやすかった。 いつも思うのだが、Singleton だけ何か仲間はずれのような気がする。

実際の C++ の仕事では、パターンは殆ど使わない。そもそも virtual という 単語も使わない。(汎用のライブラリを除く)
これまでは、パターンを敢えて使わなくてもいいと思っていたのだが、 ちょっと認識を変えた。かつて作成したプログラムで Visit パターンを 使った方がすっきりしたのではないかと思う部分があった。
あるコンテナのクラスがあるのだが、安全のため要素は公開していない。 そのため、要素を操作するメンバ関数が非常に多くなってしまった。 これは、Visit パターンを使って構造と操作を分離した方が見通しが良かっただろう。 ただ、クラスはあまり増やしたくないので Java の anonymous クラスが欲しいところである。

P.S. 結城さんの方は読み終わった。説明が生き生きしていてわかりやすい。 2冊も買わなきゃ良かった。結城さんの方の1冊で十分。


01/07/24(火)

ふと思ったこと。 Cマガ でパズルがあるのだが、 仮想言語上での回答を募集してもいいのではないだろうか。 もちろん、如何にスマートな回答を作れるかがミソになる。 仮想言語だから実際に存在している必要はないのだが、 AMPL を拡張した OPL なんかは参考になるかもしれない。(実を言えば、OPL Studio 使って、 パズルを解こうと思ったのだが、挫折した。)
ちなみに、OPL なら 8-Queen 問題は、以下のようになる。
var int queens[1..8] in 1..8;
solve {
    forall (ordered i,j in 1..8) {
        queens[i] <> queens[j];
        queens[i]+i <> queens[j]+j;
        queens[i]-i <> queens[j]-j;
    }
};

また、安定結婚問題は、以下のようになる。
enum Women ...;
enum Men ...;
int rankWomen[Women,Men] = ...;
int rankMen[Men,Women] = ...;
var Women wife[Men];
var Men   husband[Women];

solve {
    forall(m in Men) husband[wife[m]] = m;
    forall(m in Men & o in Women)
        rankMen[m,o] < rankMen[m,wife[m]] =>
            rankWomen[o,husband[o]] < rankWomen[o,m];
};

上記の2つのスクリプトは(データ(*.dat)があれば)そのまま完全に動作する。 省略は一切ない。実にシンプルかつ強力である。でも、まあかゆいところに手は届かない。 ドキュメントも英語しかない。


01/07/25(水)

メモリ管理に気がまわらないプログラマが 増えたような気がする。GC 使うからいいというものでもないだろう。 問題が生じたときに、まるで対応できない。やっぱり C は偉大だったのか。 list, string クラスくらい自作できるようになって欲しい。

文字列の処理は基本なんだけどなぁ。
あと、分からないときの聞き方も上手になって欲しいなぁ。


01/08/03(金)

Java のソースを見ていると、 this.xxx というのをよく見かける。
実は、VC++ を使っていても使うことがある。 それは、自動補間を使用したいためである。 しかし、これは、「Ctrl+スペース」とすれば this を打つ必要はない。 この方法は、「ワンポイント」を見てて知った。 (ちまちまと見ていても大変なので、 VC++ One Pointを用意した。) 逆に、この便利な機能になれると、この機能が使えなくなった時に面倒である。 時々、使えなくなることがあるのだが、なんとかならないのだろうか。
他に便利だと思ったのが、Alt+マウスドラッグによる選択である。 縦に並んでいるものを編集するのに非常に便利である。

01/08/06(月)

パラメータの持ち方について。 何らかのパラメータがあり、ダイアログで設定できるとする。 すると、
  • 元々のパラメータ
  • ダイアログのメンバ変数
  • ダイアログのコントロール
というように、同じパラメータに3種類も値ができてしまう。 2番目と3番目は、DDX を利用して UpdateData で整合性を保てる。 1番目と2番目の整合性を保つために、ダイアログ自体を元々のパラメータ (ドキュメント)にしてしまうことがある。 そこで、UpdateData を使用しつつ、キャンセルボタンも効くようにするために、
	CDlgXXX  dlg;
	dlg.Set(pDoc->m_dlg);
	if (dlg.DoModal() != IDOK) return;
	pDoc->m_dlg.Set(dlg);
	pDoc->SetModifiedFlag();

というように書いたりする。

ここで、ダイアログのメンバに参照メンバを使って失敗した。 別のデータの参照をダイアログのメンバにして DDX を使ったため、 キャンセルボタンを押しても、データが書き換わってしまっていた。 こういう場合は、参照を使用せずに素直にコピーすべきだった。


01/08/07(火)

ふと思ったこと。
  • 英語版の製品を開発し中国で売る。
  • ブラウザの「戻る」「進む」はスタック構造だが、ツリー構造にする。 「戻る」は1つだが、「進む」は選択できる。

01/08/08(水)

クラス宣言から空の関数定義を作成する やつをVC++のアドインで作った。 MakeEmptyDef.zipを 適当な所に展開して、VC++のツールメニューのカスタマイズの アドインおよびマクロファイルで指定する。
struct A {
	void f();
};

で void f の行を選択してアドインを実行すると、
void A::f()
{
}

とうのが挿入される。 但し、インデントはタブでないといけない。


01/08/09(木)

VC++ で用途をリソースにして exe を開いて、 メニューとかビットマップとかアクセラレータとかツールバーとか編集できて保存できる。 すごすぎる。 Macintosh のリソースエディタみたいだ。 VC++ で VC++ 開いてみると、バイナリのリソースばかりだ。

01/08/13(月)

携帯インターネット電話 なんていうものができるかもしれない。 常時接続している家庭や会社からだと、電話代が只。電気代だけとか。 どうですかね。

01/12/3 追記 できたよ


01/08/16(木)

書泉いったら、 財務諸表が売ってあった。顧客のをパラパラ眺めてみた。 今度、買って勉強会でもやりたい。

C++FAQ を買った。前に立ち読みで、面白くなかった印象があるのだが、 なかなかよい。というか、C++ プログラマー必読ではないだろうか。

PSP は3周してしまったので、もういいかな。今度のレビューでは、実演をする予定。 業務への応用を考えていきたいが、、、。


01/08/17(金)

ある本では、コーディングはできるだけ 最後の最後にすべきといっていた。 XP では、コーディングがメインだ。 私は、XP の方が性に合う。 私にとって、設計とは、メモ書き、ヘッダ作成、テスト作成だ。 まぁ、10KLOC 以上のを作るときは違ってくるかもしれないが。

リファクタリングはソフトウェア開発の本質を突いていると思う。 最初からよい設計などできない。但し、引際というかバランス感覚が大事だろう。

resource.h の ID の値が重なっているとなかなか気付かないバグの原因になったりする。 そこで、チェックするやつを作ったのだが、キーを登録しようとしてふと気づいた。
「あれ、もうある」
昔、作ったのに忘れていた。昔のは Windows アプリケーション。 新しいのは Console アプリケーション。

最近、Cマガがつまらない。

日経に出てた「日本ユニシスの社長の話」に対する日本ユニシスの社員の話を聞きたい。


01/08/20(月)

室内指定図書。
  • 達人プログラマー A.ハント、D.トーマス著
  • C++FAQ W.クライン、G.ロモウ、M.ギルウ著
  • VC++6.0プログラミング入門 桜田、田口著
C++ プログラミング関連ばかりだな。

問答
Q:「どうしたらプログラマになれますか?」
A:「プログラマとは、未知のウィルスに感染した人たちです。 プログラマの集まる所へ行けば、あなたも感染するかもしれません。」


01/08/22(水)

assert で気をつけないといけないこと。 分かりにくいものは避ける。意図をきちんと書く。最後に通るようにしておく。
時間をおいて触るときに、意図不明で通らない assert があると対処に困る。 (消すけど)

01/08/24(金)

技術士試験が終わって、一段落ついた。 肩の荷が下りたという感じ。

今回は、数理計画、シミュレーション、ソフトウェア工学と得意な項目が多かった。 でも、あまり自信なし。遅刻していったし。
言語が、C と Visual Basic というのには参った。せめて「C/C++」に しといて欲しかった。でも、人数的には、C only と VB が多いんだろうか。
「VB によるシミュレーション」じゃ書けん。 「C++による離散系シミュレーション」なら いくらでも書けるんだが。
あと、毎年思うんだが、「ワープロ」使わせてくれ。疲れる。 文章の推敲ができん。まぁ無理だろうけど。


01/08/28(火)

昔話。 プログラミング関係の仕事の一番最初は、大学時代に大学の付属機関のコンサル みたいなのをやったのが最初だろうか。先輩から引継いだもので月額固定で 問題があれば対処するという形式だった。消費税の税率が変わったころだろうか。
同じく先輩の紹介で、今は無き Y証券で、2次計画問題を解いてポートフォリオを 求めるプログラム開発をしたこともある。ワークステーションの使い方を、常駐していた S社の人に聞いたのを覚えている。 時給で2,3万円ぐいらいにしかならなかったように思う。今なら、数百万から数千万円だろうな。 時給がばからしくてやめた。(最後の月のバイト代は貰ってないし。)
2ヶ月働いたら、1ヶ月働いた時の倍だけ貰うのはよい。 要は、単価を認めてくれるかどうかだと思う。 (ビジネスだったら成果も保証しないといけないが。)

話は変わるが、同じプリンタを1枚に1ページ印刷用と1枚に2ページ印刷用の 2つ設定すると、非常に楽。今までは、プロパティで変えてたが、プリンタを変えるだけでOKになった。

Ctrl+Shift+Space で 引数のポップアップがでる。「1of3」とか出たときに、マウス使わないで、 次のを見るにはどうすればいいんだろう。

2ヶ月で研究開発費、半分以上使ってしまった。まだ、マニュアルの最初の方しか 読んでないのに。


01/08/29(水)

VC++ 固有の仕様で __finally というのがある。便利だけど使うと移植性がなくなる。 でも次のようなマクロを組込めば大丈夫だ。
#include <cstdio>

#ifndef _MSC_VER
struct CTryFinally {~CTryFinally(){throw 0;}};
#define __try try {CTryFinally TryFinallyDumy;
#define __finally } catch(int)
#endif // _MSC_VER

int main()
{
	__try {
		__try {
			return 0;
		} __finally {
			printf("Inner\n");
		}
	} __finally {
		printf("Outer\n");
	}
	return 0;
}
VC++ と g++ で確認した。__catch というのはないので、脱出用の例外 0 が 別のところで捕らえられる心配はない。 (__try と try は別物)
でも、内部の例外を間違えて補足する可能性があるから、int ではない方がいいかな。
どっかの FAQ にもありそうだな。見つけた人、教えて。

Expert C Programing に出てくる気圧計の話の学生は若き日のボーアだそうだ。 (YPC より)

task::delay はsetjmp、longjmp 使ってできそうだが、C++ で使うのはやばそうだ。残念。 C 用に作るか。あぁ、でも再起的に呼びあうようになってると、スタックがオーバフローしそうで現実的でないか。

stdio と fstream の比較をしてみた。
// 書込み fstream 5.678 秒
	ofstream	fs("test.txt");
	int			i;
	for (i=0;i<1000000;++i)
		fs << i << "\n";

// 読込み ifstream(1) 10.786 秒
	ifstream	fs("test.txt");
	int			i, k = 0;
	while (fs >> i)
		k += i;

// 読込み ifstream(2) 6.679 秒
	ifstream	fs("test.txt");
	int			i, k = 0;
	string		s;
	while (getline(fs,s)) {
		i = atoi(s.c_str());
		k += i;
	}

// 書込み stdio 2.403 秒
	FILE*	f = fopen("test.txt","w");
	int		i;
	for (i=0;i<1000000;++i)
		fprintf(f,"%d\n",i);
	fclose(f);

// 読込み stdio(1) 2.093 秒
	FILE*	f = fopen("test.txt","r");
	int		i, k = 0;
	while (fscanf(f,"%d\n",&i) == 1)
		k += i;
	fclose(f);

// 読込み stdio(2) 0.540 秒
	FILE*	f = fopen("test.txt","r");
	int		i, k = 0;
	char	buf[80];
	while (fgets(buf,sizeof(buf),f)) {
		i = atoi(buf);
		k += i;
	}
	fclose(f);
writeread1read2
fstream5.710.86.7
stdio2.42.10.5
やっぱり遅い。I/O がネックになることもあるし、しばらく stdio で行くか。 それとも、同じスピードになることはないから、あきらめるか。
atoi は速いがチェックできないので、sscanf の方がいい。


01/08/31(金)

XP 導入偏を読書中。
PSP を XP でやってきた人がいた。全部のプラクティスをやろうとしていたが、 1人じゃ無理だと思うよ。

名刺の裏に今までやったプロジェクトを書いておくと話のタネになるかも。 あるいは、発表論文でも書くか。それは変か。
自分の名刺を見てみる。あれ、「System Engineer」って書いてある。ううむ、下っ端でもマネージャのつもりだったんだが。 まぁ、いっか。そのうち直してもらおう。

げげ、2ch が 1000万円でオークションで売られてる。あれあれ、900京?joke か。
(9/3)やはり、joke だったようだ。おっ、西氏が 2ch のオフ会やっている。


01/09/03(月)

XP 導入編読了。 実際にやってみたくなる。ネックはやはりオンサイト顧客だろう。 でも、いい方法がある。自分が顧客になるのだ。でも、そうしたら開発できないか。 社内の人に顧客になってもらう、というのはどうだろう。
とりあえず、バグ追跡ツールとかライブラリ検索ツールとか欲しい。 他部署で作っている所あるけど。

01/09/05(水)

UnitTest をやってみた。 CTest はツリー用なのだが、要素は1個しかない。 テストファーストとはいえ、データ構造は先に決めないと、やっぱりかけない。
作業の時間を記録しようとしたのだが、なんかプレッシャーがかかってだめだ。 データ構造作成の作業時間を取ろうとしたのだが、考えがまとまらない。 結局、時間の記録をやめて、やり直した。
時間記録しているときの作りかけのデータ構造は捨ててしまった。 プレッシャーがかかっているといいのができない。(習慣になっていないせいでプレッシャーになるのかも)

01/09/06(木)

Windows2000Tips で 面白いのを見つけた。Ctrl+ホイールマウスで拡大縮小ができる。 IE,Excel,Word,SIS で対応している。Spy でみても、特別なメッセージが 飛んでいるわけではないので、コントロールキーを押しているかどうか判断しているのだろう。 早速、自分のアプリにも対応させた。

01/09/07(金)

Cマガから掲載料が来た。 10文字ぐらいしか載ってないのに。ラッキー。

メモ
ロジックは切り離し、GUI はテスト不要に持っていく。
分析、設計では、計測しない。開発以降で計測する。

開発した信頼性解析ツールは、時間記録はいまいち失敗したが、 他の項目は取れた。まず、LOC は再利用率が見積もり 90% に対し、95% もいった。 新規 LOC は 見積もりの2倍強の 600 LOC。 時間も見積もりの倍の 800分といったところか。
途中で起きた問題に対し、解決策を考えたが、もう一度考え直し対処しないことにした。 将来必要となるかもしれないが、現状、必要でないので。
再利用のベースにしたのは、CustNet+α。 プラスαにはエンジン部分の400 LOC を含んでいる。これを計画時は考慮していなかったので、 ずれた。まぁ、いずれにしろきちんと計測できていないし。


01/09/11(火)

マウスが壊れたので、 光学式の5ボタンのやつを買ってしまった。

昨日のプレゼンは大成功。プロジェクトの GO サインが出た。

明日から岡山で学会。今週、会社に出るのは今日まで。

XP での見積もりは、時間が主である。 しかし、PSP での経験だと、LOC の方が見積もりやすい。


01/09/17(月)

旅行に行っている間に、 すごいことになっている。
個人的には、犯人探しより救助に人員をさいた方がいいのではと思う。 「目には目を」よりは、コミュニケーションが必要なのではと思う。合掌。

メモ
パターンの活用。信頼性ネットワークの計算が pow(2,n) から pow(2,n/2) になるそうだ。
最小自乗法は、行列式で書くとすっきりする。
式の解析のプログラムで大域変数を使って、似たようなプログラムをよく見るのは、 yacc がそういうのを吐きだすからかも。yacc は使ったことがないので想像。


01/09/18(火)

Cマガ10月号の特集。 実際に VC++6.0 で実行時間を確認してみた。
  • List 1:for(i=n;i;)
    変わらず。クロック数がほとんど同じだと思われる。
  • List 2:
    変わらず。アセンブラで見ても全く同じ。すなわち、 x*(w+a)+y*(w+a)+z*(w+a) は、(x+y+z)*(w+a) となっている。びっくり。
  • List 3:
    この方法は有名。
    実行時間は変わらず。アセンブラで見ても全く同じ。すなわち、 1+2*x+3*x*x+4*x*x*x+5*x*x*x*x は 1+x*(2+x*(3+x*(4+5*x))) となっている。びっくり。
    ちなみに、アセンブラでは掛算の数が 3回になっている。(5*x が代入で計算されている。)
    Cマガの List 3 は、式が間違っている上に、括弧の数も合わず、セミコロンもない。ひどすぎ。
  • List 4:ループをまとめる。
    あほらしいのでやらない。
  • List 5:掛算を割算に
    効果あり。変数にしていると最適化かかりにくいのかな。意外。でも、 float はないんじゃないの。
  • List 6:
    効果あり。このくらい、最適化できんのか。意外。
  • List 7:
    やるまでもないと思いつつ、やってみる。やはり変わらず。 可読性が下がるので、ケース2はよくない。
  • List 8:
    変わらず。
    2重に間違えている。まず、if (seldom && freq) で、seldom も freq も int または bool ならば、 評価時間は無視できるほど小さい。すなわち、入替えても意味がない。そこで、seldom も freq も時間がかかる関数だと仮定しよう。 そうすると、ケース2の方が遅くなる。すなわち、「&& の場合、確率の小さい方を先に評価する方が有利」である。 「||の場合は、確率の大きい方から評価する方が有利」である。Cマガの特集記事はだれもチェックしないで出すのか。
  • List 9:(unsigned int)(x+1) <= 2+1
    効果あり。でも、可読性悪いので通常は書かない方がいいだろう。こんなの書いたら、 リファクタリングで直されるだろう。コメントに x <= 2 && x >= -1 などと書いても、2重化でバグの元になる。 とはいえ、テクニックとして覚えていてもいいだろう。
  • List 10:
    List 10 は例としておかしい。一応、やってみる。ほとんど変わらず。意味なし。
  • List 11:
    効果あり。でも、普通 return (i+1)%16; って書くけどね。ちなみに、 (i+1)%16 は、アセンブラでは (i+1)&15 になっている。
  • List 12:パック演算
    およそ4倍速くなる。可読性は良くないが、割と知られているテクニックでは。
  • List 13:不変式をループ外
    常識でしょう。やるまでもなし。多くの場合、コンパイラがやってくれます。
  • List 14:
    同上。
  • List 15:ループの展開
    やるまでもなし。リファクタリングの対象でしょう。昔、やってたけど。
  • List 16:
    同上。
  • List 17:
    同上。
  • List 18:級数展開
    近似計算だからな。最適化のところで論じるのは筋違いでしょう。
  • List 19:テーブル化
    常識。
  • List 20:インライン
    _inline じゃなくて inline。_inline はコンパイラ固有の仕様。頼むよ。っていうか、大事なことが書いてない。 1つ目、inline は C++ の仕様。「C言語の最適化」という話の中で何故、出てくる。(だから、コンパイラ依存の _inline なのか? それとも、最新の C の仕様では inline が使えるのか?) C だったらマクロの話では。でも、マクロは使わない方がいい。結論、「C++ 使え」。 2つ目、「inline 化などのパフォーマンス向上は、テスト後にすべき」。もちろん、コード変更後は再度テスト。
中級編と上級編のアセンブラの記事も一般向けとは思えない。
Efficient C++の方がためになる。

会社の宣伝:カスタマーコンファレンス2001


01/09/19(水)

面白いもの見つけた。 Windows2000 FAQRegmon。Regmon は レジストリをモニタするもの。他にもいろいろある。(トップページを見ると、ミラーサイトで更新も滞っているようだが)
デバッグの役に立ちそうだ。

また、ワームがはやっているらしい。IE 使っている人は、SP2 を早急に当てましょう。
関連
W32.Nimda.A@mm
新種のワーム
がんばれ!!ゲイツ君9/25 以降に見よう


01/09/20(木)

XML でRelaxer は、 スキーマ(Relax) から クラス定義を吐出すが、逆に、クラス定義からスキーマを吐出すのはどうだろう。 実際には、スキーマが欲しいのではなく、(1)チェック関数、(2)読込み関数、(3)出力関数が自動作成できればいいんだけど。

01/09/21(金)

Exceptional C++ を買った。 非常に良い。こういうのを読みたかった。知らなかったことも多い。

IE5のSP2 を家のPCにも当てようと、雑誌の CD を探したが入っているのが見つからない。 (こういうとき、Cマガに入ってれば、Cマガの株も上がるのに。IE6 が出たし、次号はたぶん付くだろうけど。)
しょうがないので、会社で落として持っていったら、ネットに接続してインストールするようになっていた。 家で接続すると、遅いし金がかかるので、SP2 の本体を探したのだが、なかなか見つからない。 やっと、次のようにすれば、いいことが分かった。 「"C:\ie5\ie5setup.exe" /c:"ie5wzd.exe /d /s:""#E"""」 MS のサイト不親切すぎ。


01/09/25(火)

ショックなことばかり 続く。

01/09/26(水)

公開ソフトの不人気ランキング

  1. ExtView : フォルダ内の拡張子の一覧表示
    ダウンロードした人が何に使うのか知りたい。
  2. PSPStudy : C++ 用の PSP 勉強用プログラムα版
    C++ で PSP やっている人は、殆どいないと想像される。 それでも、ダウンロードしている人は、間違えたのだろうか?
  3. ReNumber : Mvc-XXXf.jpg というファイル名を変更
    まぁ、下らないソフトだし。Perl とかですぐ書けそうだし。
  4. CalcProb : マルコフ過程のモデルを作成し、定常確率と平均推移時間を求める
    「マルコフ過程、何それ?」ってところでしょう。
  5. RevCoin : コインを使ったパズル
    Cマガのパズルで試しに作ったもの。ゲームとしてはそれほど面白くないし。
以上のソフトは公開は続けるけど、もう更新しないでしょう。
ちなみに、人気のあるのは、ECirc と WinDiffEx。

01/10/01(月)

大学生の学力低下の 話を良く聞く

実際、「学力低下」で検索すると、たくさん出てくる。特に、理系科目がひどいようだ。 文部科学省の責任は大きい。(とはいえ、既に期待していない。自分の子供は留学させる予定。)
あと、記事中には作成日を書くべきだ。(私もか)


01/10/02(火)

template <class T> void f(T&) {}
この関数の、「引数が vector<T>& の特別バージョン」を書きたいのだが、 どうすればいいのか分からない。
vector<int> v; f<int>(v); とすればできるのだが、実際には f でなく operator<< を使いたいのでコードは変更したくない。

ううむ、g++ では、普通に書いて OK だ。VC++ ではダメだ。言語的にはどっちが正しいのだろう。 g++ のような気がする。VC++ も直して欲しい。
ちなみに、VC++ では、Koenig の自動照合が operator 関数しか効かない。


01/10/03(水)

template は、 奥が深い。何か、面白い本ないだろうか。

#include <iostream>
#include <vector>
#include <list>
using namespace std;

template <typename T> void g(T&){cout << 1;}
template <typename T> void g(list<T>&){cout << 2;}
template <typename T> void g(vector<T>&){cout << 3;}
template <typename T> void g(list<vector<T> >&){cout << 4;}

int main()
{
    int                     v0;
    list<int>               v1;
    vector<int>             v2;
    list<vector<int> >      v3;
    list<list<int> >        v4;
    vector<vector<int> >    v5;
    vector<list<int> >      v6;
    g(v0); g(v1); g(v2); g(v3); g(v4); g(v5); g(v6);
    cout << "\n";
    return 0;
}
上記のプログラムは、g++ では、「1234233」と出力される。 VC++ では、コンパイルできない。(多重定義と言われる。) 是非、直して欲しい。でないと、template のライブラリを書けない。 これがコンパイルできるようになることは、かなり重要である。

VC++7 でも直ってない。

長生きの順。インターフェース。テスト。実装。


01/10/10(水)

ジオの規約の関係で、著作権が問題ありそうな コンテンツを公開しないことにした。 ついでにジオのページは閉鎖することにした。 これがジオでの最後の更新となる予定。

日経システムプロバイダのオンラインの記事を読んだ。 従量制のソフト。M&Aが進むシステム子会社。受託のオープンソフトウェア。
時代を象徴しているようだ。但し、オープンソフトウェアは流行らないと思う。 それに、実装を単純にしないと意味がないだろう。


01/10/19(金)

フレックスなし になったんで、8:30 に来ている。
担当者はフレックスで 10:00 に来るので、逆に効率悪い。 忙しくなったらもっと早く来てもらうようにするか。

01/10/24(水)

言語毎の比較を している。

Pascal,ObjectPascal,ObjectiveC,Fortran がないのが気になる。 gcc は g++ のチューニング版と思えば、g++ が一番いい? (inline 使えば、gcc 以上に速くできるし)
Java はなんでこんなにメモリ、バカ食いするんだ。しょせんインタープリタ言語か。 スクラッチ以外の用途では native コード吐けるのじゃないとダメだね。

VC++7 の vector の iterator は typedef じゃなくて クラスになっている。 今まで、T* に begin() を渡したりしていたが、&front() にしないとだめだな。


01/10/26(金)

グラフクラスを直した。 自己ループや2重アークにも対応した。実は、接続反復子を直しただけ。 最初はキーが頂点反復子だったが、キーを辺反復子に変えた。

ダブルクォーテーションを認識するように、GetCSV を修正。
#include <cstring>

char* GetCSV(char** pBuf)
{
	char	*p = *pBuf,*q = p;
	if (!p) return 0;
	if (*p == '"') {
		char*	r;
		q = r = p++;
		while (true) {
			++q;
			++r;
			if (q != r) *r = *q;
			if (!*q) break;
			else if (*q == '"') {
				if (q[1] != '"') break;
				++q;
			}
		}
		if (*q == '"') {q++; *r = 0;}
	}
	if ((*pBuf = strchr(q,',')) != 0) *(*pBuf)++ = 0;
	return p;
}

#include <cstdio>
int main()
{
	FILE*	f = fopen("a.csv","r");
	char	buf[80],*p,*pBuf;
	while (fgets(buf,sizeof(buf),f)) {
		pBuf = buf;
		while ((p = GetCSV(&pBuf)) != 0)
			printf("[%s] ",p);
		printf("\n");
	}
    return 0;
}

ツリーの表示関数。
#include "tree.h"

void ShowTree(vector<int>& v,tree<string>::node_iterator it,bool bFirst,bool bLast)
{
	int		i = 0;
	if (!bFirst) {
		vector<int>::iterator	bit = v.begin(), bite = v.end(), bite2 = bite;
		for (--bite2;bit!=bite;++bit) {
			i = *bit;
			printf("%*s",abs(i)+1,bLast && bit == bite2 ? "└"
				: (i > 0 ? (bit == bite2 ? "├" : "│") : "  "));
		}
	}
	printf("%s",it->c_str());
	if (it.size()) {
		v.push_back(it.size() > 1 ? it->length()+1 : -1-it->length());
		printf("%s",it.size() == 1 ? "─" : "┬");
		tree<string>::child_iterator	cit,cb,ce,ce2;
		cb = it.begin();
		ce2 = ce = it.end(); --ce2;
		for (cit=cb;cit!=ce;++cit) {
			if (cit == ce2) v.back() = -v.back();
			ShowTree(v,*cit,cit == cb, cit == ce2);
		}
		v.pop_back();
	} else {
		printf("\n");
	}
}

void ShowTree(tree<string>& t)
{
	vector<int>	v;
	ShowTree(v,t.root(),true,false);
}


01/11/01(木)

Linus の自伝によると 最初のマシンはコモドールの VIC-1001 らしい。実を言うと、私もそうだ。 買ったその日から、BASIC のプログラムを書いたな。 (最初に覚えたのが BASIC。次がマシン語。 マシン語のマニュアルは使いすぎてボロボロになってしまった。BASIC を覚えたのはマイナスだと思っている。) 18年以上前かな?
あのころは、ハードディスクなどなかった。キーボードが本体だった。 電源入れるたびにプログラム書いたりもしてたし。こんなことしてたんで、高校 1,2年は成績悪かった。
また昔話だ。

01/11/07(水)

IE では、JavaScript で クリップボードの内容が取れるらしい。 つまり、Submit ボタンを押すと、クライアントのクリップボードの内容をサーバに 送ることができる。仕様なんだそうだ。MS にセキュリティという概念はないようだ。
クレームが来たら、「Submit 時にクリップボードを空にするユーティリティ」を 出して、対応しましたとか言いそうだ。

ジョン・ベントリーの「珠玉のプログラミング」p262 のソートを読んで、STL が遅いと思っている 人もいるようだ。自分で使ってみりゃいいのに。inline にすれば、C の qsort より速いぞ。
p262 は set を使わずに vector を使えばいいのだ。
vector, list, map を自前で作って、メモリ地獄でも見ないと、便利さは分からないのか。


01/11/12(月)

今日、注腸検査とかで 昨日から半断食なんだけど、思いのほか調子がいい。 3kg 減ったせいかな。(昨日は、鼻水、頭痛、下痢だったんだけど)

情報漏洩後の対応みると、 朝日新聞の対応がひどいね。 反面教師にするためにも、セキュリティの担当を置いて、対応を一本化すべきだと思う。

.net 入れたら強制的に IE6 になったんだけど、途中で切れることが多い。 特に 2ch。設定で直らないかな。

12/12:.net のでない IE6 を入れなおしたら直った。

To が空でも Bcc があればメールを送れる。 To が空で、Cc だけだとダメだ。何でだろう。RFC で決まっているのかな。 To が空だと体裁が悪い。適当に書いて「:;」をつければエラーにならない。


01/11/13(火)

文字を Excel にペースト したら、一部が数字になっていた。「123E02」というような文字が「12300」になっている。 一瞬考える。123×10^2 か。なんかバグの元になりそうだな。

ペアプログラミングの説明を読んでいて、昔考えた「戦争をなくす方法」を思い出した。
その方法とは、「世界的に定期的に強制的にランダムな地域に引越しさせる」というもの。
これが実現すれば、国家は都市程度の規模になり、人種は融合していくだろう。 家は規格化され、交通の手段はより利便性が高く、効率的になるだろう。 私有財産も手回り品程度で充分になるかもしれない。 結果として、戦争は殆ど起きないと考えたのだがどうだろう。 (もちろん、実現させることは不可能だと思うが。)


01/11/14(水)

VC++7βでは、 list::sort の問題や、new の割当て失敗で bad_alloc が投げられなかったのが 修正されている。VC++6 でも直して欲しいね。
これこれは直っている。
これこれこれこれも直してよ。

01/12/03(月)

これだけメールが氾濫し、 CC や BCC に書くことが多くなると、 本文の最初に「○○様」とか入れるべきなんだろうな。 今日からそうするか。

01/12/05(水)

ここに書いても 意味ないけどメモ代わりに。
毎朝、SPAM メールを捨てているんだけど、 「Adult」「Money」「Click」って書いてあるやつや、 HTML メールは見た瞬間で消すので、私にメールする人はご注意下さい。 (危険なのでフィルタリングはしていないが)
公私のメールアドレスを分けてない。公私を分けて、公のメールは関係者は 見れる方がいいと思う。しかし、現状で問題ないので、とりあえずこのままで行く。 面倒なので。

簡単に電磁波の強さが測れる装置ないだろうか。


01/12/10(月)

発見されている最大の素数は、 2^13,466,917-1 だそうだ。

01/12/11(火)

「ピープルウェア」と「ゆとりの法則」を 読了中。考えさせられる。後で、また読むことにしよう。

01/12/18(火)

Hello World を 「こんにちは、世界」とか訳さないで欲しいな。原文のまま、もしくは「さぁ始めよう」にして欲しい。

某Kのせいで、ホットゾヌ使うようになってしまった。


01/12/18(火)

電車から珍しいものを2つ見た。 富士山と電車の窓の影だ。 すなわち、天気が良くて空気が済んで、朝早く(太陽が低く)、電車も混んでないということだ。

01/12/20(木)

Modern C++ Design を買った。 こういう本を読みたかった。

(失敗と)大失敗をした。へこむ。


01/12/25(火)

VC++ の STL の random_shuffle が サイズが2のときにランダムでない。

resize とすべきところを reserve として間違えた。 VC++ のエディタの補完で res まで打って確認しなかったせいだ。

02/01/07 追記:random_shuffle は元と同じものにならないそうだ。ということで、 サイズが2だと必ず逆順になると。仕様なのか?


01/12/26(水)

定期、駅で無くした。 ぼろぼろ。

CATV で WinXP 入れている人は、 大変だね。


前へ 目次 次へ