Qt4 の QList クラスを使うときのサンプル。 delete はここでは考慮してない。 #include#include class XY { public: int x; int y; XY() { x=y=0; } XY(int _x, int _y) { x=_x; y=_y; } ~XY() {} void dump() { qDebug() << x << ',' << y << endl; } }; int main(int argc, char *argv[]) { QList< XY > list; XY a; a.x = 1; a.y = 2; list.append(a); XY b(2, 22); list.append(b); list.append(*new XY(3,333)); QList< XY >::iterator i = list.begin(); while (i != list.end()) { XY& xy = (*i); (*i).dump(); ++i; } return 0; }
C/C++ , Visual Studioの最近のブログ記事
おつむのリハビリに数独(Number place)を解くプログラムを書いてみました。
むか〜しVisualC/C++の練習で書いたことがあったけど、
いまとなってはリハビリにはちょうどいいかも。
で、今日の今日まで知らなかったのだけど、
C++ のスコープで
for (int i=0; i<9; i++) {
...
}
としたときに、変数 i は for 文が終わると消えちゃうように
変わったんですね。以前は for の含まれるブラケットの中では
存在してたのに。
int main()
{
for (int i=0; i<9; i++) { // ここで宣言しとく
...
}
for (int i=0; i<9; i++) { // 以前は int があるとエラー
...
}
for (i=0; i<9; i++) { // 最近は int がないとエラー
...
}
return 0;
}
知らんかった。
やっぱリハビリが必要だわ。
//======================================
// Name : sudoku.cpp
// Author : tensu
// Version :
// Copyright : (c) tensu 2009
// Description : SUDOKU in C++, Ansi-style
//======================================
#include <iostream>
using namespace std;
int num[9][9] = {
{1,0,0, 2,0,0, 3,0,0},
{0,0,0, 0,3,0, 0,4,1},
{0,0,3, 0,0,4, 0,0,5},
{3,0,0, 1,0,2, 5,0,0},
{0,4,0, 0,0,0, 0,6,0},
{0,0,5, 8,0,9, 0,0,7},
{5,0,0, 6,0,0, 7,0,0},
{9,6,0, 0,7,0, 0,0,0},
{0,0,7, 0,0,8, 0,0,9},
};
int ans=0;
void dump()
{
cout << "Ans: " << ++ans << endl;
cout << " x";
for (int x=0; x<9; x++) cout << " " << x+1;
cout << endl;
cout << " *";
for (int x=0; x<9; x++) cout << "--";
cout << endl;
for (int y=0; y<9; y++) {
cout << "y" << y+1 << "|";
for (int x=0; x<9; x++)
cout << num[y][x] << " ";
cout << endl;
}
}
void probe(int loc)
{
++ent;
if (loc==81) {
dump();
} else {
int x = loc % 9;
int y = loc / 9;
int bx = (x/3)*3;
int by = (y/3)*3;
if (num[y][x]!=0) {
probe(loc+1);
} else {
for (int n=1; n<=9; n++) {
bool used = false;
int ix,iy;
for (ix=0; !used && ix<9; ix++)
if (num[y][ix]==n) used=true;
for (iy=0; !used && iy<9; iy++)
if (num[iy][x]==n) used=true;
for (iy=by; !used && iy<by+3; iy++)
for (ix=bx; !used && ix<bx+3; ix++)
if (num[iy][ix]==n) used=true;
if (used) continue;
num[y][x]=n;
probe(loc+1);
num[y][x]=0;
}
}
}
}
int main() {
cout << "9x9" << endl;
probe(0);
if (!ans)
cout << "No Ans." << endl;
return 0;
}
---
結果:
9x9
Ans: 1
x 1 2 3 4 5 6 7 8 9
*------------------
y1|1 9 4 2 8 5 3 7 6
y2|7 5 2 9 3 6 8 4 1
y3|6 8 3 7 1 4 9 2 5
y4|3 7 6 1 4 2 5 9 8
y5|8 4 9 3 5 7 1 6 2
y6|2 1 5 8 6 9 4 3 7
y7|5 2 1 6 9 3 7 8 4
y8|9 6 8 4 7 1 2 5 3
y9|4 3 7 5 2 8 6 1 9
Ans: 2
x 1 2 3 4 5 6 7 8 9
*------------------
y1|1 9 4 2 8 5 3 7 6
y2|7 5 8 9 3 6 2 4 1
y3|6 2 3 7 1 4 9 8 5
y4|3 7 6 1 4 2 5 9 8
y5|8 4 9 3 5 7 1 6 2
y6|2 1 5 8 6 9 4 3 7
y7|5 8 1 6 9 3 7 2 4
y8|9 6 2 4 7 1 8 5 3
y9|4 3 7 5 2 8 6 1 9
Qt4の練習がてら緯度経度をUTMに変換するツールを久々に作ってみた。
http://cid-e844b718ee02a287.skydrive.live.com/browse.aspx/.Public/utm
僕の作る程度のプログラムなら Eclipse CDT と Qt4 SDK があれば Visual C/C++ の必要性はかなり低くなる。
Visual C/C++ が .NET に移行してからなんか使う気があまりしないでいたけど、今後ますます使わなくなるかもしれない。
この練習プログラムのソースが Ubuntu の上でそのまま通って実行ファイルができるなら素敵だ。
Vista SP2 にインストール。
用意したもの、以下のとおり。はっきりいってよくわかっていない。
eclipse-cpp-ganymede-SR2-win32.zip ... (1)
qt-sdk-win-opensource-2009.02.1.exe ...(2)
qt-eclipse-integration-win32-1.5.1.exe ... (3)
次も一応ダウンロードだけしといた。
qt-win-opensource-4.5.1-mingw.exe ... (4)
qt-creator-win-opensource-1.1.1.exe ... (5)
(1) を展開。 c:\opt\eclipse\ に置く。
このディレクトリにはほかのバージョンの eclipse も置かれているので
実行ファイル(exlipse.exe)の位置は"C:\opt\eclipse\eclipse\eclipse.exe"
(2) を実行。 c:\opt\Qt\2009.02 にインストール。
C:\Program files\ 以下にインストールするのがいいんだろうけどなんとなく変えてみた。
(3) を実行。 C:\opt\Trolltech\Eclipse にインストール。
Eclipse のインストレーションは C:\opt\eclipse\eclipse
MinGW のインストレーションは C:\opt\Qt\2009.02\mingw\bin
をそれぞれ指定。
(4),(5) は今日は使わなかった。
Eclipse を起動。
パスを追加する。メニュー(Window) (Preference) [QT]
Bin Path: C:\opt\Qt\2009.02\qt\bin
Include Path: C:\opt\Qt\2009.02\qt\include
で、コンパイルはできるけどデバッグと実行ができない。
なにが足らないんだろ。。。
--- 1時間後、
パス(C:\opt\Qt\2009.02\qt\bin)を通したらエクスプローラから直接実行はできた。
でもまだデバッグできない。
--- さらに1時間後、
http://lists.trolltech.com/qt-interest/2008-06/msg00543.html
を見つけてプロパティをいじる。
[ Debugger Tab - Main Tab ]のデバッガのパス変更と、
C:\opt\Qt\2009.02\mingw\bin\gdb.exe
[ Debugger Tab - Shared Libraries Tab ]のライブラリの追加。
C:\opt\Qt\2009.02\lib
で何とか動いたみたい。
ついうっかり罠にはまってしまった。
ウィンドウズではイベントで関数が呼び出されるので、関数の処理される順番が必ず期待通りになるとは限らないという罠。
具体的にはOnInitDialog() よりもOnEnChangeEdit() が実行されうるということと、実行順序は Debug と Release で同一とは限らないということ。
単純に考えると、OnInitDialog() がまず実行され、その後エディットボックスに何か入力されればその都度 OnEnChangeEdit() が呼び出されそうである。
そこで、
BOOL someDlg::OnInitDialog()
{
SetDlgItemInt(IDC_EDIT1, m_foo);
}void someDlg::OnEnChangeEdit()
{
m_foo = GetDlgItemInt(IDC_EDIT1);
}
とうかつに書いたりすると初めに OnEnChangeEdit() が実行されてで m_foo が0になってしまい、OnInitDialog() でえでぃとっボックスに初期値を表示させようとしても実現できない。
someDlg::someDlg() { m_init = false; }とでもしてこの罠を回避する必要がある。 MFC のDDX 使っていれば気にする必要のないことなんだろうけどATL/WTL を使おうとすると要注意かもしれない。BOOL someDlg::OnInitDialog()
{
SetDlgItemInt(IDC_EDIT1, m_foo);
m_init = true;
}void someDlg::OnEnChangeEdit()
{
if (!m_init) return;
m_foo = GetDlgItemInt(IDC_EDIT1);
}
vs.NET2003で同じソースから msi (ウィンドウズインストーラ)ファイルを2台のマシンで作ってみた。
入力がが同じで処理するソフトが同じなら、出力も同じになっていると思っていたがそうではなかった。
1台のマシンはWindowsXP pro、もう1台はWindows2000 pro。入力になるプロジェクト(ソリューションというのか)はまったく同一で、1台からもう1台へコピーしたもの。
まず、それぞれのコンパイルされた複数の EXE のファイルサイズは同一だった。
しかしそれをまとめたインストーラの MSI ファイルは何故かWinXPで生成されたもののほうが5.8Mだったのに対しWin2000のほうは6.6Mになっていた。
なにが原因だろう?
メニューの「開く」と同様
AfxGetMainWnd()->SendMessage(WM_COMMAND, ID_FILE_OPEN);
「OK」ボタンと同様
AfxGetMainWnd()->SendMessage(WM_COMMAND, IDOK);