LastUpdate: 2009/01/19 00:23:06
戻る
■よく出くわすコンパイル/リンクエラー
■よく出くわす実行時エラー
001 char80バイト配列へのポインタの宣言方法
002 コマンドラインでの引数の取得方法
003 (C++) 純粋仮想関数の使い方
004 (C++) ポインタ渡しと参照渡し
005 変数定義時の初期化バリエーション
006 printfのよくある使い方
007 coutのよくある使い方
008 CArrayのよくある使い方
009 try、catchについて
010 継承によるスコープの変化について
011 構造体の型宣言について
012 DECLARE_SERIAL IMPLEMENT_SERIAL Serialize って何?
013 #ifdefの初歩の初歩の初歩の基本
014 Visual C++ のプロジェクトの新規作成メニューの説明
015 BSTR型の関数の戻り値をVC++内で取得する方法
016 トレースの目的で出力した内容を、ファイルに書き出す方法
017 VisualC++のプロジェクトファイルは?
018 Linkでエラー
019 fatal error C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました
020 2重インクルード防止
021 new delete の使い方
022 StdAfx.hとStdAfx.cppって何?
023 [MFC]アプリケーションで引数は取得できるの?
024 [MFC]アプリケーションクラスのオブジェクトにアクセスするには?
025 クラスにstaticなメンバ変数を追加したらリンクエラーになるが
026 ソートの話題
027 Win32APIを使うときのinclude
028 最適化のキーワード
029 リストボックスのアイテム追加の方法(MFCの練習もかねて)
030 画面ってどうやってつくるんだろう?
031 プロセス列挙の手法
032 静的メンバ関数の利用法
033 CTimeとCTimeSpanはどう違うの?
034 関数の戻り値って、どういうメカニズム?
035 よく使う型の表現範囲
036 リソースファイルを他のプロジェクトからコピーする方法
037 IDDが無いってコンパイルエラー
038 IDEにクラスのひな形を作らせる方法
039 VBからも使えるDLLの作り方
040 スタートメニューからMSDNのショートカットを作成する方法
041 インスタンスを生成しない関数の集まりのクラスを作成するには
042 よく出くわす、コンパイル/リンクエラー
043 エディタのフォントを設定する方法
044 カレントフォルダの取得
045 ベーシックなファイルIO
046 046 DLLを呼ぶようにするとき
047 よく使うマクロ
048 クラスライブラリ
049 構文メモ
050 CMapメモ
051 クラス ビューのアイコンの意味
052 よく使うショートカット一覧
053 Memory Detailsの見方
054 コード補完が正しく機能しない時の対処方法
055 const
056 ダイナミックキャスト
057 共通インクルードパスの設定方法
058 よく見失う定数
059 new foo[0]で取得できるアドレスの謎
060 よく忘れるんだなぁ qsortの使い方
061 マクロの登録の仕方
062 デバッガーでブレイクポイントを入れると固まる!
063 整数の割り算は注意!
064 エラーコードの意味を調べたい
065 改行コードあれこれ
066 EXE/DLLのデバッグあれこれ
067 アイコンのあれこれ
068 アウトプットエリアにデバッグ情報を出したいとき
069 複数階層に渡るフォルダを一発で作成したいとき
070 FileView にあるクラスが、ClassViewに表示されない!
071 実行速度のチューニング
072 リリース用のメモリとデバッグ用のメモリ
073 メンバ関数の関数ポインタ
074 仮想関数とインライン関数
075 条件指定のブレイクポイント
20060713 コマンドライン引数って何が入ってくる?
20080716 プロジェクトの初期格納フォルダの設定方法
20080716 VS2008 で ピュアな C言語 コンソールアプリを作成したい
20080717 Windows拡張機能を無効にしたい
20080723 コンパイル警告 C4996の抑制
20080725 シンプルに共通関数の実装
20080909 現在の場所のソース コードを表示できません
20080918 標準出力とエラー出力
char (*p)[80]; 1999/12/27
main関数への引数で渡される。第1引数は、コマンドライン引数の数。第2引数は、文字列配列へのポインタである。
なお配列1つ目は、自分自身のフルパスファイル名であり、必ず渡される。よって、第1引数は最低1になる。
例):コマンドライン引数の列挙
#include <iostream.h>
void main(int argc, char *argv[] ){
cout << "argc=" << argc << endl;
int i;
for (i=0 ; i < argc ; ++i){
cout << "argv[" << i
<< "]=" << argv[i] << endl;
};
return;
}
1999/12/27
サンプル
#include <iostream.h>
class classMoto{
public:
virtual int GetName()=0; //純粋仮想関数
};
class classA : public classMoto {
public:
int GetName(){
return 123;
};
};
class classB : public classMoto {
public:
int GetName(){
return 456;
};
};
int main() {
classA cAAA;
classA* pAAA;
classB cBBB;
classB* pBBB;
classMoto* pVVV;
pAAA = &cAAA;
pBBB = &cBBB;
cout << "pAAA->GetName()=" << pAAA->GetName() <<endl;
cout << "pBBB->GetName()=" << pBBB->GetName() <<endl;
pVVV = pAAA;
cout << "pAAA->GetName()=" << pVVV->GetName() <<endl;
pVVV = pBBB;
cout << "pBBB->GetName()=" << pVVV->GetName() <<endl;
return(0);
}
サンプル解説
クラス“A”とクラス“B”がある。両方を参照できるポインタを用意し、そのポインタはどちらを参照しているのかを調べたい。そこで、抽象クラスの仮想関数を設けることで関数を使い分けることが可能となる。
元クラスの virtual int GetName()=0 が仮想関数を設定しているところ。=0 により、実体のない宣言だけになり必ず子クラスで再宣言しなくてはならない意味になる。これを純粋仮想関数という。
実行結果
pAAA->GetName()=123
pBBB->GetName()=456
pAAA->GetName()=123
pBBB->GetName()=456
1999/12/27
従来Cは、ポインタ渡しだけであったが、C++では参照渡しがサポートされた。
参照は、変数の別名のようなものであり、参照先の実体と同じもののように扱うことができる。
例)
main(){
int iii;
// ポインタ渡しの例
sub1(&iii);
// 参照渡しの例
sub2(iii);
}
//ポインタ渡しの引数
void sub1(int* iii){
}
//参照渡しの引数
void sub2(int& iii){
}
1999/12/27
参照渡しをすると、上記でいうところの sub2 内で 引数iiiの内容を変更してしまうかもしれない。
そこで、void sub2(const int& iii) とすると、sub2 内部でiiiが変更できない事を保証することになる。
2002/10/16
1999/12/28
printf("name=%s\n",name); | 文字列nameの開始アドレスより、nullまでを出力。 |
printf("name=%6s\n",name); | 文字列nameの開始アドレスより、nullまでを出力。6文字未満のときは、必ず6文字出力する |
printf("name=%.6s\n",name); | 文字列nameの開始アドレスより、nullまでを出力。6文字以上のときは、6文字しか出力しない |
printf("name=%6.6s\n",name); | 文字列nameの開始アドレスより、必ず6文字を右詰出力。足りない時はブランク埋め |
printf("name=%-6.6s\n",name); | 文字列nameの開始アドレスより、必ず6文字を左詰出力。足りない時はブランク埋め |
printf("value=%X\n",value); | 数字valueを16進表示 %xはa〜f、%XはA〜Fで表示 |
printf("value=%d\n",value); | 数字valueを符号付き10進表示 |
printf("value=%5d\n",value); | 数字valueを符号付き10進表示.。右詰桁数指定 value=67のとき、“ 67” |
printf("value=%05d\n",value); | 数字valueを符号付き10進表示.。0埋め桁数指定 value=67のとき、“00067” |
printf("value=%u\n",value); | 数字valueを符号なし10進表示 |
printf("value=%3.2f\n",value); | 浮動小数点valueを精度指定で表示 |
これだけ知っていれば、ほぼ大丈夫?
2000/01/05
2000/05/25 追加
2002/11/15 %05d の説明文を修正
2008/07/25 %5d 追加
数値などを簡単に文字列に変換する方法
int i = 10;
CString strIndex;
strTime.Format("i=%d ",i);
2003/02/05
cout << dec << value << endl; | 数値valueを10進表示 |
cout << oct << value << endl; | 数値valueを8進表示 |
cout << hex << value << endl; | 数値valueを16進表示 |
cout.width(n); | 表示桁数をn桁にする |
cout.fill('文字'); | 空いている桁を'文字'で埋める |
cout.setf(ios::right, ios::adjustfield); | 右詰 |
cout.setf(ios::left, ios::adjustfield); | 左詰 |
cout.setf(ios::showpos); | 表示する数値が正数の時“+”を先頭に表示する |
cout.setf(ios::showpoint); | 少数点表示 |
cout.setf(ios::scientific, ios::floatfield); | 指数表記 |
cout.setf(ios::fixed, ios::floatfield); | 固定小数表記 |
cout.setf(ios::internal, ios::adjustfield); | cout.fillで指定された文字があれば出力 |
これだけ知っていれば、ほぼ大丈夫?
2000/01/14
CArray<型1,型2> 名前;
CArrayはクラステンプレートです。
型1,型2がテンプレート引数です。
型1により配列に格納される要素の型が決まります。
型2によりCArrayのメンバにアクセスする時の型が決まります。(メンバ関数の引数とか)
例)
関数a(){
CArray<CString,CString> aryStr; // CArrayでCStringの配列を定義
CString a;
a="test1";
aryStr.Add(a); // aryStrへ配列要素を追加(1回目)
//CArray<CString,CString> aryStr;と定義されているので引数はCString型になる。
a="test2";
aryStr.Add(a); // aryStrへ配列要素を追加(2回目)
cout << "1番目の配列要素の値" << aryStr.GetAt(0) <<
endl;
cout << "2番目の配列要素の値" << aryStr.GetAt(1) <<
endl;
}
2000/01/27
実体を格納する時は次のようにする。
CAarrya<MyClass , MyClass&> arrMyClass;
こうすると、テンプレート内部ではMyClass = MyClass なる。つまり右辺は参照なのでアドレス値がわたされるだけで済む。
もしCAarrya<MyClass , MyClass> arrMyClass; としてしまうと
テンプレート引数の段階でコピーが走るので、生成/破棄がされてしまうのでよろしくない。
2003/02/22
C++で例外処理を検出するにはtry、catchを使用します。
エラーを検出する対処範囲をtry{}で囲います。
try
{
処理・・・・・・;
・・・・・・・;
・
・
・
}
catchで検出したエラーの例外処理を行います。
catch(...)
{
例外処理・・・;
・・・・・・・;
・
・
・
}
catchの後ろの()の中には対処するエラーの種類を書きます。(エラーの種類は自分で調べてください)
()の中に...を書くと全ての例外に対応します。(どの様なエラーか分からないが)
例)
void aaa(){
int a=0,b=0,c;
c=a/b; //0割でエラー発生
}
void main( )
{
try // エラー検出の、範囲の指定
{
cout << "ここからエラーの検出区間です" <<
endl;
aaa();
} // エラー検出範囲終了
catch(...)// 例外処理の内容
{
cout << "エラーが発生しました" <<
endl;
} //例外処理終了
}
2000/01/31
throw するのは実体?ポインタか?
実体でもポインタでも、とにかく throw句に書いたもののコピーが渡される。
実体を書けば、そのコピーコンストラクタが行われるし、ポインタを書いたらポインタ変数のコピーつまりアドレス値が渡される。
try{
}
catch(classname* e){
}
throw new classname;
とすると、コピーコンストラクタが流れないので効率が良いが、newしたオブジェクトのdeleteが必要である。上記の例ではclassname がリークしてしまう。自分で正しくしdeleteする必要がある。
try{
}
catch(classname* e){
delete e;
}
throw new classname;
2003/03/04
private,protected,publicメンバの継承によるスコープの変化
基底クラスメンバのスコープ | 継承 | 派生クラスでの基底クラスメンバのスコープ | クラス外部からのアクセス |
public | public | public | アクセス可能 |
protected | public | protected | アクセス不可 |
private | public | アクセス不可 | アクセス不可 |
public | protected | protected | アクセス不可 |
protected | protected | protected | アクセス不可 |
private | protected | アクセス不可 | アクセス不可 |
public | private | private | アクセス不可 |
protected | private | private | アクセス不可 |
private | private | アクセス不可 | アクセス不可 |
2000/02/04
//構造体を定義する。
struct{
int a;
int b;
char *c;
}st1; //構造体st1を定義した
//構造体を宣言する。
struct aaa{ //structの後ろに構造体タグを書く。
int a;
int b;
char *c;
}; //構造体を宣言しただけ
struct aaa st2; //構造体タグで構造体を定義。Cの時は"struct"を先頭につけなければならない。
aaa st1; //構造体タグで構造体を定義。C++の時は"struct"をつけなくてもよい。
ついでにtypedefについて
structやclassなどは型を宣言するものです。
typedefは既存の型に別名をつけます。
typedef 型 別名; と書きます。
例1)
typedef int Integer;
Integer aaa; //int aaa;と同じ意味になる。
例2)
typdef struct aaa{ //構造体 "aaa"型
に"bbb"という別名を付ける。
int a;
int b;
char *c;
} bbb;
bbb St; //struct aaa St;と同じ意味になる。
例3)
int型を返す関数へのポインタをtypedefするには
typedef int (*pfunction)(char);
と書いたりする。
これによって、以下の用に便利になる。
ex) 「int型を返す関数へのポインタ」を返す関数定義fff
int aaa(char a){・・・・・・・・・・・・・・}
pfunction fff(int a,int b){
return aaa
}
2000/02/07
どうも、インスタンスの情報を、ファイルなどに格納するために使用するときに使う物みたいです。
Serializeメソッドをつかうとできるみたいですが、このメソッドを使うために必要なおまじないが
DECLARE_SERIAL と IMPLEMENT_SERIALのようです。
参考 http://www.asahi-net.or.jp/~yf8k-kbys/vcpp13.html
2000/02/21
Debugの時とReleaseの時で処理を変えたいとき
メニューバーの[プロジェクト]の[設定]を選択しダイアログを表示します。
設定の対象を“Debug”にして、プリプロセッサの定義で“_SP_NAGOYA”と入力してみました。
#include <iostream.h>
void main(){
#ifdef _SP_NAGOYA
cout<< "NAGOYA" << endl;
//Debugの時は_SP_NAGOYAが定義されているのでこの処理が実行される。
#else
cout<< "NAGOYAじゃない" << endl;
//Releaseの時は_SP_NAGOYAが定義されてないのでこの処理が実行される。
#endif
}
このプログラムをDebug構成のプロジェクトで実行すると、“NAGOYA”と表示されます。
Release構成のプロジェクトで実行すると、“NAGOYAじゃない”と表示されます。
2000/02/21
ATL COM AppWizard | COMをサポートするアプリケーション用 ATL (Active Template Library) は、テンプレートを基本にした C++ のクラスの集合です。(テンプレートベースの COM オブジェクト作成用ライブラリ) |
Cluster Resource Type Wizard | ? |
Custom AppWizard | AppWizardをカスタマイズし新しくAppWizardを作成する。 |
DevStudio Add-in Wizard | アドイン作成用 アドインを使用すると、タスクを実行するコマンドを追加してそのタスクを自動化できます。 |
ISAPI Extension Wizard | ISAPI 拡張機能DLL またはフィルタ DLL を作成する。 |
Makefile | MFC を利用しないスタティック ライブラリを作成する .。 |
MFC ActiveX Control Wizard | ActiveX Controlを作成するとき用 |
MFC AppWizard (dll) | MFCを使用した、DLLを作成するとき用。 (またはオートメーション用←VBが昔云っていたActiveX DLLに相当) |
MFC AppWizard (exel) | MFC(フォーム)を使用した、EXE用 |
Utility Project | ? |
Win32 Application | MFCクラスの呼び出しではなくWin32 APIの呼び出しを使用したWindowsアプリケーション用 |
Win32 Console Application | 主にコンソールアプリケーション用 (コンパイルオプションにより、MFCの利用可) |
Win32 Dynamic-Link Library | DLLの作成用 |
Win32 Static Library | スタティック ライブラリの作成用 スタティック ライブラリは、オブジェクトおよびその関数とデータが入ったファイルで、実行可能ファイルをビルドする際にプログラムにリンクされます。 |
2000/02/22
一般的にBSTR型は、OLE(ActiveX)用のExport関数で文字列を返したいときに使います。この関数をVC++内で普通にprintfしてもただしく表示できません。BSTR型は、「32ビット文字列ポインタ」とあるので、unicode系かと思います。(←昌大の推測)
とりあえずですが、以下の方法ではfprintfできました。
BSTR testsub(LPCTSTR str_in);
void main(){
BSTR bstr;
bstr = testsub("12345");
printf(">%S<\n\n",bstr);
// printfでおこなうなら、%Sを使うのがミソ
wprintf(">%s<\n\n",bstr); // %sでおこなうなら、wprintfでおこなうのがミソ
// %sを使用すると bstrの参照先はUnicodeなので{610061006200・・・・・35000000}
//となっているため2バイト目がNULLと認識され"a"のみ表示される
//(Windowsではunicodeは「下位バイト+上位バイト」で格納されている。0061は6100になる)
printf(">%s<\n\n",bstr);
}
BSTR testsub(LPCTSTR str_in){
CString str;
str = "aabbc";
str += str_in;
return str.AllocSysString();
};
がしかし、全角文字がBSTRの中に入っていたときは、正しく表示できませんでした。ご存じの方がいたら、教えてください。
2000/06/17
動作検証をしている時に、printf や、coutを使用するケースも有るかと思いますが、一度画面に表示されただけで消えてしまいます。これは、標準出力先が画面になっているからです。
それをファイルに変更するばあいには、次のように標準出力先を変更すればOKです。
例)カレントフォルダの log.txtに出力する場合
[プロジェクトの設定] → [デバッグ] → [カテゴリ:一般]
プログラムの引数に、「>log.txt」
でも、TRACEマクロなどを使用した方が、きっとスマートなんでしょうけど。
2000/07/25
一つのアプリケーション単位にプロジェクトがある。
-> dsp
一つ以上のプロジェクトをまとめて、ワークスペースという単位がある。
-> dsw
エクスプローラーからVC++を起動する時は、dswを 普通はクリックしよう!
2002/08/27
2002/10/22 天の声からのご指導にて修正
nafxcwd.lib(thrdcore.obj) : error LNK2001: 外部シンボル "__endthreadex" は未解決です
nafxcwd.lib(thrdcore.obj) : error LNK2001: 外部シンボル "__beginthreadex" は未解決です
Debug/start1.exe : fatal error LNK1120: 外部参照 2 が未解決です。
MFCを使ったコーディングに対し、プロジェクトの設定(ALT
+
F7)で「MFCを使用しない」になっているとよく出ます。確認!
2002/09/28
Microsoft Foundation Classを「 MFCのスタティックライブラリを使用」か「共有DLLでMFC使用」を選択
次に「C/C++」タブを選択します。「カテゴリ」を「コード生成」にします。
「一般」で「MFCのスタティックライブラリを使用」を選択した場合は「使用するランタイムライブラリ」を「マルチスレッド」にします。
「共有DLLでMFCを使用」を選択した場合は「マルチスレッド(DLL)」を選択します。
2002/10/03
注意:プリコンパイル済みヘッダーを使うときはすべての*.c,*.cppファイルに
#include "StdAfx.h"
という行を書く必要があります。これを書かないとそのファイルのコンパイル中に
fatal error C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
というエラーが表示されます。
http://www.sam.hi-ho.ne.jp/mi-k/program/non_mfc1.shtml
2002/10/10
#if !defined _changeTime_h_
#define _changeTime_h_
void testfunc();
#endif
2002/10/10
CTest* pTest;
pTest = new CTest[50];
delete [] pTest;
2002/10/15
http://www.geocities.co.jp/Hollywood/2358/mfc_7.html
プリコンパイル済みヘッダ って何?
プリコンパイル済みヘッダとは、システムライブラリのインクルードファイルなど、内容がほぼ変更されないインクルードをあらかじめコンパイルしておき、毎回コンパイルしないようにすることでビルドを高速化するものです。
別にビルドに掛かる時間がさして問題ではない(最近のPCなら莫大な時間が掛かるほどのシステムはそうそう無いですからね)ならプリコンパイル済みヘッダは使わなくても大丈夫…だそうだ。
プリコンパイル済みヘッダを作るファイルは[プロジェクト]→[設定]の[C/C++]タブの[カテゴリ]から[プリコンパイル済みヘッダー]を選択し,"プリコンパイル済みヘッダーファイル(.pch)の作成"をチェックする.
プリコンパイル済みヘッダを使うファイルは[プロジェクト]→[設定]の[C/C++]タブの"プリコンパイル済みヘッダーファイル(.pch)を使用"をチェックする.
http://ahirujigen.hp.infoseek.co.jp/code_vc00.htm
2002/10/15
BOOL CMy20021015_MApp::InitInstance()
{
AfxEnableControlContainer();
// 標準的な初期化処理
// もしこれらの機能を使用せず、実行ファイルのサイズを小さくしたけ
// れば以下の特定の初期化ルーチンの中から不必要なものを削除して
// ください。
#ifdef _AFXDLL
Enable3dControls(); // 共有 DLL 内で MFC を使う場合はここをコールしてください。
#else
Enable3dControlsStatic(); // MFC と静的にリンクする場合はここをコールしてください。
#endif
AfxMessageBox(this->m_lpCmdLine); //ここでは取れる
CMy20021015_MAppは、ウィザードが生成した、メインアプリケーションクラスになります。
このクラスは CWinApp を継承します。
CWinAppは、パブリック変数でm_lpCmdLineを保持しています。
2002/10/15
こんな方法もあるようです。
void CWinApp::ParseCommandLine(CCommandLineInfo& rCmdInfo)
ただし、複数の引数をひとつづつ取得するには、少々処理が必要な模様ですね〜
2004/06/28
http://www.ne.jp/asahi/yamashita/programming/tips/mfc_misc_faq.html
2002/10/15
staticなメンバ変数は クラス宣言部での宣言以外に どこかで実体が定義されている必要がある。
// xxx.h
class Test{
static int SOMEVALUE; // <- staticメンバ変数の宣言
};
...
// xxx.cpp
int Test::SOMEVALUE = 0; // <- 実体の定義 & 値の初期化
2002/10/16
2002/10/20
#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>
API関連のヘルプには、Winbase.h などと書かれているが、windows.hを取り込まないとコンパイルエラーがたくさんでる。windows.hを取り込めば、だいたいのAPIはいけると思われる。
2002/10/21
/OPT (最適化)
/OPT:{REF|NOREF|ICF[,iterations]|NOICF}
このオプションは、ビルド中に LINK が行う最適化を制御します。通常、最適化によってイメージのサイズが小さくなり、プログラムの実行速度が向上します。ただし、その代わりにリンク時間が長くなります。
MSDN から、/OPT にて検索せよ。
2002/10/30
void CTestDlg::OnButton1()
{
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
CListBox* pListBox;
pListBox = (CListBox*)this->GetDlgItem(IDC_LIST1);
pListBox->AddString("a");
pListBox->AddString("b");
pListBox->AddString("c");
pListBox->AddString("d");
pListBox->AddString("e");
}
2002/11/05
探すといっぱいありそうですが、まずは、ここ
マイクロソフト サポート技術情報 - JP175030
2002/11/08
/*
DateUtility.h
*/ class CDateUtility { public: virtual ~CDateUtility(); /*日付から、曜日に変換する*/ static int ConvDayOfWeek(int Year, int Month, int Day ); private: CDateUtility(); /*インスタンス生成禁止*/ };
/*
DateUtility.cpp
*/ int CDateUtility::ConvDayOfWeek(int Year, int Month, int Day ) { int rtn; int originalDay; static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; Year -= Month < 3; originalDay = (Year + Year/4 - Year/100 + Year/400 + t[Month-1] + Day) % 7; rtn = (originalDay + 6) % 7; return rtn; }
#include "DateUtility.h"
int main(int argc, char* argv[])
{
int rtn =CDateUtility::ConvDayOfWeek(2002,11,12);
printf("%d\n",rtn);
return 0;
}
呼び側で、クラス名::メソッド名 です。 クラスメソッドとなるので、インスタンスを生成しなくても使用できます。ただし、Staticのついていないメンバー変数やメンバー関数を呼ぶと落ちるんだろうね
2002/11/12
CTimeは絶対時間、CTimeSpanは相対時間とヘルプにはあるが、要は、
100時間53秒とか、500分とかいう、値はCTimeSpanで表現しようということ。
CTime と CTimeSpan の 2 つのオブジェクトを使って、次のように経過時間を計算します。
CTime startTime = CTime::GetCurrentTime();
// ... perform time-consuming task ...
CTime endTime = CTime::GetCurrentTime();
CTimeSpan elapsedTime = endTime - startTime;
2002/12/14
イメージ
int function(){
int ret = 1:
return ret;
}
このとき、functionの戻り値であるretは、呼び元に値のコピーがされている。だから、内部変数がスコープをはずれて破壊されても有効なのである。
2002/12/16
データ型 | サイズ | 呼称 | 表現範囲 | ||
char | 1 | 文字型 | -128 | 〜 | 127 |
unsigned char | 1 | 無符号文字型 | 0 | 〜 | 255 |
short int | 2 | 短整数型 | -32,768 | 〜 | 32,767 |
unsigned short int | 2 | 無符号短整数型 | 0 | 〜 | 65,536 |
int | 4 | 整数型 | -2,147,483,648 | 〜 | 2,147,483,647 |
unsigned int | 4 | 無符号整数型 | 0 | 〜 | 4,294,967,295 |
long | 4 | 倍整数型 | -2,147,483,648 | 〜 | 2,147,483,647 |
unsigned long | 4 | 無符号倍整数型 | 0 | 〜 | 4,294,967,295 |
float ※ | 4 | 単精度実数型 | 1.175494351e-38F | 〜 | 3.402823466e+38F |
double※ | 8 | 倍精度実数型 | 2.2250738585072014e-308 | 〜 | 1.7976931348623158e+308 |
※詳しくは、MSDN参照 キーワード:float型の範囲
2002/12/28
VC++の場合には、以下の型も存在する。詳細はMSDN [データ型の範囲]
__int8、__int16、__int32、__int64 __int64は、マクロ宣言がいるようだ!
2003/03/08
2003/03/21
xxxxxxx.h(21) : error C2065: 'IDD_XXXXXXXX_DIALOG' : 定義されていない識別子です。
この識別子は、Resource.hに宣言されている。宣言されいるか確認することと、ヘッダーそのものがインクルードされている事を確認すること。
2003/01/21
[メニューバー]→[挿入]→[クラス]
「クラスの種類」コンボクックスで“genericクラス”にすると、一番シンプルなクラスができるよ。
2003/01/21
http://www.angel.ne.jp/~mike/vb_dll/index.html を参考にしましょう。
よく、Declare宣言で Alias XXXX@8 とか宣言が必要な場合があるが、
LIBRARY InputCheck.dll
EXPORTS
CharCheck @1
TimeCheck @2
DateCheck @3
のようにすれば、Aliasは不要になるみたいだ。
2003/01/25
Microsoft Visual Basic Version 5.0 で使用する DLL の開発に関する注意
http://www.microsoft.com/japan/msdn/vs_previous/vbasic/docs/dll/#5
インストールした時になんらかの原因でMSDNのショートカットが生成されない事があった。
手動で登録すればするには、次の様にすると良い。
リンク先
C:\WINNT\hh.exe C:\Program Files\Microsoft Visual Studio\MSDN\2001OCT\1041\MSDN130.COL
作業フォルダは MSDN130.COL が存在するフォルダ
2003/01/27
2003/01/27
[メニューバー]→[ツール]→[オプション]
2003/01/28
char *_getcwd( char *buffer, int maxlen );
#include <stdio.h>
#include <string.h>
struct recTest{
char d01[100];
char d02[100];
char d03[100];
char d04[100];
char d05[100];
char d06[100];
char d07[100];
char d08[100];
char d09[100];
char d10[100];
char crlf[1];
};
// 単純に、ファイルのioを行ってみる
FILE* fp1;
FILE* fp2;
recTest rec1;
recTest rec2;
int ix = 0;
if ((fp1=fopen("data1.txt","r")) == NULL ) {
printf("data1.txt オープン失敗\n");
}else if ((fp2=fopen("data2.txt","w")) == NULL ) {
printf("data2.txt オープン失敗\n");
}else{
while (fread(&rec1,sizeof(rec1),1,fp1)){
memcpy(&rec2,&rec1,sizeof(rec2));
fwrite(&rec2,sizeof(rec2),1,fp2);
ix ++;
}
fclose(fp1);
fclose(fp2);
printf("読み込み件数=%d",ix);
}
ファイルのレングスから一揆に読み込む方法
// ファイルのサイズを求めよう
CFile file;
file.Open("data1.txt",CFile::modeRead);
int leng = file.GetLength();
file.Close();
int reccount = leng/(sizeof(recTest)+0);
// 単純に、ファイルのioを行ってみる
FILE* fp1;
FILE* fp2;
recTest rec1;
recTest rec2;
int ix = 0;
recTest* prec = new recTest[reccount];
if ((fp1=fopen("data1.txt","r")) == NULL ) {
printf("data1.txt オープン失敗\n");
}else if ((fp2=fopen("data2.txt","w")) == NULL ) {
printf("data2.txt オープン失敗\n");
}else{
fread(prec,leng,1,fp1);
fwrite(prec,leng,1,fp2);
fclose(fp1);
fclose(fp2);
printf("読み込み件数=%d",reccount);
}
delete []prec;
2003/02/06
DLLを静的リンクする際に利用側となるものは、
ヘッダファイル→これが無いと、コンパイルが通らない。
LIBファイル→このなかに、それぞれのEXPORTした関数のエントリーポイントが書いてある。リンクする際に必要。
実行時に必要なものは、検索パスにDLLファイルがあるだけでよい。
DLLファイルを修正した場合、インターフェイスを変えなければ、LIBは再配布する必要はない。つまり、呼び元のリコンパイル&ビルドは必要ない。
2003/09/05
_DEBUG | デバッグモードでコンパイルされるとき #ifdef _DEBUG AfxMessageBox("デバッグモード!!"); #endif |
__FILE__ | 現在のソース ファイル名。__FILE__ は展開され、二重引用符で囲まれた文字列になります。 |
__LINE__ | 現在のソース ファイルの行番号。行番号は 10 進の整数定数になります。この値は #line ディレクティブで変更できます。 |
クラスライブラリの作り方は予想以上に簡単。VBや、Cから呼ぶ必要がなく、VC++からだけ呼ばれば良いのであるならば、クラスライブラリ化した方が簡単である。
概略は、MFC DLLベースでバイナリを作成する。その際、外部に公開するための修飾子ExportをつければOK。あとは、そのクラスに対し、CStringのごとくクラスとして単に利用するだけである。
2003/02/14
構文メモ
while( 1の間 ){
continue;
}
CMapからの全件取りだし例 MSDN 「 コレクション : コレクションの全メンバのアクセス 」
CMap<CString, LPCTSTR, CPerson*, CPerson*> myMap;
POSITION pos = myMap.GetStartPosition();
while( pos != NULL )
{
CPerson* pPerson;
CString string;
// Get key ( string ) and value ( pPerson )
myMap.GetNextAssoc( pos, string, pPerson );
// Use string and pPerson
}
2003/02/22
CMap<CString,LPCTSTR,int,int> myMap;
2004/04/27
MSDN [ClassView の使い方」で検索
2003/03/01
ビルド系
Ctrl + F5 | 実行 | デバッグ系のF5と、どう違うか? |
Ctrl + F7 | 現在のファイルだけをコンパイル | |
エディタ系
Ctrl + Shift + 8 | TAB、改行記号 の 表示/非表示を切り替える | メニューバー:編集→高度な操作 からも可能 |
デバック系
F9 | ストップマークを設定/解除 | メソッド入り口で止めたい時は { のある行で指定すること |
Ctrl + Shift + F9 | 全てのストップマークを解除 | メソッド入り口で止めたい時は { のある行で指定すること |
F5 | 実行 コンパイルしていないファイルは自動ビルド |
|
F10 | 下へ潜らないで、そのままステップ実行 | |
F11 | 下へ潜りながら、ステップ実行 | |
Shift + F11 | 上へ上がりながら、ステップ実行 | |
Ctrl + F10 | カーソル行まで実行 | |
F5 と Ctrl + F5 はどう違うか?
コンソールアプリケーションでは、Ctrl + F5にて実行すると、コンソールが閉じる前にHitAnyKeyが表示されて一時停止するが、F5では実行後瞬時にコンソールが閉じてしまう。
2004/03/11
http://www.microsoft.com/japan/developer/library/vcug/_asug_memory_details_dialog_box.htm
2003/03/02
拡張子 ncb のファイルを削除して、再生成させよ。たいてい回復する
2003/03/04
const 型 変数名
const付きのポインタ変数は、あくまで、指し示す先のオブジェクトの内容が固定になるということ。アドレス値は変更できる。
そもそも、引数の値は、必ずコピーされてくるわけだから、(const
int i)なんてやっても意味が無いのだ
void test4_2(const int* i){
const int* pi = i;
pi = i; //代入しても良い
pi = NULL; //値を変更できる
pi = i;
*pi = 2; //コンパイルエラー 指し示すエリアの値は変えられない。
}
型 const 変数名
これは const char* name が、nameが示す実体の値を書き換えられないのに対して
char* const name
は、nameの示す実体の内容は着替えられるが、他の実体はさせないということ。
じゃ、const char* const name ってあるんか?今度調べてみよう
リファレンスも同じ考え方
void test5_1(const int& i){
int i1 = i;
i1 = 3; //OK iの示す中身を複写した別ものだからOK
i = 3; //コンパイルエラー iはコンストオブジェクト
}
2003/03/10
リンク先を見て一度勉強しましょう
http://tt.sakura.ne.jp/~suzu/tips/cast.html
なお、VC++でダイナミックキャストを使用するときは、下記の設定をしておく必要がある。
そうしないと
dynamic_cast' が /GR- を使用したポリモーフィック型 'class ClassName' で使用されています; 動作結果は保証されません。
が表示されてしまう。
2003/04/19
..\..\..\include,..\..\..\..\common\include のように、カンマ区切で複数設定できる
ライブラリのパスの追加
2003/03/25
VS2008 では、指定方法が変わっている→20080725_vs2008_simple_common_function_implement/vs2008_simple_common_function_implement.html
#define MAX_PATH 260
windef.h
new foo[n] で配列を作成した場合に、確保されるメモリ領域は「sizeof(foo) * n + デリミタのサイズ」分である。
よって
foo *pfoo = new foo[0];
で取得できるpfooのアドレスはnewでアロケートされた配列のデリミタのアドレスである。
(「foo * 0 + デリミタ」がアロケートされる)
qsort(array.GetData(), // ソートする配列の先頭 array.GetSize(), // 配列の要素数 sizeof(ClassName*) , // 配列要素のサイズ この例は、ポインタ値をそーとする class::compareFunction // 比較関数 ); int class::compareFunction(const void *pkey1, const void *pkey2){
ClassName
** p1 = (
ClassName
**)pkey1;
ClassName
** p2 = (
ClassName
**)pkey2; //p1 < p2 は負を返すこと //p1 == p2 は0を返すこと //p1 > p2 は正を返すこと 降順にする場合は、逆です return (*p1)->value - (*p2)->value; }
2003/05/06
ネットで便利なマクロが登録されている。これを、IDE上から簡単に実行できるようにする時の方法について。
2003/06/06
自分のコーディグバグもあるのかもしれませんが、あるページで参考になる事が書いてありました。
最初はインストールしてあるWindowsのどこかが腐ってしまっているのかとも思い、何度かWindows XP のクリーンインストールや Visual Studio のインストールをやり直したり、あるいは色々なデバイスを無効化してみたりもしましたが、まったく治まりませんでした。 そして最後に疑ったのはIME関係。 XPでは新しく 「言語バー」 が導入されており、どうもこの言語バーとVisual Studio のデバッガの相性が良くないような気がしてきました。
言語バーの状態は、コントロールパネルの「地域と言語のオプション」から非表示にする事ができますが、言語バーのプログラム実体である CTFMON.EXE は、依然ログイン時に必ずプロセスとして自動的にロードされてしまいます。
この自動ロードを指定しているレジストリ ( HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run ) で CTFMON.EXEのロードを指定している部分を手で削除しても、次回Windows起動時には自動的に設定が復活してしまうところなど、 「このプログラム、ますます怪しい!」 と思いました。
http://www.wg7.com/w2ktips/#CTFMON
これを参考にレジストリから消してみましたら、私も固まらなくなりましたねぇ〜
2003/06/17
整数どうしの割り算は、入れ先の型に関係なく、整数になってしまいます。
float f;
int a = 5;
int b = 7;
f = a / b;
fは、ゼロになってしまいます。これはCの規則のようです。
期待する値を求める為には、どちらかをfloat型にキャストすれば良いようです。
float f;
int a = 5;
int b = 7;
f = (float)a / b;
2003/06/18
GetLastError関数の戻り値の数値から、エラーの意味を調べたい時に、便利なTOOLがある。
[スタート]→[プログラム]→[Microsoft Visual Studio 6.0]→[Microsoft Visual Studio 6.0 ツール]→[Error Lookup]
2003/07/22
sprintf("abc\ndef\n");
のように文字列を作成し、ファイルに出力した。それを秀丸で開くと正しく改行してくれるのであるが、ノートパッドで開くと
abc↑def↑
のように表示されてしまう。
バイナリエディタで確認すると、"\n"は、0x0A
であった。
秀丸では0x0Aだけでも改行表示してくれるが、ノートパッドは0x0D0Aをいれないとダメみたいである。
sprintf("abc\r\ndef\r\n");
MSDN
¥記号の規則
規則 | 意味 |
\a | 警報 (0x07) |
\b | バックスラッシュ (0x08) |
\f | 改ページ (0x0c) |
\n | 改行 (0x0a) |
\r | キャリッジ リターン (0x0d) |
\t | 水平タブ (0x09) |
\v | 垂直タブ (0x0b) |
\\ | バックスラッシュ (0x5c) |
\" | 引用符 (0x22) |
\' | 単一引用符 (0x27) |
\nnn | その 8 進値が nnn である文字 (ここで n は 0〜7) |
\Xnn | その 16 進値が nn である文字 (ここで n は 0〜9、a〜f または A〜F) |
2003/08/14
2003/09/01
2003/09/11
winbase.h
VOID OutputDebugString(LPCSTR lpOutputString)
を使用する
dprintf を使用する。
#include <dprintf.h>
------------------------
#ifdef DEBUG
dprintf("%s=%d\n","aaa",1);
#endif
・#include <dprintf.h> を宣言すること。
・DEBUG を宣言しないと、無効になる。
2003/10/30
C:\aaa が存在しているときに、 C:\aaa\bbb\ccc\ を作成したいときにどうするか?
MakeSureDirectoryPathExists を使用すれば良い。
#include <imagehlp.h>
BOOL Brtn = MakeSureDirectoryPathExists("c:\\aaa\\bbb\\ccc\\");
ただし、imagehlp.lib を組み込む必要あり。
フォルダ名に、スラッシュ指定はできなかった
2003/10/30
ヘッダファイルがプロジェクトに登録されているか確認!
2004/01/23
開発対象ソースをデバッグビルドで開発をしている。使用するDLLはリリースビルドされている。
開発対象ソース側のCArrayをDLL側に渡してメンバをセットしてもらった後、開発対象側でCArrayのRemoveAllを行うと、CArray内のメモリ解放時にAssertが発生してしまう現象があった。
推察すると、DLL側つまりリリース用CArrayにデータを追加する時は、メモリの再アロケート時にイメージはリリース用であるが、デバッグ側でメモリを解放するときは、デバッグイメージであるにも関わらず、デバッグ用の情報が無いのでAssertが発生したと思われる。
つまり、リリースモードでアロケートした領域をデバッグモードで解放すると、警告が発生されると解釈した。
解決方法は、アロケート側と解放側のメモリの取り方を合わせれば良い訳である。
今回は、デバッグビルドされたDLLを入手できなかったので、開発対象側のメモリの取り方をリリース用に合わせた。
その方法
[プロジェクトの設定]→[C/C++]→[カテゴリ:一般]→[プリプロセッサ]
_DEBUG を 取れば良い。
参照 MSDN : メモリ管理とデバッグ ヒープ
2004/04/23
http://www1.kcn.ne.jp/~robe/cpphtml/html03/cpp03057.html
2004/05/05
スーパークラスにあるインライン指定された仮想関数を、サブクラスでオーバーライズしている場合、どのような事が起きるか?
インライン関数は、コンパイル時に呼び元に展開される事がある。仮想関数は実行時にサブクラスが存在する場合に実行される関数が切り替える事ができるので、コンパイル時に確定できない〜。
で、実際に行なうとどうなるか?
どうやらインライン指定は無視されているかの如く、正常に動作した。
うまく行かない時は、リビルドをせよ!←これで私はハマッタ
2004/05/31
ソースエディタ上で F9 等から、ブレイクポイントを設定できる。が、任意の条件の時だけ停止して欲しいときは、以下の方法が簡単。
2004/05/31
コントロールをダイアログのメンバーとしてアクセスできれば良い訳ですね
2004/05/31
int main(int argc, char* argv[])
[0]は、プログラム名そのものが入って来ます。
[1]以降に、引数が設定されてきます。
これは、Windowsでも、UNIXでも 同じなようです。
VS2008
初期値は、
C:\Documents and Settings\UserId\My Documents\Visual Studio 2008\Projects
である。これを、変更するには、以下のダイアログより設定する
vs2008環境で、入門的なベタCソースを作成してみたい。どうやってやるか…?
実際にやってみた。ココを参照
プロジェクトのプロパティーシートから設定する
http://msdn.microsoft.com/ja-jp/library/0k0w269d.aspx
Microsoft C/C++ の拡張機能
http://msdn.microsoft.com/ja-jp/library/34h23df8.aspx
例として、以前普通に使っていた strcpyを使用すると、コンパイル時にワーニングになってしまう。
#include <stdio.h> #include <string.h> #include "proto_conv_instance_id.h" int proto_conv_setup(const char* file_name, int record_size){ return 0; }; int proto_conv_get_instance_id(const char* key, char* instance_id){ strcpy(instance_id,"インスタンスIDを入れてみた"); strcpy(key,"キーを変更してみた"); return 0; };
警告 1 warning C4996: 'strcpy': This function or variable may be unsafe. …
これを抑制するには、#define _CRT_SECURE_NO_DEPRECATE を付ければ良い
#define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <string.h> #include "proto_conv_instance_id.h" int proto_conv_setup(const char* file_name, int record_size){ return 0; }; int proto_conv_get_instance_id(const char* key, char* instance_id){ strcpy(instance_id,"インスタンスIDを入れてみた"); strcpy(key,"キーを変更してみた"); return 0; };警告になる関数のヘッダよりも、上に 宣言する事がポイント
複数のEXEから使用される共通関数の開発をするときの、一例
もっともシンプルな形をとりたい。→コンソールアプリケーション、スタティックリンク
VS2008
こんなメッセージが表示されて、デバッグできなくなってしまった。
原因は解明できていないが、以下の設定を調整すると、とりえあず、普及できるかもしれない
[ツール]→[オプション]
このチェックをOFFにしてみること
printf などを用いて、メッセージを出力するとき、標準とエラーを分ける方法もある
fprintf(stdout,"okokok"); fprintf(stderr,"ererere");
上記のように実装しておくと、
hogehoge.exe > info.txt 2> err.txt
それぞれ
> 標準出力 …stdout
2> エラー出力…stderr
stdout stderr は、それぞれ stdio.h で 宣言されている。MS VC++の場合
#ifndef _STDSTREAM_DEFINED #define stdin (&__iob_func()[0]) #define stdout (&__iob_func()[1]) #define stderr (&__iob_func()[2]) #define _STDSTREAM_DEFINED #endif