【初心者歓迎】C/C++室 Ver.4【環境依存OK】
5 :
デフォルトの名無しさん:04/01/08 14:04
template <> class basic_string<int> {
public:
basic_string(int dt) {
char ss[10];
sprintf( ss, "%d", dt );
?? = ss;
};
};
stirngクラスで、intに対応したクラスを作ろうと思って、書いては見たんですが、
int型をchar型に変えたssを何に代入すればいいのかわかりません
教えてください
>>5 何のために新しいクラスを作る必要があるのかわからんが
int から string に変換したいのなら
#include <sstream>
std::string itos(int a) {
std::stringstream strm;
a >> strm;
return strm.str();
}
でいいんでね。
あるいは boost::lexical_cast とか。
7 :
デフォルトの名無しさん:04/01/08 18:47
>>6 void (string a, string b);
だと、int渡すとエラーになるから、intを対応さしたいんだけど
8 :
デフォルトの名無しさん:04/01/08 18:49
Linuxで値を設定するとその値の時間が経ったら立ち上がる関数ってないですか?
>>7 オーバーロードを使いなさい
void fun(string&,string&);
void fun(int,int);
>>7 ますますわからん
それはその関数を作り直すべきところなんじゃないか?
というか string しか受け付けないなら自作 string を渡してもはねられるだろ。
11 :
デフォルトの名無しさん:04/01/08 20:09
プログラム初心者ながら現在VC++でプログラミングしてます。
1msecの待ち時間を入れるにはどういう関数を使ったらいいのでしょうか。
#include <windows.h>
Sleep(1);
普通にSleepじゃ1msecにはならんな。そんなに精度高くない。
つか、どうして初心者が1msecの待ち時間が必要なのか、そちらのほうが興味ある。
実は
>>11に待ち時間など必要ないに、100ルピー
C初心者です。
Win98SE,LSI-C86試食で、DOS用テトリスでも作ってみようかと思ったんですが、
精密な時間(一秒以下の)を測る方法ってありますか?
画面の書き換え間隔を、一万回ループとかにしとくのも心許無いんで…。
あと、画面描画は、一画面分の文字列を一気にprintfしてウェイトの繰り返し、
って方法しか思いつかなかったんですが、他に何か方法ってありますか?
温くてすいません。
16 :
デフォルトの名無しさん:04/01/09 03:51
レベルが下がって恐縮ですがこちらも質問です。
BCB6使ってるんですが、コールバック関数でファイルを検索する最中に、
検索途中経過を表示するダイアログを出そうと思ってます。
で、検索に入る直前にDialog1->Show();して、
コールバック関数がファイルを発見するたびに //(TCustomForm Dialog1)
Dialog1->Label1->Caption = (発見したファイル数)+"件のファイルが見つかりました";
みたいにやってるんですが、処理が早すぎるせいかラベルには何も表示されません。
ためしに、コールバック関数を使ってるのと同じメインフォームに貼り付けてある
ステータスバーに表示させると、
ちゃんと発見したファイル数の表示が高速で切り替わっていくんですが…。
もしかしてこういうケースの時に使うコンポーネントの選択を間違ってるんでしょうか?
よろしければアドバイスなどお願いします。
>精密な時間(一秒以下の)を測る方法ってありますか?
以下の感じかな。引数である間隔の時間の単位はミリ秒で10以上推奨。
複数のタイマーを同時使う時は引数にパスワードを付けたりするとよい。
#include <stdio.h>
#include <windows.h>
int Timer(unsigned long time)
{
static unsigned long end=0;unsigned long now=GetTickCount();
if(end==0)end=GetTickCount()+time;
if(now>=end){end=0;return 1;}
return 0;
}
int main(void)
{
int t;
for(t=0;t<10;)if(Timer(500)){t++;puts("hoge");}
return 0;
}
>画面描画は、一画面分の文字列を一気にprintfして
表示するタイミングは初期、ラインがそろった時、ブロックが現れる時、
ブロックが落ちる時、キー入力でブロックが動く時があって、
前の2つはそれで良いのだけど、後の、特にキー入力の時は
表示が追いつかなくなるので、移動前のブロックを消して移動後の
ブロックの表示と部分的の表示の方が良い。
21 :
デフォルトの名無しさん:04/01/09 11:30
C言語で、三角関数sin(x)の値を得るには
y=sin(x);
という記述でいいのでしょうか?
また、xはラジアン角で指定するらしいのですが、ラジアン角の指定の
しかたもいまいち解りません。
360°= 2πラジアンなので、
rad = degree / 180 * PI;
y=sin(rad);
>>15 >DOS用テトリスでも作ってみようかと思ったんですが、
>精密な時間(一秒以下の)を測る方法ってありますか?
測るんじゃないんだよ、タイマー割り込みで回すのだ。
コンシューマーやアーケードではV-SYNC同期なのだが、
PCの場合なら適当なタイマー割り込みだね。
Windowsムービーメーカーでは動画キャプチャできないカメラから、
イメージをキャプチャしてそれをリアルタイムに動画で書き出すことは可能ですか?
うまく説明できないので、
「カメラから、現在映っている画像を取得する。
そのデータを、動画データに変換」
「」を繰り返して、最終的に何分かの動画になる。
できれば、フレーム間隔は一定。
このようなことはできますか?
25 :
デフォルトの名無しさん:04/01/09 17:35
>>17 それだと、t++;puts("hoge");の分の処理の遅れがでませんでしょうか?
微々たるものでしょうが、それも考慮して精度を上げたいのですが・・・
>>15 >精密な時間(一秒以下の)を測る方法ってありますか?
マシン次第。
どうでもいいが、
>>18の言うように
画面表示に変更がある場合のみに出力するように変更した方がいいぞ。
アルゴリズムを見直せ。
>>10 intとstringの順番が前後しても、問題ないようなのを作りたいんです
28 :
デフォルトの名無しさん:04/01/09 18:38
Windowsで1度呼び出すと設定時間周期でシグナルを投げつづける関数ってありませんでしょうか?
>>27 string itostr(int i) {
char str[16];
sprintf(str, "%d", i);
return str;
}
31 :
デフォルトの名無しさん:04/01/09 19:26
>>30 ありがとうございます。
SetTimerを使用した場合、コールバック関数の処理が重いと
次のSetTimerをコールするタイミングが遅れ、
そのためにシグナルを投げるのが遅くなってしまうので悩んでます。
SetTimer って一度呼べば十分なんじゃなかったっけ?
>>32 ううう・・・そうでした。
解決しました。ありがとうございました。
36 :
デフォルトの名無しさん:04/01/09 19:55
前スレ埋まった。
>>35 アホは俺でした。回線切って首吊って氏んできます。
イ㌔
>>15です。(
>>11,
>>25さんとは別人です。念のため)
皆さん回答有難うございます。
>>17さん、なんだかLSI-c試食ではwindows.h使えないっぽいです。32bitがどーたらで。
標準ライブラリの時間取得は秒単位までらしいので、他に手はないものかと…。
>>18,
>>26サン。
そうですね。必要な時に必要なだけ描画する方がいいですね。
dos窓で30fpsは無理そうだ…(そんなに要らないけど)
あと、描画時にどうしても書き掛けの文字列が表示されて、画面が一瞬ぶれちゃうんですけど、
どうにかなんないでしょうか。ちなみにマシンは多分4年くらい前のVAIOノートです。
>>39 bccとかMingWとかWin32対応したコンパイラ使う。
>>25 微妙にずれていくかもしれないけど。表示を変えただけだけど実験用。
#include <stdio.h>
#include <windows.h>
int Timer(unsigned long time)
{
static unsigned long end=0;unsigned long now=GetTickCount();
if(end==0)end=GetTickCount()+time;
if(now>=end){end=0;return 1;}
return 0;
}
int main(void)
{
int t;unsigned long start=GetTickCount();
for(t=0;t<10;)if(Timer(500)){t++;printf("%ld\n",GetTickCount()-start);}
return 0;
}
>標準ライブラリの時間取得は秒単位までらしいので
clockがあるけど、環境で微妙に変わるみたい。
>描画時にどうしても書き掛けの文字列が表示されて、画面が一瞬ぶれちゃうん
まず、機種は十分だと思う。ドス窓は上書き型だから、部分表示をしていれば
全体としてずれてくる事は無いと思うのだけど。
>>40 やっぱりそれしかないですかね。いずれにせよLSI-CじゃWinアプリ作れないし。
LSI苦労して入れたばっかなのに…w
>>41 ああ…遠いなあ。何言ってるか全然分かりましぇん。
>>42 clock()さっき試してみましたが、どうもtime()と出力される値が一緒で
(一秒おきに同時にカウントアップする)使えなさそうでした。
>まず、機種は十分だと思う。ドス窓は上書き型だから、部分表示をしていれば
>全体としてずれてくる事は無いと思うのだけど。
あ、はい。全体表示(25行x16文字)してました。
ん、あれ?ていうか、部分表示ってどうやるんですか?
今やってるのは↓なんですけど(すいません、巧く説明できないもので)、
部分表示っていうのは、既に描いた文字を、一部書き直すやり方ですよね。
文字の上書きなんて出来るんでしょうか。ご教授下さいマセ。
static char field[25][16]={…初期化(16文字間隔で\nを代入)…};
for (i=1;i<=20000;i++)/*メインループ*/
{
printf('\f');
printf(field);
for (j=1;j<=3000000;j++)/*ウェイト*/
printf("");
}
44 :
デフォルトの名無しさん:04/01/10 02:41
質問です。UNIX上でC言語で組んでます。
char型からint型に変換するのは
atoi(char c);
で出来るんですが、逆にchar型からint型に変換する方法はありますか?
sprintf
あと char 配列な。
そのくらい汲んでやれと小一時間・・・
>>49 コンパイラは、暫くLSI-Cで行ってみようかな、と。
DOSの世界も勉強したいですし。
動きました!jがオーバーフローしてたっぽいけど。
"\x1b[%d;%dH■"
が重要だったんですね。エスケープシーケンスか…面白そう。
色々調べてきて、勉強になりました。
何とかなりそうです。長々とありがとうございました!
51 :
デフォルトの名無しさん:04/01/10 13:41
boostを使おうと思ったのですが、コンパイルしようとすると
「オプションコンテキスト応答深度の上限を超過: 再帰をチェックしてください」
というエラーが出てしまいます。これはどういったエラーで、またこれを回避するには
どうしたらいいのでしょうか。
環境は
OS:windows XP
コンパイラ:borland c++compiler5.5.1
です。
52 :
デフォルトの名無しさん:04/01/10 14:19
はじめまして。C言語初心者です。
どなたn×n(n:奇数)の大きさの魔方陣のプログラムを教えて頂けませんか?
53 :
デフォルトの名無しさん:04/01/10 14:40
SH系で、static const char *a = "abc";
文字列はCセクションになりますが、Dセクションにこの文字列の参照が入ります
Dセクションを使わないようにするにはどうしたらいいですか?
static const char * const a = "abc";
55 :
デフォルトの名無しさん:04/01/10 14:58
CLASS1::CLASS1()
: hoge(0),fuga(0)
{
}
C++でこんな宣言を見かけたんですがどう解釈すればいいんでしょうか?
どうかよろしくお願いします。
>>54 サンキュー
久々にCに戻ったから忘れちまってた
会社の都合で・・・
>>55 メンバ初期化子とか、メンバイニシャライザとかかな。
一般的には何て言うんだろう。
WinMe/VC6で
char *box[299];
strcpy(box[10],"hoge");
ってやったらbox[10]以外も全部"hoge"になるっぽいんだけど、どこが間違ってるかおしえていただけませんか?
>>58 何がやりたいのか解らんが、初期化していないポインタを使用してはいけない。
>>58 char box[299];
strcpy(box,"hoge");
>>51 とりあえず英語版の BCC を使えばそんなエラーは出さずに済むんで
そっちを使ってみては?
(日本語版そのものってサポートされてたっけ……)
>>58 質問内容がどうもわからんが
とりあえず box はちゃんと配列の配列で宣言するかしないと
char ポインタの先に領域が確保されていないんで未定義動作が引き起こされる。
正直、スマンカッタ
もっぺん組みなおしてくる。
>>61 ありがとうございます。早速試してみたいと思います。
>>55 もうわかったのかな?
CLASS1::CLASS1(){
this->hoge = 0; this->fuga = 0;
}
とほぼ同じ。
ただ こちらだとhoge,fugaを生成してから代入するのにたいし、
君のだとコンストラクタ時に値を使用して作成される(あー、うまくカケネーや)、
場合によって動作が変わる時がある。
class a; a=0;
class a(0);
の違いみたいなもん。
CLASS1::CLASS1() : hoge(0), fuga(0) { }
は初期化。
CLASS1::CLASS1() { hoge = 0; fuga = 0; }
は代入。
int とかだと有難味がないかもしれないけど、
クラスの場合はコンストラクタを呼ぶのに
必要になることがよくある。
constなメンバはメンバイニシャライザを使わないと
初期化できないということもある。
std::auto_ptr<>みたいに初期化と代入で記述がかなり違う奴もあるな。
>>64 > ただ こちらだとhoge,fugaを生成してから代入するのにたいし、
hoge, fuga が POD 型だと、変わらんけどな。
hoge, fuga が非 POD だと、hoge(0), fuga(0) の場合
1. CLASS1 を格納するに十分なメモリが割り当てられる
2. hoge と fuga のコンストラクタが呼ばれる (引数は 0)
3. CLASS1 のコンストラクタが呼ばれる
となって、hoeg = 0, fuga = 0 だと
1. CLASS1 を格納するに十分なメモリが割り当てられる
2. hoge と fuga のコンストラクタが呼ばれる (引数なし)
3. CLASS1 のコンストラクタが呼ばれる
4. hoge と fuga の代入演算子が呼ばれる
という順番になる。
>>68 いや、初期化子を省略した場合
POD 型のデフォルトコンストラクタは呼ばれない。
POD 型のデフォルトコンストラクタは 0 クリアだけど、
初期化子で明示的に呼んだとき、
もしくはnew するときにしか実行されない。
class CLASS1 {
int hoge, fuga;
public:
CLASS1() : hoge() { cout << hoge << endl << fuga << endl; }
};
を実行してみれ。
70 :
デフォルトの名無しさん:04/01/10 22:49
BCB6ですが、コールバック関数でファイルを検索する最中に、
処理をキャンセルするダイアログを出そうと思ってます。
しかし、コールバック関数が回ってる間はマウス操作を一切受け付けてくれなくて困ってます。
一応出したダイアログはUpdate();を繰り返したりもしてみたんですが…
とりあえず、解決策として、関数に何かコードを入れるのか、
ダイアログのプロパティを設定すればいいのかもよくわかりませんです
こういう場合、マウス操作を受け取れるようにして、途中でコールバック関数を停止させるには、
どうしたらよいのでしょうか…。おねがいします。
71 :
デフォルトの名無しさん:04/01/10 23:02
行列の表示に関する質問なんですが、よろしくおねがいします。
for(int i=0; i<3; i++)
{
cout<<"|";
for(int j=0; j<3; j++)
{
cout<<matrix[i][j];
}
cout<<"|";
}
このように書くと、当然matrix[i][j]の数字のケタ数によって
横の幅がバラバラになりますよね。そこでsetw()なりwidth()なりを
使って書式指定し、上手く幅を揃えたいのですが、例えば
cout<<setw(3);
cout<<matrix[i][j];
などとすると、matrix[1][j]が1ケタでmatrix[2][j]が4ケタの場合
揃わなくなってしまいます。あらかじめmatrix[i][j]の最大ケタ数がわかっている場合なら
setw()の数字をそれより大きくしておけばいいのですが、ケタ数が色々変化する場合は
どのようにして幅を揃えればよいのでしょうか。
あらかじめ最大桁数を取得し設定する。
処理の流れを考えれば他に方法はない。
まあ途中で切れてもいいのなら
あらかじめ絶対桁を指定してそこに収まるように指示してもいいが。
>>72 うーむ、それしかないですか・・・
どうもありがとうございました。
>>70 BCBならイベントハンドラのこっちゃないのか?
それとも本当にコールバック関数で処理しているのか?
BCB(つかVCL)だとこの2つは厳密に使い分けるぞ。
以下はイベントハンドラの話として回答。
要点は、
その一:
Update()はファイル検索ループの中で呼び出すべし。
その二:
ダイアログから検索ループを回してるフォームにキャンセルを通知する手段が必要。
たとえば、
フォームにbool値型フィールド(ex.FCanceled)とそれにアクセスするpublicメソッド(ex.CancelCopy() )を実装。
ユーザがキャンセルボタンを押す
→ダイアログがメインフォームのCancelCopy()を呼ぶ
→CancelCopy内でFCanceledを立てる
→検索ループでは定期的に if ( FCanceled ) break; をチェックする
んな感じ。なお、面倒くさかったらFCanceledをそのままpublicにしちゃう(w
↑どうでもいいが訂正
×CancelCopy
○CancelSearch
>>74 重大な訂正
あー、Update()してどうすんだよ。
Application->ProcessMessages() 呼ぶんだよループから。
いいかげん飲み過ぎたみたいなんで寝ます。じゃね。
>>74 >>76 ありがとうございます!できました!
とてもわかりやすくて助かりました。おやすみなさい!
>>69 > POD 型のデフォルトコンストラクタは呼ばれない。
誰か POD 型のデフォルトコンストラクタを呼ぶと書いてる?
>>78 >>68 2. hoge と fuga のコンストラクタが呼ばれる (引数なし)
俺が悪かった。
std::vector<AnsiString> hoge=("あか","あお","みどり");
これがコンパイル通らないので //char*型はstd::vector<AnsiString>~に変換出来ない
std::vector<AnsiString> hoge;
hoge.push_back("あか","あお","みどり");
と強引にこんなことやってみたんですが、やっぱむりでした。
vectorに1行で複数の初期値を代入するにはどう書いたらいいんでしょうか?
いろいろあるだろうが、一番簡単なのは、
const char *colors[] = {"あか", "あお", "みどり"};
std::vector<AnsiString> hoge(colors, colors+3);
>>83 ありがとさんです、その一番簡単な方法ですることにします。
colors+3より、colors+ sizeof(colors) / sizeof(*colors)の方が良いと思う。
#define ELEMOF(array) (sizeof (array) / sizeof *(array))
で
colors+ELEMOF(colors)
>>86 その辺は趣味だな。
template <typename T, size_t N>
inline T*
lastof(T (&ary)[N])
{
return &ary[N];
}
template <typename T, size_t N>
inline T const*
lastof(T const (&ary)[N])
{
return &ary[N];
}
boost::array<const char *, 3>::endとかね。
boost::array<>は要素数を数えてくれないからなあ。
それとも俺が知らないだけで数えさせる方法があったりする?
90 :
デフォルトの名無しさん:04/01/11 18:51
どなたか↓のどこがおかしいのか教えてもらえませんか?
#include <stdio.h>
main()
{
double a,b;
printf("2つの実数をスペースで区切り、入力する\n");
scanf("%1f %1f",&a,&b);
printf("tasu=%f\n",a+b);
printf("hiku=%f\n",a-b);
}
>>90 scanf("%1f %1f",&a,&b);
>>89 size()
max_size()
static_size <- static 用
どれも中身は同じ。
>>90 C言語なら return 0; 付けるのも忘れずにな。
94 :
デフォルトの名無しさん:04/01/11 20:03
Born=1975
Hoby=乗馬
Work=力士
Adress=ハワイダイアモンドヘッド島サンチャゴ市イーストストリート
Tel=090-2000-2000
みたいなフォーマットで入ってるプロフィール用の.txtファイルが大量にあります。
で、一つのファイルの中にどの順番にどの項目/値が入ってるか、入ってないか、は不明なんですが、
必要な項目は"Name","Born","Adress","Tel"だけなんです。
で、引数に必要な「項目」を与えれば値が帰ってくる関数を作ろうと思ったんですが
(例えばHead("Tel");とかやれば"090-2000-2000"が返ってくる)
、どうも上手くいきません。
自分の頭の悪さを思い知る次第ですが、丸一日くらい延々とやっても出来ないです。
以下は自分で頑張って途中まで書いてみたコードです。
とにかくファイルの数が多いので簡潔かつ高速化したいと思ってるんですがそれ以前の問題ですね…
よろしければアドバイスのほど、よろしくお願いします。
const char *head[] = {"Name","Born","Adress","Tel"};
std::vector<AnsiString> VecHead(head, head+4);
AnsiString Head(AnsiString Item,AnsiString Text){
//Itemは"Name"とかの項目名。Textはファイルから抜き出した1行。
int Tpos = Text.Pos( "=" );//"="の位置を調べる
AnsiString str = Text.SubString(1, Tpos-1 );//その行が何の項目かを抜き出す。
AnsiString Val = Text.Delete( 1 , Tpos ); //値を切り離してValに入れる。
AnsiString *i;
i =std::find(VecHead.begin(),VecHead.end(),str);//項目がファイルの中に存在するか調べる
//これ以上できませんでした…
}
テストでございます
確認だが、1ファイル1人か?
あと、AnsiStringを使ってるということは環境はBCBか?
BCBならTStringListでファイル読込んで TStringList->Valuesで
何も悩まずに値を取得できるが?
TStringList使ってかまわないならヘルプ読んでみ。
多分30分もかからんで書けるで。
>>93 >size()
>max_size()
>static_size <- static 用
const char *colors[]←これのことだと思われ。
>C言語なら return 0; 付けるのも忘れずにな。
C99ならok!
>>97 そうです、1ファイル一人です、っていうか
>BCBならTStringListでファイル読込んで TStringList->Valuesで
>何も悩まずに値を取得できるが?
↑コレ読んで涙が出そうになりました…、知らんかった(;´Д`)
これでおっしゃる通り簡単に出来るのではと思います。
どうもありがとうございます。
100 :
デフォルトの名無しさん:04/01/11 20:36
c++なんですが、BCCを使ってのコンパイルが出来ません。
bcc32 hello.cpp(対象のファイル名)
と、小林健一郎さんの入門ページに書いてあるとおりやったのですが、
エラー E2209 hello.cpp 2: インクルードファイル 'iostream' をオープンできない
エラー E2282 hello.cpp 3: 名前空間名が必要
エラー E2451 hello.cpp 7: 未定義のシンボル cout(関数 main())
エラー E2451 hello.cpp 7: 未定義のシンボル cout(関数 main())
と表示されてしまいます。見本のページと同じようにやっているのに何がいけないんでしょうか。
どなたか教えてください。
ちなみに、当方、昨日プログラムを始めたばかりの初心者で右も左もわかりません。
わかりやすく教えていただけたらうれしいです。
>>92-93 すまん。俺の書き方が悪かった。
>>98が言う様に、int array[] = { 0, 1, 2, 3, }; みたいにboost::array<>は要素数を明示せずに
初期化出来ないのかな、という事。
iostream.hとか、using namespace std;とか、std::coutとか、そういう事じゃないかな。
>>101 .Borland C++
Borland C++はあらかじめインストールしておいてください。
これは、Borlandのサイトや雑誌・書籍の付録などにあり、無料です。
インストール方法については、それらを参考にしてください。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
↓参考
http://www.mgs2.com/online.lesson/language.c/02.html コンパイラの環境設定のところから読んで
一番下の設定ファイルの作成
bcc32.cfgとilink32.cfg ファイルを作成する。
ご回答ありがとうございました。
>>100 MSDNにそのまま書いてあるとおりなんだが……
簡単にいえば他のプロセスの該当ファイルへのアクセスをどれくらい許すかを指定する。
>>103 そもそも初期化子を用いた初期化が使えるのは
C的な配列と構造体だけなんだから使いようがないと思うのだが。
いったいどういうことがやりたいんだろう。
>>100 誤解のないように言うと、
標準のファイルストリームにそんな3番目の引数はない。
.NET独自の拡張だろうから本を責めるところではないぞ。
>>109 コンパイラはVC++6.0なんですが、いろいろwindowsUpDataとかしたのでこういう風になっちゃったのかな?
>windowsUpData
二重に誤解している気がする。英語の知識ない奴多いんだろうなぁ。
update
113 :
デフォルトの名無しさん:04/01/11 22:15
ヘッダーファイルの中で、
class aaa{
private:
string aa;
};
(#include <string>を上で実行済み)
や
void aaa( ifstream& a);
(#include <fstream>を上で実行済み)
のようなクラスを使う場所でエラーが出ます
エラー内容
error C2146: 構文エラー : ';' が、識別子 'ErrStr' の前に必要です。
error C2501: 'ErrStr' : 識別名を宣言するのに、型が指定されていません。
error C2065: 'ifstream' : 定義されていない識別子です。
.cppファイル内にプロトタイプや関数を書いた時はエラーが出ませんでした
何がやりたいのかも書いてないようだしいろいろつっこみどころはあるが。
その ErrStr はどこに現れるんだ?
元のソースを半端な判断で省略するな。
とりあえず std::string, std::ifstream な
ながいことプログラムを離れていて、大事なことを忘れていた
using namespace std;
原因見つけるのに、1時間もかかっちまった・・・
もう寝よう
ごめん部長・・・
ヘッダでusingすんじゃねぇ。
そのヘッダをインクルードしたファイル全てで using されるから。
>>119 いったん using すると、取り消す方法がないから。
namespace {} の中とか、関数の中みたいに using の効果がスコープ内に限定
される場所なら using namespace して良し。
122 :
デフォルトの名無しさん:04/01/11 23:47
vc++.netでDirectXのプログラムを作ることにしたのですが、ちょっと質問させてください。
Teapotのメッシュを作って表示するサンプルプログラムみたいなのがありますよね。
あれを改造しようと思い、水平スクロールバーをつけてパラメータを変えて
描画するようにしたのですが、スクロールバーのボタンを押し続けると、押している間中は
再描画されず、ボタンを離して初めて再描画されるんです。
メッセージを取得して処理するたびに再描画させたいんですけどどうしたらいいんでしょうか。
プログラムは以下のようなものです。
void CAppForm::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO : ここにメッセージ ハンドラ コードを追加するか、既定の処理を呼び出します。
// ここでいろいろやる
// ここにRender();と書き加えても再描画されない!
__super::OnHScroll(nSBCode, nPos, pScrollBar);
}
>>108 boost::array<int,5> a = { { 1, 2, 3, 4, 5 } };
boost::array<>は上の様な書き方も可能。
だから、テンプレート引数の2つ目が冗長なので嫌だからどうにかならないかと思ったのだけど。
突っ込むと
配列の初期化子は後続の要素を省略できるから
2つ目の引数は決して冗長ではないな。
>>122 そこはInvalidateRectで再描画要求して
OnDrawで描画したほうがええような・・・
MFCよくしらなけど。
>>123 boost::array の elems って public だったのね。
それなら初期化子は確かに使えるな。
だが完全な型が指定されていない限り変数の宣言はできないんだから。
初期化子側からテンプレートの仮引数に干渉するのは無理だろう。
言語的な仕組みに頼ろうとしても配列を含む無名構造体に対してすら
初期化子からの要素数推論ははたらかないしね。
#補助オブジェクトを用いた間接的な初期化に頼る手もあるが、
要素数が明示されるからこそ最大のパフォーマンスを得られる
このクラスに求めるような物ではないと個人的には思う。
一応3段落目は、
struct {
int hoge[];
} hage = { { 1,2,3,4,5 } };
みたいな記述ね。
>>125 InvalidateRectをやってもやはりスクロールバー押しっぱなし中は再描画されません・・・。
誰か助けてくれ~
>>128 よくわからないけどとりあえずソフト晒してくれ。
3時までなら待つ。
誤爆!
>>122 あなた初心者ではないと思うよ
の間違いでした!スマソ
なんか自分でアップしたのを実行したら強制終了するようになってしまった。
もうどうしたらいいのかわかりません。助けてください。
すいません修正してコンパイル&実行はできるようにしておきました。
STLのスレッドがなかったもんで,こっちに質問させてもらいます..
mapクラスって二分木で構築されてますでしょ?で,
itr = Database.begin();
itrEnd = Database.end();
for( ; itr != itrEnd ; itr++ )
{
pszKey = (char*)itr->first.data();
pszData = (char*)itr->second.data();
//ソートされて書きだされる.
File.Write( pszKey );
File.Write( pszData );
}
ってな感じでファイルに書き出してます.
このファイルから再度mapの2分木を再構築しようと思うと,
ソートされた順に木に追加しているわけだから2分木ではなく,
1方向分岐になってしまいますよね?
良い解決策をありませんか?
Databaseはmapのオブジェクトです.
itrはそのイテレーターでございます.
>>137 mapってB木で実現されているんですか?!勉強になりました.
これで安心してプログラムを組めます.
ありがとうございました.
既知の実装の大半は赤黒木じゃなかったか。
>>122 問題のスクロールバーの部分が消えてるんだが…
>>131に実物があるんでやってみてもらえませんか?
>>140 balanced treeのつもりでB木と書いていたりして(w
>>122 ドラッグしてるときに
WM_CTLCOLORSCROLLBARっていうメッセージ
でてるんでそっちのメッセージで処理を書けばできるかと。
インポートライブラリリンクしてんのか?
147 :
デフォルトの名無しさん:04/01/13 00:58
クレクレですいません
Cのソースからフローチャートを作ってくれるソフトなんてありませんか?
voidは返却値が無いという意味だと習ったんですが、どういう意味ですか?
voidと打った後の文の所で終了ということですか?
皆さんからすると簡単なことかもしれませんがわかりません(><)
教えて下さい。お願いします1m(__)m
>>148 a = foo(0); ってのができないってだけ。
()の中に何も入れない時にVOIDを入れるってことですか?
>>148 別の場所でこれと同じ書き込みを見たような気がするのは俺だけか?
void は、引数、もしくは戻り値がないことを表す。
void bar(void) { ... }
は bar(); と呼び出す。
戻り値がないので a = bar(); とはできないし、
引数がないので bar(0); とはできない。
>>152 ありがとうございます^^void bar(void) { ... } とbar();は同じ事ということですか?あと、戻り値がないとは何処に戻って来る値がないってことですか?
>>151 同じ質問をしたのですが、本に書いてあると言われました。その後本を読んだのですが、よくわかりませんでした(><)
関数の使い方について勉強し直してこい。
たとえば int 型の返り値を持つ関数を一度でも使ったことがあれば
そんな質問は出ようがないはず。
お前は本当に本を一冊でも読んだのかと。
>>153 void bar(void) { ... } を使うときに bar(); と書くわけであって、
この2つが同じというわけではない。
関数というものを難しく考えてるようなので、
ここで1つたとえ話をしてみよう。
関数というのは、誰かに頼みごとをするのに良く似ている。
例えば、宿題を手伝ってもらうとする。
これを関数と対応付けて考えると、次のようになる。
分からない問題を友達に教えて(引数から関数に問題を渡して)、
友達がその問題を考えて(関数が処理を行い)、
友達がその答えを返し(関数が戻り値を返し)、
その答えを受け取る(戻り値を変数に入れたりする)。
では、引数や戻り値がない場合というのはどうだろうか?
これは、例えば、お風呂にお湯を溜めてくれと頼むことに似ている。
つまり、
頼み(関数を呼んで)、
頼んだ相手がお風呂にお湯を溜めて(関数が処理を行い)、
お湯がたまったことを知らせる(関数から処理が返される)。
この場合、特に渡すものもないし、
終わった時も終わったことが知らされるだけであって、
特に受け取るものも無い
(まぁ、お湯のたまったお風呂を受け取ると考えてもいいけど、
ここではお風呂をグローバル変数のようなものと考えておく)。
かなりわかりました!そういった戻り値がない関数にvoidとつけるのですね?
そう。
#include <stdio.h>
void hello(void) {
printf("Hello, world!\n");
}
int main() {
printf("before\n");
hello();
printf("after\n");
return 0;
}
hello は単に "Hello, world!\n" を表示するだけの関数。
これには引数もいらないし、戻り値もいらない。
だから、両方 void にしてある。
>>146 setbccを使って設定はしたんですが…。
159 :
デフォルトの名無しさん:04/01/13 15:35
質問です。乱数を求めたいのですが、上手く行きません。
具体的に言うと、ループ内でrand関数を使って、複数回乱数を求めるのですが、
何度やっても同じ値の乱数が発生します。
例えば、
int tmp;
for(i = 1; i < 10; i++){
tmp = rand();
printf("%d番目の乱数:%d", i, tmp);
}
とやると、何回ループをまわしても、例えば「1回目の乱数=300」のようになり、
同じ結果となってしまいます。
実行するたびに乱数が変わるようにするには、どうしたら良いですか?
教えて君ですいません。。
よろしくお願い致します。
163 :
デフォルトの名無しさん:04/01/15 02:37
質問です.
Googleとかみたいなアンド検索のインターフェイスをつくってるんですが、
スペース区切りによるアンド検索の場合にキーワードを複数に分割する処理で、
もうちょっと効率の良い方法がないかな、と思って質問します。
自分の考えた処理の流れを書けば、
1、検索バーに打ち込まれた文字の全角スペースをStringReplaceで全て半角スペースに変える
2、左端から1文字ずつループをまわしてIsDelimiterをかける。区切り文字は半角スペース。
3、半角スペースにヒットしたら、その位置までの文字列を切り取ってリストに入れる。
4、切り取った後の残りの部分の両端に半角スペースがあればTrimとかで削除。
(↑半角スペースが並んでる可能性を想定してのこと)
5、2に戻る
というものですが、もっと簡単な流れになったりしますでしょうか。
環境はBCB6使ってます。
とりあえず連続するデリミタの削除は検索部分に統合できる。
1.Delimiterでないところを探してそこをトークンの先頭とする。
2.Delimiterであるところを探してその前までをトークンの終端とする。
全角スペースは2文字分あるから
ここは先に半角スペースに置換した方が楽に作れるかな。
うわ、名前欄残ってた
つーか、自分で頭から一文字ずつ見ていったほうが速いと思うが。
>>164 すばやい解答ありがとうございます。
>1.Delimiterでないところを探してそこをトークンの先頭とする。
あぁ、なるほど!確かにtrueとfalseを上手く使い分けて効率的な作業が出来そうですね。
大いに参考にさせていただきます。
>>163 BCBならTStringList->DelimitedTextがまさにそのような用途のために用意されている。
こういうもんは、あるものを使った方が面倒が無くていいと思うが。
なお、トークン切り出しは、きちんと作ろうとすると、引用符とそのエスケープまで作り込まないと
ならないので予想以上に厄介だよ。よって「あるものを使え」と。
169 :
デフォルトの名無しさん :04/01/15 19:49
変数が静的のデータかどうか判定する方法ってない?
171 :
デフォルトの名無しさん:04/01/15 20:32
Cはどのようにして学べばいいのですか?
勉強したいんですけど
みなさんはどのような方法で?
>>169 register 見れば分るかもしんない。
自動変数かどうかなら分かるかも。
#include <iostream>
bool isAuto(void* p) {
static void* pArgv = NULL;
if(pArgv == NULL) {
pArgv = p;
return true;
} else {
return (&p < p && p <= pArgv);
}
}
int main(int argc, char** argv) {
isAuto(&argv);
static int a;
int* p = new int;
if(isAuto(&a)) { std::cout << "a is auto-var." << std::endl; }
if(isAuto(&p)) { std::cout << "p is auto-var." << std::endl; }
if(isAuto( p)) { std::cout << "new int is auto-var." << std::endl; }
delete p;
}
>>169 機種依存の方法で良ければ、一応あるが。とりあえず処理系と目的を言ってみ。
>>169 インスタンスを二つ作って該当する変数のアドレスを比較すればいい
>>168 遅れましたがありがとうございます。
最初絶対そういった関数があるはずだとヘルプで探したんですが、
みつからなくて質問したんですが、やっぱあったんですか…。
ヘルプの文章がわかりづらくて読み飛ばしてたようです。
177 :
デフォルトの名無しさん:04/01/17 06:46
Cでファイルをドラッグ&ドロップして処理するようなプログラムを作りたいと思い、
void main(int argc, char *argv[]){
FILE *file;
char filename[10];
filename = argv[1];
file = fopen(filename,"r");
…
のようなコードを書いたのですが、filename = argv[1];の部分で
「'char *'から'char [10]'に変換することはできません。」
というエラーが出てコンパイルできませんでした。
そこで
filename = argv[1];
の部分を
strcpy(filename, argv[1]);
に変えたところ上手く動いたのですが、なんだかすっきりしません。
filename = argv[1];
はfilename[0]のアドレスをargv[1][0]のアドレスにするだから、
結局filename[]にargv[1][]が代入されるんじゃないんですか?
どなたか説明してもらえないでしょうか?
初心者な質問ですいません。
よろしくお願いします。
179 :
デフォルトの名無しさん:04/01/17 08:27
>>177 配列の先頭アドレスは、変更できない。
> filename = argv[1];
とやりたいなら、char *filename; と宣言しな。
181 :
デフォルトの名無しさん:04/01/17 09:58
C++で、大量のデータを処理したく配列を以下のように、
300000とると正常に動作しなくなりました。
20000以下なら正常に動作します。
同じマシンでExcelマクロを用いて同様に、配列を300000採ってみると
正常に動作します。
メインメモリは、200M以上あるので、ハードでなくソフトの方に
問題があるようですが、ExcelマクロよりC++の機能が弱いのはショックです。
なんとかC++で配列を広く使えるようにしたいのですが
誰かご教示ください。
#include<iostream.h>
void main(void)
{
int data1[300000]; //20000以下とすれば以下の表示可
data1[0] = 45;
cout<<data1[0]<<endl;
}
Excelマクロ例
Sub 配列テスト()
Dim Data(3000000) As Integer
Data(0) = 100
Data(3000000) = 548
MsgBox Data(0) & "と" & Data(3000000)
End Sub
スタック上にそんな馬鹿でかい配列を確保するな。
newを使ってヒープ上に確保するか、もしくはvector等を使え。
#include <iostream>
#include <vector>
int main()
{
using namespace std;
vector<int> data1(300000) //20000以下とすれば以下の表示可
data1[0] = 45;
cout<<data1[0]<<endl;
return 0;
}
183 :
デフォルトの名無しさん:04/01/17 13:40
182さんへ
181です。うまくいきました。ありがとうございました。
defファイル使用でDLL作成するときに
関数のオーバーロードの方法がわかりません。
>>178-
>>180 ありがとうございました。
なんとなくですが、理解できた気がします。
Windowsの HIWORD マクロなんですが、
#define HIWORD(l) ((WORD) (((DWORD) (l) >> 16) & 0xFFFF))
と定義されていて、 '& 0xFFFF' の部分は冗長のように思えるんですが、
これが無いとどんな場合に問題が起こるのでしょうか。
CHAR_BIT が 9 の時とか?
でも、そんな環境では Windows は動かない肝。
>>186 馬鹿じゃねえの?
天下のMS謹製ヘッダファイルが無意味な設計のわけねえだろ。
ちゃんと計算されてる。角度とか。
>>186 WORD=32bit
DWORD=64bit
のプラットフォーム用とか、
ビットシフトが巡回シフトなアーキテクチャ用とか
>>189 そうだとするとHIWORDという名前と機能が矛盾するわけで。
ありがとうございます。
単純に WORD==16ビットと考えてましたが、実際にどんなサイズのデータ型が
割り当てられるかは、環境によって違うからなんですね。スッキリしました。
>>191 以外は全然スッキリしていない悪寒...。
>>190 WORDが16bitなんてのはIAでの話というだけ
16bitなところもあるし32bitなところもある
>>193 例えば?
そして、そこで windows.h を使ったプログラムは動くの?
早合点し過ぎたかな。LOWORDは
#define LOWORD(l) ((WORD) (l))
だからWORDが32ビットだとすると、下位32ビットが取り出されてしまうことに
なるか。HIWORDは本当なら、32ビットシフトしないとならないことになる?
& 0xFFFF は冗長で FA ?
最適化で消えるだろうから無問題
199 :
デフォルトの名無しさん:04/01/18 00:46
以下のプログラムでエラーがでてします
やりたいことはバッファに関数をコピーしてバッファを関数として
扱いたいのですが、CPU的にはデータが置かれるとこはマシン語として
実行できないのでしょうか??
#include <string.h>
#include <iostream>
using namespace std;
typedef int (*FUNC) (int,int);
static char buf[1000] = {0};
int add(int arg0, int arg1)
{
return arg0+arg1;
}
int main()
{
void* src = &add;
void* dest = buf;
memmove(dest, src, sizeof(buf));
FUNC f = (FUNC)dest;
int ans = f(1,2);
cout << ans << endl;
return 0;
}
そんな素直なコードじゃダメだ。もっとコンパイラにばれないようにしる。
>199
コードセグメントとデータセグメントが分離していなくて、
マシン語が完全にリロケータブルな環境なら動作するかもしれないが、
一般には、無理。
規格に厳密にいうと、この時点でアウト。
void* src = &add;
FUNC dummy = &add;
void* src = reinterpret_cast< void*& >( dummy );
これなら大抵のコンパイラで通るかな。
>>203 VirtualProtectを使うのはたんなる礼儀
#もしくは他のプロセッサに対応していたときの名残
実際にはスタックだろうがヒープだろうが
そこにジャンプすれば普通に実行される。
一応FlushInstructionCache()ぐらいは。
レスが遅れてしまってすみません
混同モードで調べてわかったのですが
srcに代入されたアドレス(00419618)はaddが配置されているアドレスではなく
00419613 E9 E8 D5 00 00 jmp std::basic_string<char,std::char_traits<char>,std::allocator<char> >::compare (426C00h)
00419618 E9 83 1B 00 00 jmp add (41B1A0h)
0041961D E9 BE 14 02 00 jmp __init_time (43AAE0h)
00419622 E9 E9 C1 01 00 jmp strcat (435810h)
00419627 E9 C4 DA 00 00 jmp std::_Fac_node::~_Fac_node (4270F0h)
↑のように関数へのjmp群でした
そこで直接srcにaddが配置されると思われるアドレス(0041B190)
を代入するようにしたところ実行に成功しました
しかしこれだとあれなので
void* get_addr(void* p)
{
unsigned int addr = 0;
//もしjmpなら
if((char)0xe9==*(char*)p)
{
addr = *(unsigned int*)((unsigned int)(p)+1);
addr = (unsigned int)(p)+5+addr;
return (void*)addr;
}
return p;
}
void* src = get_addr(add);
として、こちらも成功しました
レスしていただいた皆さんありがとうございました
207 :
デフォルトの名無しさん:04/01/18 05:04
存在するファイルは A.h , A.cpp , B.h , B.cpp , main.cpp の5個
// A.h ヘッダファイル
class A
{
friend ・・・
}
// B.h ヘッダファイル
class B
{
private:
A a;
}
上記のように、あるクラスAとBがあって、BではAをデータメンバとしています。
このような状況でmakeしようとすると、「フレンドは関数かクラスでなければならない」
というエラーがA.hのfriend関数の宣言の部分に出てしまうのですが、これはいったい
どういう意味なのでしょうか。もちろんA.h , A.cpp , main_A.cppという感じでmain関数を
書けば、何も問題なくクラスAをmake&実行出来るのです。
また、クラスBのヘッダファイルB.hにおいて、#include "A.h" と書かないと
「型名がない」というようなエラーも出ます。クラスBのヘッダファイルにはAの
ヘッダファイルをincludeする必要はないと思うのですが。全てがわかりません・・・
どなたかよろしくお願いします
すいません、環境を書くの忘れてました。
CPad for Borland C++ Compiler です。
>クラスBのヘッダファイルにはAの
>ヘッダファイルをincludeする必要はないと思うのですが
なんでそう思うの?
思うというか、使っている本でそうなっていたのと
いくつか実験した経験からです。違うのでしたら申し訳ないです。
ただそのエラーはincludeすればいいだけなのでいいのですが
「フレンドは関数かクラスでなければならない」 というエラーが
どうしていいか全くわからなくて困っています。
BがAをメンバに持ってるならAの定義がいると考えない方が不自然だ。
何も言わずincludeしろ。
friend云々のエラーは肝心なところが省略されてるから何とも言えないが
単体でコンパイルできたのならmainでA.hより前にincludeされてる
ファイルに問題があってその影響が波及してる可能性が高いな。
>>204 > 実際にはスタックだろうがヒープだろうがそこにジャンプすれば普通に実行される。
横道にそれるが、普通のプログラムはそんなことしないのでスタックとかヒープとか (要はデータ領域) は、実行禁止にしておけばバッファーオーバーランを使ったウィルス対策になるんじゃなかろうか ?
(無論そういうことしたいこともあるから、許可するような設定も作る必要はあるが...。)
>>207 ヘッダファイルについては既にレスが憑いてる通りincludeが必要。
フレンド宣言について。
宣言の構文が間違ってるか、フレンド宣言の時点で対象のクラスがまだ宣言されてないか。
207氏はヘッダファイルとincludeの役割を良く理解してないみたいなので後者の可能性が高いかな。
自力で解決できなかったらソース晒すよろし。
>>213 ×憑いている
○ついている
単なる誤変換だ。気を悪くしないでくれ。
>>212 CPUにもよるがセグメントやページ単位で実行不能属性がつけれたりとか、
スタック上でのコード実行を禁止しているOS(OpenBSDだっけか?)はもうある。
「ら」抜き言葉が蔓延してます
218 :
デフォルトの名無しさん:04/01/18 18:14
C++でFF4のようなゲームって作れますか?
C++を使えたとしてもPICじゃ無理だろうな
>>218は初心者とは言わない。さらにレベルの低い次元である。
がんばればつくれるZE
221 :
デフォルトの名無しさん:04/01/18 18:21
がんばれば作れるんですか?
じゃあがんばります。
職場でC#を使っていてDelegateの素晴らしさを体感したんですが
これをC++に移植(?)した例とかってありますか。
ここを見ろとかこの本を買えとか俺様仕様でこうしたとかありましたら
教えて頂きたいのですが。
よろしくお願いします。
似たようなものはもちろん実装可能だけど、C#のdelegateが便利なのは
それを処理系が認識して特別な構文(シンタックスシュガー)が存在している
ってことが一番大きいんじゃないの?
>>224 似たようなものを目指しています。
処理系がサポートしていないのを承知で、実装でカバーするつもりでの
設計を考えています。
>>225 boost::functionはダメ?
ちょっと便乗質問なんだけど、delegateってさ、C/C++で言うところの
「関数ポインタを持ったリスト」でいいんだよね?
>>226 あったんだ(汗
スマートポインタと正規表現しか眼中に無かった・・・。
作る前に気づいて教えて頂きありがとん。
>>227 「型安全な」関数ポインタを持ったリストという認識でいます。
228の日本語おかしいけど気にしません(ヲィ
>>226 引数が少ない場合のやつは、使わない引数の部分を void で specialization するという風にすれば、
function1 とか function2 とか不恰好な数値をつけなくていいと思うんだけど、どうなの?
実際そういうの作って使ってみたけど問題なかったけど。
231 :
ヒープ情報:04/01/19 12:04
VC6 + WinXP です。
自作アプリのリリースバージョンに、自プロセスの使用ヒープサイズとヒープ内のフラグメントサイズをレポートする
モニタ関数を組み込みたいのですが、それらの情報を得るための CRT関数 や API関数 を教えてください。
_CrtMem系はデバッグバージョンでのみ使用可能なので目的に合わないのです。
コンパイルしたらエラーでUnknown dimensionってでたんですけど、
これってどういうエラーなんですか?
だれか教えてください
メッセージの通り。
int f(char a[][]) { ... } とか
スンマセン、よくわかんないです。
メッセージ通りってことはunknown=わかんない、dimension=次元ですか
ら、何次元の変数かよくわかんねえぞゴラァ、ってことなんでしょうか?
本気で知りたいならソースのエラーの出てる行くらい貼ればいいのに
236 :
デフォルトの名無しさん:04/01/19 23:29
http://www.yamagame.com/MyWeb/Heart/heart11.html ここのGAMESYS2をvisualc++5.0でコンパイルしようとしたんですが、下記のようなエラーが出てうまくいきません。
どなたか原因を教えていただけると助かります。
コンパイル中...
GAMESYS.CPP
E:\DX90SDK\INCLUDE\dsound.h(305) : error C2501: 'DWORD_PTR' : 識別名を宣言するのに、型が指定されていません。
E:\DX90SDK\INCLUDE\dsound.h(305) : error C2146: 構文エラー : ';' が、識別子 'dwReserved1' の前に必要です。
E:\DX90SDK\INCLUDE\dsound.h(305) : error C2501: 'dwReserved1' : 識別名を宣言するのに、型が指定されていません。
E:\DX90SDK\INCLUDE\dsound.h(306) : error C2501: 'DWORD_PTR' : 識別名を宣言するのに、型が指定されていません。
E:\DX90SDK\INCLUDE\dsound.h(306) : error C2146: 構文エラー : ';' が、識別子 'dwReserved2' の前に必要です。
E:\DX90SDK\INCLUDE\dsound.h(306) : error C2501: 'dwReserved2' : 識別名を宣言するのに、型が指定されていません。
cl.exe の実行エラー
GAMESYS.exe - エラー 6、警告 0
使用しているDirectX SDKは9.0 SDK Update(Summer 2003)、ランタイムはDirectX9.0b、OSはWin2000です。
>>236 GAMESYS.CPPの#include <dsound.h>より前に#include <basetsd.h>がいる。(試してないけど)
>>1にあるように、正にエスケープシーケンスで詰まりました。
main( )
{
printf("\x1b[2J");
printf("\x1b[4;8H");
printf("test1\n");
printf("\x1b[6;8H");
printf("test2\n");
}
結果はDOS窓に
*[2J*[4;8Htest1
*[6;8Htest2 (*にはエンターの矢印が入ります)
と表示されるだけです。エスケープ文字が上手く機能していないような・・
OSはwindows XP
コンパイラはborland c++compiler5.5.1 です。
環境によって上手くいかない場合があるのでしょうか?
基本的にXPでエスケープシーケンスが動くとは思わないほうがいい。
Console操作用のWindows API使え。
>>239 深夜レスサンクスです。
レスを元に少し調べてみたら、XPや2000では駄目のようですね。
解決策として、コンパイラを変えるとかしかなさそうですが、
エスケープ系は諦めて、フリーで制限無しのボーランドで勉強を続けます。
ありがとうございました。
プログラミングの勉強を始めようとして本を買ったのですが、そこのついていた付属の
CD-ROMでBCCというやつで始めようかなと思ったんですけど、Visual C.NETというやつが
売ってますよね?あれとはどう違うのでしょうか?初歩的なことかもしれませんが教えてください。
>>241 BCCはコンパイラ
Visual C++.NETは開発環境
コンパイラはプログラミング言語で書かれたソースコードを、
コンピュータが実行できるマシン語に翻訳するソフト。
開発環境はプログラミングをするための便利なツールと
ライブラリというプログラムの部品とコンパイラ他をセットにした商品。
ものすごく適当に言うと、コンパイラは針と糸で
開発環境はマイコン制御自動パターン縫い機能付ミシン。
取り敢えず君がその入門書を仕上げる段階ではBCCだけで間に合う。
どの開発環境を使ったらいいか相談したかったら、その入門書を
仕上げてから質問すればいい。
borlandのコンパイラだけをインストールしていたのですが、
今日、Visual C++をインストールしてみました。
・・・わけわからん。
>>242さんが言うように、今まで針と糸でやっていたのに突然高性能ミシン
に変えると多機能すぎて付いていけませんw
挙句には、手探りで簡単なソースをコンパイルしてみるものの、
いつまで経ってもコンパイルが終了しません。(半分フリーズ状態。)
borland入れたときに色々いじったから、Visualに移行する際は
設定をデフォルトに戻さないとダメなんでしょうか?(パスの設定とか)
>>243 取り敢えずパスからBCC関連のディレクトリ外してみ。
>>242 わかりやすいです。
ではまずBCCでかった入門書をやり終えてからまた考えます。
ありがとうございました。
246 :
デフォルトの名無しさん:04/01/22 03:19
VCのDLL初心者です.
VBからDLL呼び出してそこでピクチャボックスみたいの作って
お絵描きとか色々(ウィンドウプロシージャとか)したいんだけど、
駄目なんです.
Cは下に書きます.
VBから
Ret=dllTest(frmMainForm.hWnd)
で呼び出すとウィンドウは作るんだけど、
Ret=dllTest(0)
で矩形を描こうとしても駄目なの.
DLLは漏れにはまだ早いのかなぁ.
247 :
デフォルトの名無しさん:04/01/22 03:20
#include <windows.h>
LRESULT CALLBACK dllWndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE hInst;
HWND hWnd;
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD dwReason, LPVOID lpReserved){
if(dwReason==DLL_PROCESS_ATTACH) hInst = hInstDLL;
return TRUE;
}
LRESULT CALLBACK dllWndProc(HWND hWnd, UINT winmsg, WPARAM wparam, LPARAM lparam){
return(DefWindowProc(hWnd, winmsg, wparam, lparam));
}
248 :
デフォルトの名無しさん:04/01/22 03:21
__declspec(dllexport) int __stdcall dllTest(int Opt){
WNDCLASS wc;
PAINTSTRUCT ps;
HDC hdc;
if(Opt!=0){
wc.style=0, wc.lpfnWndProc=dllWndProc, wc.cbClsExtra=0,
wc.cbWndExtra=0, wc.hInstance=hInst, wc.hIcon=NULL, wc.hCursor=NULL,
wc.hbrBackground=(HBRUSH)GetStockObject(LTGRAY_BRUSH),
wc.lpszMenuName=NULL, wc.lpszClassName="Class;dllWndProc";
RegisterClass(&wc);
hWnd=CreateWindow("Class;dllWndProc", NULL, WS_BORDER|WS_CHILD|WS_VISIBLE ,
10, 10, 50, 30, (HWND)Opt, NULL, hInst, NULL);
}
else{
hdc=BeginPaint(hWnd, &ps);
SelectObject(hdc, (HBRUSH)GetStockObject(BLACK_BRUSH));
Rectangle(hdc, 15, 5, 35, 25);
EndPaint(hWnd, &ps);
return 0;
} }
長くてすんまそん.
>>246 BeginPaint(), EndPaint()の使い方が違う。
ヘルプよく読め。
できたー!
ありが㌧!!
こんな簡単なコトだったんだ.
コレですね.
>BeginPaint メンバ関数を呼び出すのは、WM_PAINT メッセージに応答するときだけです。
要は作画命令は基本的にWM_PAINTに置いてあとはSendMessageしろ、
っていうポリシー(?)だと解釈していいのかな.
追加で質問お願いします.
248の、BeginPaint~EndPaintの代わりに、GetWindowDSを使うのはどうですか?
一応、今んとここれでいけるんやけど….
不具合が起こる可能性がある?それとも普通なコト?
(最終的にはWM_PAINTでやろうとは思ってるけど)
hdc=GetWindowDC(hWnd);
SelectObject(hdc, (HBRUSH)GetStockObject(BLACK_BRUSH));
Rectangle(hdc, 15, 5, 35, 25);
ReleaseDC(hWnd, hdc);
GetWindowDCだと非クライアント領域(枠とかタイトルとか)まで含まれるから
やるならGetDC。
もっとも、WM_PAINTはどのみち処理する必要があるから描画コードが複数個所
に散らばって面倒だけどな。再描画の処理も面倒になるし。
まぁ、最終的には裏画面に描画してそれをBitBlt、みたいなとこに落ち着くわけだが。
ちなみにWM_PAINTを要求するときはSendMessageじゃなくてInvalidateRectとか使う。
なるほど、何となく理解した.
InvalidateRectも了解でつ.
裏画面をBitBltも考えてるです.今回の目的は、
VBでマウスに追随して作画処理をさせようとしてんだけど、
計算が遅かったんで、そこだけdllに任そうかな、てのだったんで.
ともかくありがとー!
これで(俺の中の)可能性がまた拡がったぜ!
254 :
デフォルトの名無しさん:04/01/22 17:58
クラスのstaticメンバ関数なんですが、この関数から
同じクラスのstaticメンバ変数にアクセスすることは
できないのでしょうか? コンパイラは通るのですが
リンカでエラーがでます。
#include <iostream>
class CSample {
public:
static int iItemStatic;
static void Func(int n);
};
void CSample::Func(int n)
{
iItemStatic = n*n;
}
void main()
{
CSample::Func(100);
std::cout << CSample::iItemStatic << '\n';
}
main.obj : error LNK2001: 外部シンボル ""public: static int CSample::iItemStatic" (?iItemStatic@CSample@@2HA)" は未解決です
Debug/test.exe : fatal error LNK1120: 外部参照 1 が未解決です。
link.exe の実行エラー
static関数がどうとかは関係ないぞ。
staticメンバ変数の定義がないのが問題なだけだ。
>>255 成功しますた!
ありがとうございますた!
258 :
デフォルトの名無しさん:04/01/23 00:27
2つのヘッダーファイルA.hとB.hで、
それぞれクラスCAとCBを定義していて、
CAのメンバ変数にCBのオブジェクト、
CBのメンバ変数にCAのオブジェクトが含まれる場合、
どうやってコンパイルしたらいいんでしょうか?
ヘッダファイル A.h
class CA{
CB member;
};
ヘッダファイル B.h
class CB{
CA member;
};
みたいな感じです。開発環境はVisual C++.netです。
259 :
デフォルトの名無しさん:04/01/23 00:30
>>258 無理です。無限の大きさを持つクラスは定義できません。
そのmemberはポインタで持ちましょう。
260 :
デフォルトの名無しさん:04/01/23 01:00
>>259 ポインタにしてみたんですが、
「A.hの識別名CBが未定義」みたいなエラーが出るんです。
(B.hのほうでもCAが定義されていないと出ます)
class CB;
class CA { ... };
class CA;
class CB { ... };
>>260 ヘッダファイル A.h
class CB;
class CA{
CB* member;
};
そしてA.cppにB.hをインクルード。
B.h B.cppでも同じことをする。
263 :
デフォルトの名無しさん:04/01/23 01:13
コンパイルできました。ありがとうございます。
関数のプロトタイプみたいな感じでやればよかったんですね。
264 :
デフォルトの名無しさん:04/01/23 02:40
1から8までの処理があるとします。
条件Aでは1、2、5の処理を実行、条件Bの時は4、5、7、8を実行するような場合、
どういうコードを書けばよいか見当がつきません。
if(1を実行)
else(2を実行)
else(3を実行)
.
.
.
というようにするぐらいしか自分には思い付かないんですが、
何か良い方法は無いでしょうか?
265 :
デフォルトの名無しさん:04/01/23 02:57
>>264 1~8を関数化。C++の場合できるだけinlineに。
A == ( B || C )
A == B || A==C
C++で上の2つは同じでしょうか?
>>266 違う
>>264 さらに関数はできれば型を同じにしてインデックス値とともに関数テーブルに格納。
こんな感じ?
typedef int (*FUNC)(void);
typedef struct TABLE{
int nIndex;
FUNC fn;
}*LPTABLE;
const static TABLE table[]={
{1,fn1},
{2,fn2},
{3,fn3},
{4,fn4},
{5,fn5},
{6,fn6},
{7,fn7},
{8,fn8},
{-1,NULL}
};
void execute(int* aExeIndex)
{
for(int i=0;aExeInded[i]!=-1;++i) table[aExeIndex[i]].fn();
}
void You(void)
{
int a[]={1,2,5,-1},b={4,5,7,8,-1};
if(条件A) execute(a);
if(条件B) execute(b);
}
まぁ、これじゃインデックス値は別に使う必要は無いけどね。
268 :
デフォルトの名無しさん:04/01/23 03:49
>>266 ABCがboolなら同じだろうが、それ以外の型では違う事も
多かろう。
multimapで、あるキーとペアになっているデータを全て表示する関数ってあるの?
素直にcount()してその数だけループさせて表示するしかないのかな
>>271 レスサンクス。
でも、使いかたがわからん。。
>>264 >条件Aでは1、2、5の処理を実行、条件Bの時は4、5、7、8を実行するような場合、
>どういうコードを書けばよいか見当がつきません。
if( 条件A ) /* 条件Aか? */
{
処理1;
処理2;
処理5;
}
else if( 条件B ) /* 条件Bか? */
{
処理4;
処理5;
処理7;
処理8;
}
だろ?
>>273 >条件Aでは1、2、5の処理を実行、条件Bの時は4、5、7、8を実行するような場合、
>どういうコードを書けばよいか見当がつきません。
int a = 条件A;
int b = 条件B;
if(a) { 処理1; 処理2; }
処理3;
if(b) { 処理4; }
if(a || b) { 処理5; }
処理6;
if(b) { 処理7; 処理8; }
こういうことじゃないの?
フラグがもっとたくさんある場合なんかは
if-else並べるより一つにまとめて ( a << 1 | b ) switchする方法も。
まあいずれにせよ、
>>273は条件の排他性について明確でない上に
処理番号にまだ裏がありそうでよくわからんね。
返答待ちかな?
276 :
デフォルトの名無しさん:04/01/23 17:29
MIMEのアタッチメント方式で,
本文のテキスト文に,おそらくBase64エンコードのバイナリファイルがくっ付いた
ファイルから,メインのテキスト文だけを抽出するにはどうしたらよいでしょうか?
環境はgccで,言語はC++です.
全部をメモリに読み出すことは不可能なため,ファイルの中を検索して,
バウンダリ文字列を探すしかないと思うのですが,
ファイル操作や文字列操作に不慣れなもので・・・
何か,参考になるようなサイトやソースをご存知でないでしょうか?
>>272 typedef std::multimap<std::string, std::string> MMap;
MMap mmap;
...
typedef MMap::iterator Itr;
std::pair<Itr, Itr> p = mmap.equal_range("key");
for (Itr i = p.first; i != p.second; ++i) {
...
}
std::bad_alloc() を常に考慮したコードを書くべきでしょうか?
例外が発生しても各種リソースがリークしないようには心がけるべきだが、
bad_allocが発生したときには素直にプロセス落とすのも一つの見識。
ま、その辺はそのプログラムにナニが求められてるかにもよるが。
280 :
デフォルトの名無しさん:04/01/24 12:43
関数のデフォルト値は、ヘッダに書くもんですか?定義に書くもんですか?
どっちにも?両者で値が違うとエラーかな?
この辺、初心者向け解説書には書いてなかったりして判断に困ります。
278じゃないけど、自分の場合、std:bad_alloc()を拾ったら
そのクラスで定義したエラー型(enum)でthrowしなおすようにしてます。
どのクラスのどこで投げた例外か一発でわかるように。
でも、C++のプログラムとしては甘っちょろいことをやってるのかなぁと
最近思います。
>>280 > 両者で値が違うとエラーかな?
何で自分でやってみようとしないのか...。
--- test.cpp ---
void foo1(const int i = 2);
void foo1(const int i = 3){}
void foo2(const int i);
void foo2(const int i = 3){}
void foo3(const int i = 2);
void foo3(const int i){}
$ cc -Wall test.cpp
test.cpp: In function `void foo1(int = 3)':
test.cpp:2: default argument given for parameter 1 of `void foo1(int = 3)'
test.cpp:1: after previous specification in `void foo1(int = 2)'
$
どうすればいいかは、自分で考えてくれ。
>>280 答えは
>>282を見れば判るとして、
まともな入門書ならデフォ値のことは書いてある。
読み落としたか、よほどデタラメな本かどっちか。
というかそのものずばり書いてなくても
呼び出し側で必要な情報かそうでないかを考えれば明らかだろうに
285 :
デフォルトの名無しさん:04/01/24 16:30
MFC5.0つかって mdbファイルに接続するツールを
作成しています。
DAOで繋いでいるのですが
ほしいデータの抽出SQLをなげる時に
条件をあやまって 大量のデータでレコードセットを実行した時
ボタンによる中止処理を実装したいのですが
どうすれば 可能ですか?
286 :
デフォルトの名無しさん:04/01/24 19:38
関数を使用しないでvc++やC言語でファイルをロックしたいのですが、
どうやればいいんでしょうか?
関数等を使用して排他的で開いて共有できないようにする、や
ソフトを起動中だけ、ということではないんですが。
わかるのは
・C/C++は苦手らしい
・日本語はもっと苦手らしい
ということだけだな
事故レスです.
MIMEで添付処理されると,
バウンダリで必ず改行されるそうなので,
普通にgetlineで読んでいけば良いようです.
お手数をおかけしました.
よけいわからん
火星語なのか?
直接誰にあてたレスという訳ではないけど。
質問するときは、覚えたての、まだ意味がよく判ってない用語を使わんで、
普通の言葉で普通に質問すればいい。
ただし出来るだけ状況を具体的にかつ正確に書く必要があるのは言うまでもない。
ここは初心者スレなんで、どんな初歩的な質問も基本的にヲケだが、
質問内容が理解できないのはどうにもならん。
プログラミング初心者は歓迎するが、日本語初心者や一般常識初心者は
相手にされんというこっちゃ。
そうそう、ついでに言うと、
「○○しようと思ってプログラミングしたんですが上手くいきません何ででしょう?」
ってときは、必ず自分の書いたソースを提示するべし。
初心者の「上手く動きません」ってのは十中八九ソースがおかしい。
そこを突っ込まれるのが嫌なら、人様に質問なんかせず自力で解決すべし。
292 :
デフォルトの名無しさん:04/01/24 22:42
質問です。liboctave c++のMatrixという行列のクラスを使いたいんですが。
500×500くらいの行列を宣言すると落ちます→static Matrix m(500,500);
クラスの使い方は
Matrix m(3, 2); //3,2の行列の宣言
00010 m(0,0) = 3; m(0,1) = 2;
00011 m(1,0) = 2; m(1,1) = 0;
00012 m(2,0) = 4; m(2,1) = 2;
みたいな感じに行列要素を入れるみたいです。
メモリ確保の為にポインタ使って下のようにしようと思ったんですが
Matrix *m;
m = new Matrix(500,500);
要素を操作するにはどうしたら良いでしょう?
やっぱクラスの中みないと無理でしょうか?ちょっとC++初心者で
クラスとかあまり分かってないのですが、よろしくお願いします。
293 :
デフォルトの名無しさん:04/01/24 22:45
連結アイコンの作り方を教えてください、若しくは連結アイコンを作るのに役立つツールの名称を教えてください。
>>291 > ここは初心者スレなんで、どんな初歩的な質問も基本的にヲケだが、
勝手に、C/C++ の縛りを解くなよ。
>>293 みたいな質問には、お前が答えてくれるのか ?
>>295 だれも「C/C++に関係しない質問でも構わない」とは書いてないが?
"C/C++室"での質問はC/C++に関したものであるのは自明のことでは?
スレ違いの質問が舞い込んだら無視したらいいだけのことでは?
>>292 500×500=250000じゃスタックに積むのは無理だろ。
newで確保で正解。
使い方はライブラリのドキュメントを読むしかなかんべ。
>>297 "C/C++室"で「どんな初歩的な質問でも」と言えば、それはC/C++に関連しない質問も
含むということになれば、プログラミングに関連しなくてもヲケ、コンピュータに関連しなくても
ヲケって事になるな。
そうならないのは「"C/C++室"での質問はC/C++に関したものである」という前提が
自明のこととしてある訳で。
その辺の事情が納得できないなら「一般常識の初心者」としか言いようがない。
>>299 どんな ≡ 〔いかなる…も〕
日本語の初心者の方ですか ?
>>298 Matrix m(500, 500);
という使い方を見るに、
行列は動的に確保してるんだと思うんだが。
スタックや静的領域に確保するには
Matrix<500, 500> m;
という仕様じゃないと無理ぽ。
これで落ちるとすれば、
>>292 のプログラムで(m に関係するかしないかに関わらず)変なことしてるか、
いつのマシンだよ! ってなくらい極めて貧弱な環境で実行してるか、
ライブラリ自体が変か、のどれかだろうな。
Matrix<500, 500> m;
みたいな宣言のしかたが無いか探してみます。
それで、だめなら他のライブラリ探すか
ドキュメント精読するしかないか・・・
マシン環境もAthlon2Gくらい積んでるLinuxなんで、まあ問題ないかと。
>>301 あぁ、そうだ。短絡的に判断してもた。フォロースマン。>Matrix
>>302 いや、それを探すのは止めとけ(w
304 :
デフォルトの名無しさん:04/01/25 01:35
>>301 >ライブラリ自体が変か
が現実味を帯びてまいりました・・・
今、家に同じ環境(のつもり)を構築してみたら
Matrix(500,500);
だけで正常に動作、苦戦してるあいだにC++の勉強にはなりましたが
明日、もっかい確認してみます。
Treeの実装に不備はないの?
>>306 > Treeの実装に不備はないの?
いや、Treeの実装と言われましても、単に上記サイトの説明の通りに
そのままはっつけただけなんですが…。
よくわからないんですがBCBのTTreeViewの仕様自体に問題があるってことですか?
>>304 Treeという型はVCLにはない。
で、そのMLのログを遡って見てゆくと、Treeは元発言の投稿者が独自に定義した構造体であると判る。
まねするならそこからまねをする必要がある。
なお、テンプレートが特化できないのが問題なんで、「stTreeが未定義」ってのは気にしなくていい。
>>305 はじめはみんなそう思うんだけどね、
そう思ってるうちの 99 % くらいは間違いで、
自分のプログラムの方が間違ってることが殆どだ。
まぁ、たまにライブラリの方にミスがあることもあるけど...。
会社か大学かは分からんけど、
そっちでやっても Matrix m(500, 500); だけだと
エラーは出ないと思うぜ。
というか、どの時点で落ちるのかとか確かめてる?
>>310 OH!うっかりしてました。
ありがとうございます。
ま、今回は解決したからいいけど、
こういうケースが「○○はライブラリにバグがあるらしい」
とかいう根拠の無い噂の源になるんだよな。
>>311確かめてますよ・・・
Matrix m(500, 500);
宣言するだけで落ちてたし
gdbでデバッグしても、そこでセグメンテーションフォルトって
でてましたからね。これがMatrix(3,2);とかだと
ちゃんと動いたり・・・わけわからんです。
みなさまお手数かけました。学校で動いた動かないにかかわらず
明日、報告だけは致しますm(__)m
>>314 エラー出るのか...。
それは流石にライブラリの方の問題っぽいなぁ。
templateとか絡んでるとコンパイラのバグの可能性もあるけどな。
gccのバージョンが3未満だったりとかVC++6.0とか。
今、ゲーム(簡単なもの)作っててつまずいたので
お力添えいただきたいのですが。
まず、親ウィンドウがあって、一時的に子ウィンドウを
親にぴったり貼り付けて、別処理をさせています。
親から子に操作が移る時は、なんとも無いのですが、
子を終了させて親に戻った時、つまり子ウィンドウ破棄の時に
一瞬画面がちらつきます。
これをユーザー側に気がつかれないようにしたいのですが
どうすれば良いのでしょうか。
DestroyWindow()の前にShowWindow()での画面切り替えも
試してみたのですが、どうしてもちらつきます。
どうかよろしくお願いします。
>>317 直接の回答ではないが。
1)子ウィンドウを使わず、自前でウィンドウのようなものを作る。
2)子ウィンドウを初めから表示しない(表示を親ウィンドウに任せる)
3)ゲーム関係のWebをあさる。
ライブラリのリビルドで学校でも動くようになりました・・・
お騒がせしました。
ずこー
>>317 ちらつく症状にもよるが一瞬子ウィンドウがあった場所が白くなる、とかいうのなら
WM_ERASEBKGNDでなにもせずにTRUEを返すだけでよかったりするが。
ダブルバッファリングとWM_PAINTのPAINTSTRUCT::rcPaintを参照して再描画部分を
最小限にするのは基本。
322 :
デフォルトの名無しさん:04/01/26 16:47
array=(*ppsa)->pvData;
のかわりに、
array=(*ppsa).pvData;
てやるとコンパイラに怒られます。
「->」の書き換えってないの?
(*p).hoge
=
p->hoge
うぉ、
>>323をよく見たら解決した.
ありがとー.
「最後の一行だけ見て脊髄反射レスしやがったな」と思っちまってゴメンよ.
array=(**ppsa).pvData;
325 :
デフォルトの名無しさん:04/01/27 01:39
326 :
デフォルトの名無しさん:04/01/27 01:55
>>325 数値で書くと、
ss[]={0x41,0x42,0x43}
と代入されてて、ss[2]=0x43だから、
2引くと0x41='A'となる。
文字も数値である
ってのがまだピンと来ていない人と見た。
>>325 サンプルが配列を使ってるので、ポイントがつかみ難くなってるな。
配列を取っ払って、
char ss = 'C';
printf("%d", ss - 'A');
としても、2と表示される。
これは、>>326-
>>327でも書かれているけど、
文字(文字列にあらず。シングルクォートで囲まれた一文字)は
コンパイラにはそのキャラクタのコードで示される「数字」として
解釈されるため。
通常ASCIIでは'C'=67,'A'=65だから上のコードはコンパイルされると
char ss = 67;
printf("%d", ss - 65);
として解釈される。
注意しないといけないのは、これは環境依存のコードで、いつでも
成り立つわけではない。もし'A'=1で'C'=100として定義されるコード体系
の環境だと、2ではなく98が結果として返される。
#これを基点にソースコード中の「文字列」はどう解釈されるか
#も調べればいい勉強になると思います。
まぁ、'A' と 'C' の差が 2 でない環境が本当にあるのかというと、
ないんだろうけどね。
>>326-329 わざわざ親切にありがとうございます。
とてもわかりやすい説明で、納得できました!
ありがとうございましたm(__)m
331 :
デフォルトの名無しさん:04/01/27 20:33
質問です。どなたか助けてください。
VC++ Ver5.0でプログラムの勉強をしているのですが、これに添付されていた
サンプルSUPERPADを元に、自分のプログラムでもフォントを変更するルーチンを
組み込もうとしています。手順はCView派生クラス配下にこんな感じのメンバ関数
を作ってます。
LOGFONT lf;
CFontDialog dlg(&lf, CF_SCREENFONTS|CF_INITTOLOGFONTSTRUCT);
CFont font;
font.CreateFontIndirect( &lf );
SetFont( &font );
んが、サンプルのSUPERPADではフォントが変わるのに、私のプログラムでは
変わってくれません。直後に
CFont* pfont;
pfont=GetFont();
などとやってpfontの内容を調べてみると、SUPERPADではきちんとしたポインタが
帰ってきますが、私の場合NULLしか帰ってこないのです。
何か初期化処理が足りないのかと思いいろいろ調べていますが、どうしても
分かりません。おそらく、hWndに結びつけられているHFONTを一旦解放するような
処理が必要になるのではと当たりはつけたのですが、デバッガでもSendMessageで
WM_SETFONTを送り出し、戻ってくるまでのルーチンには潜れず、大変困っています。
解りにくい説明で申し訳ありませんが、どなたかご教授願えませんか?
>>331 俺と同じ経験だ。
CViewだとSetFont使えないのかねぇ?
WM_SETFONTをラップしてるだけみたいだから
できそうなもんなんだけど・・・。
仕方ないから代わりに毎回LOGFONTからフォント
を作成してるよ。↓こんな感じ。
void CFontTestView::OnDraw(CDC* pDC)
{
CFontTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: この場所にネイティブ データ用の描画コードを追加します。
CRect rcClient;
GetClientRect(&rcClient);
// CFontDlg の m_LogFont から CFont を作成
CMainFrame* pFrame = dynamic_cast<CMainFrame*>(GetParentFrame());
CFontDlg* pFontDlg = &(pFrame->m_FontDlg);
CFont Font;
Font.CreateFontIndirect(&(pFontDlg->m_LogFont));
CFont* pOldFont;
pOldFont = pDC->SelectObject(&Font);
pDC->DrawText(pszText, -1, &rcClient,
DT_LEFT | DT_TOP);
pDC->SelectObject(pOldFont);
}
334 :
デフォルトの名無しさん:04/01/27 21:41
>332
わざわざサンプル提供ありがとうこざいます。参考にさせていただきます。
しかし、どうしてCView派生はダメなのでしょうね…… CEditView派生なら
問題なくできるのに……
Cコンパイラはなかったけど、某パソコンはアルファベットがリニアに並んでなかった記憶がある。
こうして見ると、EBCDICとも違ってるなぁ。
と言うことで、案外'c'-'a'が2じゃない環境はあるもんですな。
>>334 GetFont() に成功したら報告ヨロシク。
関数にstring型の配列を引数として渡すにはどうすればいいでしょうか?
string str[100];
hoge(str)
でいいんでしょうか?
まずはstring型の配列を引数として受け取る関数を探すんだ。
うーん、これでいいんでしょうか?
string str[100];
hoge(string *str)
>>342 そういう関数を、「作りたい」のか、
そういう関数に、「渡したい」のか、
はっきりさせるんだ。
string str[100]のような配列を受け取ってくれる関数を作りたいです。
int型の配列を渡す時はどうやってたかな…
ほれ。
void hoge( string str[] );
サイズが要るなら。
void hoge( string str[] , size_t n );
書き換え不可ならこんなかんじ。
void hoge( string const str[] , size_t n );
C++としては、こっちのほうが素敵。
void hoge( vector< string > const& str );
void hoge( vector< string >& str );
void hoge( vector< string > str );
template<typename ITER> void hoge(ITER begin, ITER end);
template<typename ITER> void hoge_n(ITER it, size_t n);
の方が素敵。
347 :
デフォルトの名無しさん:04/01/28 01:37
UNIX/Cのお勧めのリファレンス本ありませんか?
比較的高度なライブラリ関数も載ってたり、UNIXのプロセスやファイル構造まで詳しく書かれているものが欲しいです。
さらに、きれいにまとめられていて・・・
ない、次。
>>335 先に例を挙げられてしまった...。
「C言語を256倍」本にはstrcmpの実装に絡んで
「EBCDICの様な汎用機では激しくメジャーなコードで
この有様なので、キャラクタコード依存のコードはやっちゃいかん」
と書かれてるね。
>>350 俺も好きな本だけど、
1文字1文字調べろって書いてあってワラタ。
>>352 多分 #if で分岐させた方がいいよね...。
文字列の大小関係を調べるだけのstrcmpでキャラクタ依存ってなんだろう。
どんな文字コードでも同じ大小関係が成り立つようにしろってことか?
でもそうすると何を基準にすべきなのかという問題が出てくるよね。
特定のコードにマッピングしたらいいんだよ。
マップ後のコードは既存のコードである必要はないし、1バイトである必要もない。
とにかく、全ての環境で同じ結果が出ることが保証できれば良い。
つーか、そもそもstrcmpによる比較って漢字とか絡むとほぼ確実に期待通りには
ならんわけで、一定の結果が帰ってくる以上のことを期待するほうが間違ってると
思うんだが。
>>356 さすがにマルチバイト文字の話はちょっと筋違いという気がするが。
俺はとても筋が通っていると思う。
俺漏れも。
ちょっと聞きたいんだけど、マルチバイト文字を示す
数値がいくつかありますよね。
あれって文字列を最初からサーチした場合、
文字の始めに来るんですっけ? それとも
文字の後ろに来るんですっけ?
たしかインテルの場合は、CPUのバイトオーダーに
合わせて、文字列も小さい方から並べていたような
記憶があるんですが、それで正しかった?
>>360 文字コードに依存するので何とも言えない。
マルチバイト文字は普通ビッグエンディアン。
1バイト目で2バイト文字かどうか確かめるから。
つーか、MBCSならエンディアンに関係ないが。
あ、じゃあ、気にしなくていいのか。
前後を逆にしなくちゃいけないのは、
9801のVRAMに直接書き込むときの話だったかも知れない。
さんくすこ。
JIS コード 8140 は 81 → 40 の順に現れるだろ?
そういう意味。
Shift が抜けた...。
Shift-JIS ね。
もちろん、3040 とかなら JIS でもいいんだが。
マルチバイト文字で日本語は二バイトの整数で表されるというよりも、
一バイトの整数二つで表されるといった解釈が正しい
UCSなら一つの整数だがな。
それはそれで面倒なんだ。
>>367 でも、コードの割り当て順を見ると
2バイトとして考えるのも妥当な肝。
よそで聞いたら初心者スレへ誘導されました。質問です。
DirectXGraphicsなプログラムを作っていて、必要が出てきて「猫でもわかる~」を見ながら、
リストビューをつけました。
リストはウィンドウにうまく張り付いて表示されるように出来たのだけど、このリストを
クリックしてしまうと以降、親ウィンドウのキー入力やらマウス入力のメッセージが
来なくなってしまうんです。一度ほかのプログラムを最前面にしたりすると直るんだけど。
リストビューにキー入力を持って行かれない方法というか、 親ウィンドウに速やかに
キー入力を返却する方法自体が判らなくて調べもつかずに 弱っています・・・。
>>372 そこから初心者スレ逝くよういわれて来ました。とほほ・・・。
Win32APIスレでSetFocusを教えてもらい、何とかなるかもです。
MSDNライブラリから、したい事を探すのがうまくなりたい・・・。
375 :
デフォルトの名無しさん:04/01/31 09:31
空白で区切られたデータを読む時、C++ではどうするのが定石?
AAA 111 BBB 222 CCC
見たいな行をstringに読む。
Cならsscanfとかだろうけど。
getlineしてstring.find_not_first_of とか string.substr の方がコーディング
として望ましい?
getlineは第3引数でデリミタを指定できる
377 :
デフォルトの名無しさん:04/01/31 10:13
000095bf: 0f 90
000095c0: 85 e9
ウィンドウズで↑みたいなやつをいじりたいんですが、何を使えばできるんでしょうか?
よろしくお願いします。
板違い
ついでにexeやdllファイルの改変は大抵の場合、ライセンス違反
へ~
↑それはうそ
罰則なしだから事実上そのとおりだけど
リバースエンジニアリング禁止は裁判やると絶対無効って判決でるがな。
ただし、再配布すると一発アウト。
リバースエンジニアリングは別にして、
「改変」は著作物の同一性保持権を侵害するからアウト。
ただしプログラムの場合、移植やバグフィックスなどは
例外として改変が認められているけど。
388 :
デフォルトの名無しさん:04/01/31 19:14
日本語化パッチってどうなんだろう。
389 :
デフォルトの名無しさん:04/01/31 22:11
static int func(..) {
}
とか、
const char *func(..) {
}
みたいに関数の頭にconstやstaticをつけるのはなぜ?
使い道がよくわかりません。
390 :
デフォルトの名無しさん:04/01/31 22:17
>>389 関数の戻り値の型にconstをつける理由は知らないが、staticをつける理由は、その関数は他のファイルからは呼び出さない関数だから。
C++の場合は同等のことを
無名名前空間で行うことができる
namespace {
int hogehoge()
{
................
}
}
392 :
デフォルトの名無しさん:04/01/31 22:23
>>390 他のファイルから呼びださないからstatic?
どうしてですか?
393 :
デフォルトの名無しさん:04/01/31 22:24
>>392 一つのプログラム内に同名の関数があってもかぶらなくなる。
394 :
デフォルトの名無しさん:04/01/31 22:40
自分の家で電話かけているときにPCを使って電話を切断するってことは可能ですかね?
今、いとこがずっと長電話してて困ってるんですけど、そういうツールあったら教えてもらえませんか?
>>389 const をつけるのは、GCC とかの拡張じゃなかったっけ ?
関数の引数が同じ時に必ず同じ値を返す関数 (例: sin(x) とか) の時につけると、コンパイラが最適化の参考にする。
質問させていただきます。
ある2つのクラス間でそれぞれ相手のクラスをメンバを
持つにはどうしたら良いでしょうか?
hoge1.h --------------
#include "hoge2.h"
class hoge1{
hoge2 m_hoge2 ;
}
hoge2.h --------------
#include "hoge1.h"
class hoge2{
hoge1 m_hoge1 ;
}
↑でコンパイルするとエラーが出てしまいます。
回避法を御存知の方がいらっしゃいましたらご教授願いたいです。
397 :
デフォルトの名無しさん:04/01/31 23:32
>>396 不可能
そのm_hoge2がどんなメンバーを持つか考えれば分かるはず。
hoge1 a; a.m_hoge2.m_hoge1.m_hoge2.m_hoge1・・・・・止まらないね。
>>389 const を つけるのは 値を変更すんなってこと。
無理やりキャストとかして値変更したら、プログラムがぶっ飛ぶかも知れない。
>>396 無理。ポインタで我慢しる。かなり既出。
んで、解決策としては、ポインタを持つようにするとか。
>>397-399 早速のレスありがとうございます。
考えてみたらその通りでした。確かに無理がありました。
hoge2のメンバにhoge1のポインタを持つ事にします。
hoge2.h -------------
class hoge2{
void* m_hoge1 ;
}
使用時に
(hoge1*)m_hoge1
とキャストをするのは一般的な方法なのでしょうか?
hoge1.h --------------
class hoge1{
class hoge2* m_hoge2 ;
};
もしくは
hoge1.h --------------
class hoge2*;
class hoge1{
hoge2* m_hoge2 ;
};
402 :
デフォルトの名無しさん:04/01/31 23:48
>>400 なんでvoid *なんだよ。hoge1 *だろ。
hoge1.h --------------
#include "hoge2.h"
class hoge2;
class hoge1{
hoge2 *m_hoge2 ;
}
hoge2.h --------------
#include "hoge1.h"
class hoge1;
class hoge2{
hoge1 *m_hoge1 ;
}
ミスった・・・。
もしくは
hoge1.h --------------
class hoge2*;
の部分をを
class hoge2;
に訂正
>>402 ヘッダの中で、ヘッダをインクルードするのは避けた方が良いと思うが・・・。
(いや、まぁ状況しだいだろうけど・・・。)
405 :
デフォルトの名無しさん:04/01/31 23:51
406 :
デフォルトの名無しさん:04/01/31 23:52
既存のバイナリのデータファイルから,32ビット分などを読み込んで,
それをlongなどに変換したいのです.エンディアン等は自分で処理してます.
今までは,freadしてcharの4文字に入れ,操作していました.
しかしながら,スマートに,
ifstream ifs(file, ios::binary);
ifs.seekg(8,ios::beg);
bitset<32> bit;
ifs >> bit;
などやってみたいのですが,どうも,>>やifs.readなどでは無理のようです.
何か方法はないでしょうか?
>>402 hoge1* が望む所だったのですがインクルードが出来ず
型が宣言出来なかったもので…。
>>403 目からウロコでした。これで何とかなりそうです。
>>404 なるべくはしない様に心掛けています。
皆様どうもありがとうございました。
よく見てよ・・・
BCCを使っているのですが、一度画面をきれいにする場合は改ページでいいのでしょうか?printf("\f")を入れても画面がきれいにならないんですが・・・
>>402 失礼しました。クラスの型を宣言しておくのですね。
早速修正させていただきました。お陰様でエラー無しです。
ありがとうございました。
事故レスです.
Windows環境で,このようにキャストしたら読めた雰囲気です.
ifs.read((char*)&bit, sizeof(bit));
gcc2や3でOKなのか心配ですが・・・
>>411 それで構わない
>>406のやり方は operator>>( const istream&, std::bitset<32>& ) を自前で用意する必要がある
>>412 どうも有り難うございました.
演算子を用意するのは大変そうなので,キャストでいってみます.
有難うございました.
414 :
デフォルトの名無しさん:04/02/01 00:15
MIDIで音楽再生したんですけど
ボリュームの変更は可能ですか??
>>414 一般論でだが、再生デバイスに送るMIDIデータに直接ボリューム変化のデータを混ぜて送ればいいのでは。
>>415ありがとう
かなりの初心者なので良くわからない
ボリューム変更の関数みたいなのはないのですか?
難しい・・・
const が理解できてねーのがごろごろいるのは怖いな
アタシは説明していないわよ!
他人が壊したメモリの不始末をつける羽目になるのは勘弁してほしい
const char* func()
{
return "文字列";
}
これでいいんじゃない?
文字列リテラルっちゅーんだっけ?
これへのポインタは const だろう。
ちなみに定数文字列のスコープは
関数内にあっても常にグローバルね。
ここでもスコープと寿命の混同が
const char *を返す関数は使いづらい。
std::stringを返せと彼は言う
俺は CString ばっか使ってるなぁ。
逃れられないMS中毒。
const オブジェクトの参照を返すことなんかはよくあると思うんだが。
const / static / extern / explict / virtual
この辺だけ詳細に解説した本が欲しい。
文脈によって意味や効果が微妙に変わるよね。
初心者歓迎スレとはいえ、悲惨な状況だな。
>>432 たしかにstaticはローカルかモジュールレベルかで激しく意味が変わるが、
C++では後者の意味ではほとんど使わんだろ。Classの中に入れちまうから。
普通だったらあおって終わりだが、初心者スレだから、さくっと行っとくぞ。
const
書き換えられないオブジェクトをさす。関数の戻り値でも同じ。
帰ってきた値は書き換えられないということを意味する。
static(C)
ローカルなら静的オブジェクト。スコープを抜けても値が変化しない。
モジュールレベルなら、他のモジュールからは参照できないオブジェクト。
static(C++)
(インスタンスに対してではなく)Classに対するオブジェクト。
Classから生成されるインスタンスで共通に利用される。
explicit(つづり間違ってるぞ
>>432)
コンストラクタが引数に対して暗黙の型変換を行わないようにする。
平たく言えば、自分の書いたようにしかオブジェクトを生成しなくなる。
virtual
仮想関数であることをあらわす。要するにポリモーフィズムが利用できる関数。
vitrualがついていない関数を継承でオーバライドしても、ポリモーフィズムは
使えないからそのつもりで。
ポリモーフィズムがわからん?もっと勉強しなさい。
>>430 俺もそう思う。
>>404みたいな基準でインクルードされるファイルは選ばんだろ。
(宣言であろうが定義であろうが)そのファイルに必要なヘッダならincludeすべき。
というかせねばならん。ライブラリのヘッダとか読んだこと無いのか?
というか、
>>430以外誰も突っ込んでないのがやばい。
ここは初心者しか見てないのか?で、
>>404みたいな変な意見が出たら、
疑いもせず「そうなのか」って読んでるのか?大丈夫か、みんな?
ヘッダファイルから他のヘッダをあまりインクルードしてると依存関係が酷いことになるから、
前方宣言で済ませされるならなるべくインクルードせずに済ませたほうがいいというのは
事実だと思うが。
まぁ、程度問題ではあるが。
LSI C-86 と Borland C++5.5 の両方を使って勉強してます。
hoge="test";
sprintf( hoge, "%s is hoge", hoge);
上記のコードを書いた場合、
LSI C-86: "test is hoge"
Borland C++: " is hoge"
と結果が変わってしまいました。
この場合、sprintf の前後の変数は別々のもので処理しないといけないんでしょうか。
>>437 >この場合、sprintf の前後の変数は別々のもので処理しないといけないんでしょうか。
うーん、大丈夫かどうかは実装によるんじゃないかと。自信なし。なんか決まってるのかなぁ。
どちらにせよ別領域をお勧めするが。
ちなみにそのコードは別の問題も含んでいる。
440 :
デフォルトの名無しさん:04/02/01 06:51
C++にjavadocみたいなツールってあります?
>>437 同じ変数を使っちゃダメ
せめて、こうして欲しい
char buf[100];
sprintf(buf, "%s honya honya", hoge);
文字列、配列、ポインタについて書かれた本を読もう。
柴田望洋の本は、くどいがそういう面はきちんと書いてある。
(他は読んだこと無いんで、識者の方よろしく)
443 :
デフォルトの名無しさん:04/02/01 09:53
下のようなコードでdouble値をfloatに変換して、bufに流し込もうとしているのですが、
(計算上dblはdoubleで、通信量の節約からbufの中身をfloatにしたい)
RHL7.3(gcc2.95等)では問題なく、cygwin(gcc3.3.1)でコンパイルしようとすると、
error: non-lvalue in unary `&' を発生します。
char buf[128]; double dbl=1.20;
memcpy(&buf[0], &(float)dbl, 4);
float tmp = static_cast<float>dbl; memcpy(&buf[0], &tmp, 4); するよりは、
(明示的に)一時ファイルを作らない分、コードとして速いと考えていたのですが、
(たとえcompileが通ったとしても)やっていることは同じことなのでしょうか?
(そもそもdoubleをfloatに型変換して、送信バッファにほうり込む場合、どう組んだら最速なのか)
どうぞご教授くださいませ。
あー。質問は整理してから書いたほうがいいです。
Cの知識で答えます。
&(float)dbl←(float)dblが左辺値でないので&は使えません。
コンパイラでエラーがでるのはこのせいです。
よい書き方はあなたの書き方のように、
型変換させるために変数を使うことです。
こんな感じで愚直に書くのが間違えにくくてよいです。
char buf[128];
double dbl = 1.20;
float flt;
flt = (float) dbl;
memcpy(&buf[0], &flt sizeof(flt)); /* ←型のバイト数を直接書かないでsizeof()を使うほうがいいです */
・明示的に一時ファイル(変数のことですね?)をつくらずコードとして速い
→それよりも正しいことが大切です。
・やってるこは同じことなのでしょうか
→エラーが出ているものは正しくないコードなので同じとは言えません。
・送信バッファに放り込む場合、どう組んだら最速なのか
→通信は遅いものなので速度は気にしないで、マシン依存の部分を減らすほうが肝心です。
doubleやfloatはマシン依存なので、別のフォーマットを考えたほうがいいです。
浮動小数点数が必要なく、固定小数点数で扱えるのだったら、自分で表現方法を定義するのも手です。
445 :
デフォルトの名無しさん:04/02/01 12:31
std::vectorと代入演算子の関係について分からないことがあるので教えてください。
まず、Hogeクラスというのを作成し、オブジェクトのコピーを禁止するため
http://www.ogis-ri.co.jp/otc/hiroba/technical/CppDesignNote/ にあるように、コピーコンストラクタ、代入演算子を無効にしました。
class Hoge
{
private:
Hoge(const Hoge& other);
Hoge& operator=(const Hoge& other);
public:
//....
}
そして、このHogeクラスをstd::vectorを使って、動的にメモリを確保しようとしたら
以下のようなエラーになりました。
446 :
デフォルトの名無しさん:04/02/01 12:31
Hoge hoge;
std::vector<Hoge> h;
h.push_back(h);
'=' : private メンバ (クラス 'Hoge' で宣言されている)にアクセスできません。
'=' の宣言を確認してください。
コンパイルされたクラスのテンプレートのインスタンス化 'void __cdecl std::fill(class Hoge *,class Hoge *,const class Hoge &)' の参照を確認してください
'Hoge::Hoge' : private メンバ (クラス 'Hoge' で宣言されている)にアクセスできません。
'Hoge::Hoge' の宣言を確認してください。
コンパイルされたクラスのテンプレートのインスタンス化 'void __cdecl std::_Construct(class Hoge *,const class Hoge &)' の参照を確認してください
このとき、コピーコンストラクタと代入演算子をpublicにすると、エラーは出なくなります。
しかし、
http://www.ogis-ri.co.jp/otc/hiroba/technical/CppDesignNote/に コピーコンストラクタと代入演算子を明示的に定義しないと「どこからも指されていないメモリや、
複数箇所から指されているメモリができ、エラーが発生」とあります。
コピーコンストラクタと代入演算子の属性を変えないで、このエラーを回避するにはどうしたらよいでしょうか?
なんで「コピーコンストラクタと代入演算子を明示的に定義」しないの?
>>394 いとこに直接「長電話するな」と言えばいいと思うけど。
なんでもかんでも PC に頼るなよ。
>>417 すまん、char *const func() との勘違いだ。
>>422,
>>429 はぁ ? お前ら大丈夫か ?
>>431 2ch で「プロ」名乗ってる奴を参考にしてどうするよ。
449 :
デフォルトの名無しさん:04/02/01 12:45
何かの関数を使うとき、ヘッダーファイルをインクルードしますが、
ヘッダーファイルには宣言しか書いてないのですが、
その実装部分はどこにあるのでしょうか。
>>449 ソースファイルorオブジェクトファイルorライブラリ
シラネーヨ
このスレは初心者歓迎ですが解答者も初心者です
>>446 h.push_back(h)はh.push_back(hoge)の間違いかな?
そら、コピーを禁じるためにコピーコンストラクタ、代入演算子を無効にしておいて、
コピー作ろうとしたらあかんがな。
>>450 それじゃあ、例えばfopen()関数の実体はどこにあるのでしょうか。
どうやってリンクさせているのでしょうか。
455 :
デフォルトの名無しさん:04/02/01 13:30
そりゃDLLだろーよ
456 :
デフォルトの名無しさん:04/02/01 13:38
C/C++というよりはウィンドウズプログラミングに関する質問ということになると
思うのですが、教えてください。
ダイアログで設定を行ったデータを、そのダイアログの親であるウィンドウで用いたいです。
つまり、ダイアログプロシージャ内で設定したものをウィンドウプロシージャ内で使いたい
のですが、このインターフェイスはどうすればいいのでしょうか?
グローバル変数の使用は避けるという条件付きです。
以上、よろしくおながいします。
458 :
デフォルトの名無しさん:04/02/01 13:41
>>447 そっか。明示的に定義してみる。
>>453 はい。h.push_back(hoge);の間違いです。
やはり、コピーコンストラクタと代入演算子がprivate属性のままでは、
そのクラスはvectorで動的にメモリ確保はできないんですかね?
459 :
デフォルトの名無しさん:04/02/01 13:43
ダイアログが閉じられてから設定内容を取り出す関数とか用意しておいてソレ使えば?
>>458 だから、
>>453をもういっぺん声に出して読んでみれ。
つか、きみ、自分が参考にした文書に書かれてること理解しているか?
昔はconstがなかっただけで作法でもなんでもないと思うが
463 :
デフォルトの名無しさん:04/02/01 14:09
>>460 すいまそ。やっと理解しました。
コピーコンストラクタと代入演算子を明示的に定義します。
>>455 それはコンパイラが、使える関数をすでに全部知っているという
ことでしょうか。
それらの関数はどうやって登録されているのでしょうか。
それとも規定のディレクトリにオブジェクトを入れておけば
いいのでしょうか。
465 :
デフォルトの名無しさん:04/02/01 14:19
>>464 コンパイル済みのオブジェクトコードをまとめたものがどこかにあるはず。
*.libとか*.aで検索すると出てくると思う。
すでにコンパイルしてあるからいちいち使うたびにコンパイルせずにすむ。
>>463 いや、理解してない(苦笑
そもそもの問題は、
>>446のコードはオブジェクトをコピーをしようとしている
という点なんだけど。
なんで指定しなくても使えるかというと、printf等が入っているライブラリは大抵はデフォルトでリンクされるようになっているから。
そうでない関数を使うときは指定する必要があるよ(数学関連の関数を使うときの-lmはかなり有名)。
>>444 丁寧な回答ありがとうございます。
>あー。質問は整理してから書いたほうがいいです。
面目ないっす。
>こんな感じで愚直に書くのが間違えにくくてよいです。
>→それよりも正しいことが大切です。
>→通信は遅いものなので速度は気にしないで、マシン依存の部分を減らすほうが肝心です
いちいちごもっともです。それこそ頻繁に使うsizeof()の部分とか、
変に貧乏性になっている部分までバレバレでした。
470 :
デフォルトの名無しさん:04/02/01 15:10
>>466 う~ん、困った。
「コピーコンストラクタ、代入演算子を明示的に定義しないと、
元オブジェクトのフィールドをコピーしてくる。
そのとき、フィールド内に配列やポインタがあると、
元オブジェクトのフィールドのポインタが代入されてしまうので、
複数箇所から指定されているメモリができる。
だから、自分で明示的にメモリ確保の必要がある。」
と理解したんだけど・・・。
オブジェクトをコピーしようとしているのは分かります。
でも、vectorにオブジェクトを追加したい場合、
どのようにすればいいのか分かりません。
教えてください。
471 :
デフォルトの名無しさん:04/02/01 15:20
>>462 古いソースとの互換性を考慮してということ?
char *s=strerror(errno); /* 戻り値の型がconst char *だったらエラー */
こういうコードが通るようにするため?
>>170 いったいどっちを理解していないのかよくわからないな。
正しくコピーコンストラクタ/代入演算子が定義されてれば
何の問題もなくvectorに要素を追加できるぞ。
>>470 Hogeのコピーコンストラクタと代入演算子をPrivateにしているのは
どうしてなの?
一般的なコードで、コンストラクタがprivateってのはないかと
思うんだけど。operator=も。
そとから使うためにあるんでしょ?こいつら。
474 :
デフォルトの名無しさん:04/02/01 15:35
mallocの使い方が分からないんですが教えてくださいませ。
struct node *n; /* structureは構造体です。 */
n = malloc(sizeof(struct node)) ;
こういう場合に、nにアクセスするとき構造体として構造体のなかの変数にアクセスできますよね。
これはなぜなんですか?mallocというのは動的にメモリ領域を確保するだけではないんですか?
(だからnのなかに変数があるということは分からないんだと・・・思うんですが。。)
nが構造体型のポインタ変数だからその構造体にしたがってnを操作できるということですか?
その場合っていうのは構造体の中の変数のメモリ領域っていうのはnにアクセスしたとき初めて確保されるんですか?
(ポインタ変数を宣言&定義したときはポインタ分の領域しか確保されないと思うし・・・)
分かりずらかったらスイマセン。文章力ないもので・・
↑
struct node *n; /* structureは構造体です。 */ ←のコメント部分は無視してくださってけっこうです。
476 :
デフォルトの名無しさん:04/02/01 15:40
>>474 構造体というのは複数の変数を一つにまとめたようなもの。
だから構造体の大きさ分領域を確保するということは、少なくともその中に含まれる変数(メンバー)分は領域を確保することになる。だからアクセスできる。
struct node *n;
n = malloc(sizeof(struct node)) ;
これで、nにアクセスするコードは、
n->hoge;
と書くわけだが、コンパイラはnode構造体メモリ構造を知っているので、
hogeを指す適切なオフセットへアクセスする命令を生成すればいいわけだ。
>>470 もう、バカかアフォかと小一時間(ry
>オブジェクトをコピーしようとしているのは分かります。
自分でオブジェクトのコピーを禁ずるようクラスを定義しておいて、
自分で「コピーしようとしているのは分かります」って?
じゃ、コンパイルエラーで実行できないのが当然なのも分かるよな?
>でも、vectorにオブジェクトを追加したい場合、
>どのようにすればいいのか分かりません。
>教えてください。
これが聞きたかったなら最初からそう質問せぇや。回りくどいことは止めろ。
ポインタ使え
std::vector<Hoge*> hogetta;
hogetta.push_back( new Hoge() );
deleteを忘れないこと。
>>446のリンク先の文書をよく読んで理解すること。
あの文書は必要なことは一通り全て書いていてくれるぞ。
しかし、なんでオレが読まなアカンのか(苦笑
>>472-473 もとの質問は、「コピーコンストラクタと代入演算子を外から使えなくする」が趣旨
>>476 >>477 レスありがとうございます。
変数(メンバー)分は領域を確保するってことは分かってるんですよ。
その「hogeのメモリ領域」を「mallocで確保したメモリ領域」に割り当てる(hoge専用メモリ領域が作られる)っていのうはhogeにアクセスした瞬間ですよね?
(mallocで確保された領域はまっさらなわけだから・・・)
481 :
デフォルトの名無しさん:04/02/01 15:55
>>480 一度printfの%pを使って構造体変数のアドレスや、その中のメンバーのアドレスを表示させてみるとよいかもね。
>>480 違います。
mallocによってまっさら(というか、何が入ってるか不明)なメモリ領域が確保されます。
構造体のポインタ経由のアクセスは、そのメモリ領域が実際に何を指していようとも、
単純にそのまま行われます。
>>480 ちがいます。
malloc()の戻り値である、確保メモリ領域の先頭アドレスをさすvoid*型が、キャストされることで
その型として扱えるようになるのです。
単純なイメージだと、
struct node {
int hoge;
char hage;
double boke;
}
とした場合、struct node へのポインタ p を用いたアクセスは、
p->hoge : (int *)p + 0
p->hage : (char *)p + 4
p->boke : (double *)p + 6
などのように解釈されるような感じか。
485 :
デフォルトの名無しさん:04/02/01 16:08
じゃなくて*(int *)((char *)p+0) *(double *)((char *)p + 6)など
ありがとうございます。
つまり
>その「hogeのメモリ領域」を「mallocで確保したメモリ領域」に割り当てる(hoge専用メモリ領域が作られる)っていのうはhogeにアクセスした瞬間ですよね?
と言う考え方事態まちがってるんてて、、
mallocのメモリ領域は何が入ってるか分からないが、別に何が入ってるかは関係なく、その構造体のメモリ構造を見て、「hogeだったら*((int *)p+4)へのアクセスする」
というふうにコンパイラが解釈してるんですね?
とまあこのような考え方でいいんですよね?
489 :
デフォルトの名無しさん:04/02/01 18:00
>>478 どうもありがとうございます!
>自分でオブジェクトのコピーを禁ずるようクラスを定義しておいて、
>自分で「コピーしようとしているのは分かります」って?
>じゃ、コンパイルエラーで実行できないのが当然なのも分かるよな?
はい。コピーコンストラクタを外から見えないようにprivateで定義。
vector::push_back()でHogeクラスのコピーコンストラクタを呼び出しているので、
コンパイルエラーが出ていると理解しています。
>ポインタ使え
ポインタを使うことにより問題を解決することができました。
>deleteを忘れないこと。
hogetta.push_back( new Hoge() );
上のようにvectorにオブジェクトを追加した場合、deleteはどのように行っているのでしょう?
一応、調べて以下のサイトを見つけました。
http://www.radiofly.to/nishi/programming/cplusplus/multiset.html このサイトでは、明示的にdeleteを呼び出していません。
恐らく、begin()、end()を呼び出すことによってメモリの開放をしているのだろうと理解しています。
間違っていたらご指摘よろしくお願いします。
>>489 newを使ってpush_backによって要素を追加する場合、
明示的にdeleteを呼び出さない場合にはメモリリークが発生します。
ご指定のサイトのサンプルコードにおいては、プログラム終了時に
まとめてOSにメモリが返されることになりますが、大規模なプログラムにおいては
メモリを食いつぶしますので、やってはいけません。ポインタ型のコンテナを使うと、
std::vector.erase()等の削除系の関数を使うことができなくなります。なぜならば、
STLコンテナ内部でポインタ型に対して自動的にdeleteを呼び出すように規定されて
いないからです。というより、確実にメモリリークします。どうしてもポインタを
使いたければ、単純なポインタ型を使うのではなく、boost::shared_ptrなどの
参照回数計測のスマートポインタを使うようにしましょう。std::auto_ptrはご法度です。
ポインタ型でなければdeleteされるんだっけ?
ポインタ型にdeleteする理由はないです。
間違った。ポインタ型でなければdeleteする理由はないです。
> ちなみに定数文字列のスコープは
> 関数内にあっても常にグローバルね。
これはヤバイだろ。
>>490-493 質問の内容がはっきりしてなかったので、まとめます。
やりたいこと:
・vectorにオブジェクトを追加したい
・そのとき、クラスのコピーコンストラクタ、代入演算子はprivate属性にしておきたい
・追加したいクラス内のフィールドは複数の値とポインタだが、値のみ参照できればOK
問題点:
・オブジェクトのポインタを追加するときには、オブジェクトのポインタの変数を利用し、
その変数を用いることにより、あとで明示的にdeleteを行わなければならない。
Hoge* ptr = new Hoge();
std::vector<Hoge*> hogetta;
hogetta.push_back( ptr );
delete ptr;
・push_back(new Hoge())で要素を追加するとメモリリークが発生
・しかし、追加するオブジェクトの数は動的に変化させたい
充分大きなサイズでオブジェクトのポインタの配列を定義して
その配列に代入していけば大丈夫?
何かいい方法があったら教えてください。よろしくお願いします。
>>497 だからboost::shared_ptr使えといわれておろーが。
>・そのとき、クラスのコピーコンストラクタ、代入演算子はprivate属性にしておきたい
その設計のクラスで その使い方をするってーのが俺の頭の中で繋がらない。
ごめんな。力になれそうもない。
スイマセン、誰か
>>487を答えてくれませうか?なんか心配なんで・・・
>hogeのメモリ領域が取られるとか取られないとか関係なく・・・
>mallocのメモリ領域は何が入ってるか分からないが、別に何が入ってるかは関係なく、その構造体のメモリ構造を見て、「hogeだったら*((int *)p+4)へのアクセスする」
>というふうにコンパイラが解釈してる。
と言う風に考えていいんでしょうか?
STLのコンテナに載せるオブジェクトは
コピーコンストラクタが必須なのだが。
(デフォルトコンストラクタは必須ではなかったと思う)
>>500 mallocというより、ポインタ、構造体のメモリ空間並びがわかっているのか?
ポインタはアドレスの参照先を、型名に従って操作できるようにするためのものだ。
君はmallocでエリアを確保している。
そのエリアの先頭アドレスをポインタ型に格納している。
ポインタ型はhogeである。
そしてメンバにアクセスするときは
>>484が記述している通り
>>498-499 boost::shared_ptrを使って、vectorにオブジェクトを追加できるようになりました。
助言してくださった皆さん、どうもありがとうございました。
505 :
デフォルトの名無しさん:04/02/02 00:33
自作の関数を自作のヘッダーファイルに定義して、そのヘッダファイルをインクルードするだけで
関数を使えるようにしたいのですが、具体的にはどうすればいいんでしょうか?
例えば、自作の文字列コピー関数mystrcmp()を作り、それをmystring.hに定義します。
実際のプログラムでは #include "mystring.h" とすれば使えるようにしたいんですが・・・
>自作の関数を自作のヘッダーファイルに定義
それはやめときなさい。
>>505 オレもつねづね知りたいと思ってたんだけど、インクルードファイルの構成ってみんなどうやってるの?
VC使いなんでクラスヘッダと実装に分けることが多いんだけど、
コンポジションで他のクラスとかいれるとヘッダがすぐ重複するよね。
名前空間をちゃんと使えってことなのかなぁ。
do{
ret = read(fd,buf,1);
write(1,buf,1);
}while(ret!=0);
read で1バイト読み、それをEOFがくるまで表示するわけですが、
読んだ後に表示して、それからEOFのチェックってのはまずいでしょうか。
最初のreadで読みこめない場合を考えてみてください。
>>507 #defineで2回読まれても大丈夫なように書くでしょ
既存のヘッダ見てみりゃわかる
>>505 これも初心者FAQだな。
>>506もいってるけどインクルードするためのヘッダファイルに置くのは関数の”宣言”だけ。
”定義”は複数存在しちゃいけないからソースファイルに書いて分割してコンパイルする。
あとは整合性がチェックできるようにソースファイルからもヘッダファイルをインクルードしておく。
>>507 名前空間がヘッダの重複防止にはどう貢献するのかがわからんのだが
boostみたいに、
ヘッダを階層化した上で名前空間をつかうってことじゃないか?
ところで、コーディングルールとかが一般的できちっとしてる
クラスライブラリのお手本になるライブラリってどんなのがありますか?
(複数解答求む)
>>511 質問なんですけど、enumなんかも
ヘッダ
enum Hoge;
実装
enum Hoge{
Hage,
Hige,
Mage
};
とかできるんですか?ひょっとして。
よくクラス定義と抱き合わせでenumを置いて、リンカに文句言われるもんで
嫌気がさしてたんですが。
すいません、あまりに基本なことが出来ないのでこっちで聞かせてください。
BCBで複数行のテキストを表示させるのにLabelやStaticTextを使おうとしたんですが、
Wordrapをtrueにしたりしても幅のサイズで自動的に改行されるだけなんです。
任意の位置で改行させることって出来ないんでしょうか?
TMemoのカラーを後ろと合わせてBorderをゼロにして透明なラベルのフリをする、、
っていうのも考えたんですが、出来ればそれは最終手段に摂っておきたいと思いまして。
馬鹿な質問ですいません反省します。ごめんなさい生まれてすいません。
どなたかよろしければ教えてください…
>>513 >>511じゃないけど。
その実際に列挙しているところはヘッダに。
それで実体がとられるものではないでしょ?
.c や .cpp など、そのヘッダをインクルードする側では
#include "hoge.h"
enum hoge_var;
hoge_var = Hage;
:
if(hoge_var == Mage)
:
ってつかえばいいような。
>>514 すいません、そのあまりに基本的な質問の意味がわからないのであっちできいてください。
>>517 すいません、簡単なことをわかりにくく語ってしまいました。
要はLabel内のテキストを改行させるには?という質問です。
Lineプロパティのようなものがあればいいんですが、どうやらないようなのです。
>>518 良く知らないまま言っちゃってわるいけど、
文字列に \r\n 入れてもだめ?
>>513 > よくクラス定義と抱き合わせでenumを置いて、リンカに文句言われるもんで
よく言われるそのエラーメッセージを教えてもらえますか?
ワードラップは日本語には使えません
try~catchの例外処理って、
条件分岐とかでエラーメッセージ出してexit
とかするのとどういうメリットがあるのでしょうか?
>>524 exit なんかしちゃったら
デストラクタが呼ばれないじゃぁないの。
>>524 exitなんかしちゃったらプログラム丸ごと終了しちゃうじゃないか!
>>524 今までのスタイルだと、関数1つ1つの戻り値を
調べて、エラーかどうかを調べないといけないですよね。
で、面倒だからついついエラーチェックも疎かになっちゃ
うんですが、そうするとエラーが発生したまま、プログラムが
進行しちゃうかも知れない。
例外を投げるスタイルだと、ユーザーがエラーチェックを
しなくても、エラーが出たら確実に止まってくれるわけです。
これだとエラーを抱えたまま、プログラムが走って間違った
結果を出すことが抑止される。
こういう利点があるんじゃないですかね。
んで、止めたくなければ 例外をcatch すればいいんです。
例外を使わない場合
if(hoge)
erroe処理;
if(foo)
erroe処理;
if(bar)
erroe処理;
例外を使うと(各関数内で例外を投げるとすると)
try{
hoge;
foo;
bar;
}catch(...){
error処理;
}
ただし処理速度が少々犠牲になる
エロ絵処理;
float型の数値をCString型に変更したいのですが
どうすればよろしいでしょうか・・・?
Formatとか
532 :
デフォルトの名無しさん:04/02/04 20:44
ofstreamなどでファイルを生成する際に,ファイル権限を任意に指定することは可能でしょうか?
Linux上で動作するマルチプロセスのプログラムがあり,
片方はApache権限,片方はルート権限で動作します.
プロセス間通信をソケットで行い,それぞれがデータをファイルに書き出すのですが,
root権限側のプログラムが生成したファイルがApache側モジュールで改変できないのです.
ということで,root権限で動作するプログラムがストリームを開く際に,
他のユーザが改変できるようなレベルでファイル生成することは可能なのでしょうか・・・?
>>532 共通のグループ作って、グループに対して rw 権限与えればいいと思うが。
あるいはファイル作った後で、chown 使って apache のユーザーに変更しちゃうとか。
>>532 root権限側で、setuidとか実行権限を変更したり、
>>533 のchownとか。
535 :
デフォルトの名無しさん:04/02/05 04:03
multimap<string, string> str;
str.insert(make_pair("A", "aaa"));
str.insert(make_pair("A", "bbb"));
str.insert(make_pair("A", "ccc"));
このようになっている場合、"A"とペアになっているものを全て
出力するにはどうすればいいのでしょうか?一応
multimap<string, string>::iterator q;
cout << q->second << endl;
cout << (++q)->second << endl;
cout << (++q)->second << endl;
一応これで出力できたんですが、もうちょっとスマートなやり方があるらしいんですが
どうすればいいんでしょうか?
537 :
デフォルトの名無しさん:04/02/05 08:38
multimap<int, string> mapa;
string str[xx][yy]="(初期化)";
for(int i=0; i<xx; i++){
for(int j=0; j<yy; j++){
mapa.insert(make_pair(i, re_cabocha[i][j]));
}
}
こんな感じのプログラムを組んでるんですが、なぜか最初のペアをinsertする時点で
セグメンテーション違反で止まってしまいます。
文法的には間違ってないと思うんですが、なぜなんでしょうか?
538 :
デフォルトの名無しさん:04/02/05 08:39
multimap<int, string> mapa;
string str[xx][yy]="(初期化)";
for(int i=0; i<xx; i++){
for(int j=0; j<yy; j++){
mapa.insert(make_pair(i, str[i][j]));
}
}
すいません、こうでした…
すげぇ、馬鹿みたいな質問します。
どなたか教えてください。
hogehogeってClassがあったとします。そのクラスには
unkoというメンバーが含まれています。
ここからなんですが
hogehoge test;
hogehoge *test2 = new hogehoge;
test.unko();
test2->unko();
間接参照子使うのとそうではないの、違いはなんでしょう?(汗
いったいどういう風に使い分けすればよいのでしょうか?
結果は同じなんですよね…
どなたが教えてくださいお願いいたしますm(_ _)m
>>540 前にも見たな。この手の質問。
a->b は (*a).b の略記形。
>>540 ホントにウンコみたいな質問だな
ポインタ->
インスタンス.
「ポインタ」と「インスタンス」の違いをもう一辺勉強しなおすべし
>>541 どっちが効率がよいとかそういうものではないのですか?
>>541 オペレーターが書きかえられてたら、その限りではないのでは?
あ、ごめん、
ポインタ->
なら、オペレーターうんぬんは関係ないっすね。
>>544 まぁね。
普通は -> が (* ). の略記形になるように
オーバーロードすると思うけど、
確かにその限りではない。
547 :
デフォルトの名無しさん:04/02/05 13:07
浮動小数は、値に誤差がふくまれると聞いたのですが、
float a = 1.0f;
a /= 1.0f
とした場合でも
誤差が含まれることはあるのでしょうか?
誤差というのは、CPUの浮動小数演算から発生するものなのでしょうか?
浮動小数演算の誤差にはいくつか種類があるが、
代表的な(例として出されることが多い)誤差は、実数部が2^nで表せない数値である時、
それに最も近い2進数として処理されることにより発生する。
549 :
デフォルトの名無しさん:04/02/05 13:35
Linuxで自パスの取得方法ってないでしょうか?
Windowsならば
charszPath[_MAX_PATH];
charszTemp[_MAX_PATH];
char*pPos;
UINTnLen;
ZeroMemory(szPath, _MAX_PATH);
::GetModuleFileName(NULL, szTemp, _MAX_PATH);
pPos= strrchr(szTemp, '\\');
nLen= pPos - szTemp + 1;
lstrcpyn(szPath, szTemp, nLen + 1);
みたいに取得できるけど。
どなたかご存知ありませんか?
550 :
デフォルトの名無しさん:04/02/05 15:25
>>549 プログラムなら
argv[0]
あとは…次のひと
sample.cppの関数をsample.hでプロトタイプ宣言するとき他のファイルから読み込むためにexternで宣言しますよね?
このときsample.cppの内部でsample.hをincludeしてもプログラムは動きますが速度低下やプログラムサイズの増大などの問題はあるでしょうか?
ヘッダファイルはあくまで外部が参照するためのもので、ファイル内部の関数やクラスについては必要があればそのファイルの中用に別にプロトタイプ宣言を書くべきなのでしょうか?
ちょっと気になってるので教えてくださいm(_ _)m
>>551 >他のファイルから読み込むためにexternで宣言しますよね
普通しないと思うが・・・。
[hoge.h]
#ifndef ___HOGE__H___
#define ___HOGE__H___
void funcHoge();
#endif
で、2重読み込みは回避できると思うが・・・。
コマンドライン hoge.exe hogeで
hogeに-hoge0が指定されたらint hogeに0を、
hogeに-hoge1が指定されたらint hogeに1を代入するにはどうすればいいですか?
関数のextern宣言って意味あるのか?
あってもなくてもかわらんような・・・
>>550 フルパスが得られる保証がないんだよな。
でも、フルパスを得られる移植性のある方法はない。
argv[0] が相対パスなら
何らかの関数でカレントディレクトリを得て
くっつけるしかないけど、
カレントディレクトリを得る標準関数はない
(ディレクトリの概念がない環境も考慮してるため)。
でも、Linux なら大抵のコンパイラで getcwd が使えるかな?
>>551 #includeの動作を考えてください。
>>553 コマンドラインを解析すればいいっしょ。
二次元配列a[][]を実引数として、呼び出される関数に渡す場合は
どのように記述したらよいのでしょうか?
一次元の場合は、
void aaa(int s[])
↑
aaa(s)
だと思うのですが、二次元になるとわかりません。
>>550 ありがと、取得できました。
コマンドラインとは盲点だった・・・。
>>555 >>557 ちなみにカレントからやった場合は ./実行ファイル名
で取得になるけど、今回はカレントにあるファイルを
取得したかったので解決でした。
getcwd は調べてみますっ。
>>558 ちなみに、char型の配列を渡したいです。
char buf[256];
memset(buf[0] , 0 , sizeof(buf));
って言うの出したら
(´・ω・`) 文字を0で初期化すんなゴルァって言われたんですが
memset(buf[0] , NULL , sizeof(buf));
これって有りですか?コンパイルは通るんですがなんか不安で…
>>563 memset(buf, 0, sizeof buf);
memset(buf, '\0', sizeof(buf));
の方が(見かけ上)良いかもしれないが、
> 文字を0で初期化すんなゴルァって言われたんですが
これを言った奴の言葉は、今後信用するな。
NULLは不可。
#defineの仕方によっては通らない(そのdefineも正しい)し、
通るとしても、NULLはポインタが必要な文脈でのみ使われるべき。
'\0'が0でない処理系があるとか
>>552 初心者スレで敢えて言っておきたい。
> #ifndef ___HOGE__H___
これは処理系用に予約された識別子に含まれてしまう
にもかかわらず、インクルードガードに大量のアンダースコアを使う人は依然として多いようだ。
hoge.h に対する(簡単な)インクルードガードの例としては、
#if !defined( HOGE_H_INCLUDED )
をお勧めしたい。
>>566 型を考えると '\0' と 0 は違うかもしれんけど、
この場合はそれらの違いが影響しないので
単に見た目の問題だね。
>>567 #if !defined( HOGE_H_INCLUDED ) の理由は何?
#ifndefじゃだめなの?
>>568 __ を含むマクロ名か、_ で始まるマクロ名は
処理系に予約されている。
でも、_ で終わることはできるので、
俺はインクルードガードとか
外部から使用しないようなマクロ名とかは、
その印として _ で終わるようにしてるな。
あと、#ifndef を使えるところには #ifndef を使いたいな。
拡張する予定のある場合や
#elif がある場合は #if 使うけど、
インクルードガードはどちらにも該当しないので
#ifndef を使ってる。
タイプ数少ないし、define と同じタイプ数なので
上書き編集で #ifndef ~ を #define ~ に変えれるし。
予約はキャンセルしといてください
すいません。言いたかったのは名前の問題だけです。
#ifndefでまったく問題ありません。
>>557 それがうまくできないわけで…
#include <iostreame.h>
void main(int ac, char *av[]){
int hoge = -1;
if(av[1] == "-x") hoge = 0;
if(av[1] == "-y") hoge = 1;
printf("ac=%d hoge=%d", ac, hoge);
}
これだと-x、-yのいずれでもhoge = -1になってしまうのは何故…?
>>575 はぁ...。
strcmp を調べれ。
strcmp
>>552 多重定義はしないようにしてあります。
>>554 VCの場合はexternを付けなくてもコンパイルが通りましたが、
g++の場合にはexternは必須でした。
externの仕様を読んでもやはり別のファイルに呼び出す関数がある場合にはexternは必要なようです。
1つのcppファイルをクラスのようなものとみなすと
extern -> public
static -> private
のような意味合いになるようです。(あってる?実際にはメモリの確保とかの別の意味合いもあるけど)
externが付いているプロトタイプ宣言を読み込んでもリンカが解決してくれそうなのであまり関係ないのですかね?
>>578 きっとなにか大誤解しているからソースをさらせ。
>>551 >このときsample.cppの内部でsample.hをincludeしてもプログラムは動きますが速度低下やプログラムサイズの増大などの問題はあるでしょうか?
結論としては、両方のパターンでコンパイル・リンクかけて、
サイズ、実行速度を計測すれば答えはでる。
581 :
デフォルトの名無しさん:04/02/05 23:31
>>456 【規定】
この説明において、ウィンドウプロシージャをWinProc()、ダイアログ
プロシージャをDlgProc()と呼ぶことにする。
【方針】
WinProc()、DlgProc()で要するデータは構造体にまとめておき、実体を
WinProc()側に持ち、この実体を指すポインタをDlgProc()で参照可能にする。
【手順】
1) WinProcのWM_CREATEにてポインタが実体を指すようにする。
2) 1)の直後に SetWindowLong()する。第一引数はウィンドウハンドル、
第二引数は 0、第三引数は上記ポインタをLONGでキャストしたものとする。
3) WinProcのWM_CREATE内で行うべき処理は以上。
4) DlgProcのWM_INITDIALOGにてGetWindowLong()する。第一引数はウィンドウ
ハンドルなのでダイアログのハンドルに対してGetParent()したものを
用いればいいだろう。第二引数は 0。このGetWindowLong()の戻り値が
1)でのポインタなのでキャストをして用いる。
【余談】
WinMain()とWinProc()との間でも同じ手法を用いれるか試してみたがNG。
WinMain()でウィンドウハンドルを得る前に、WinProc()でのWM_CREATEイベント
が起こるためにタイミングが合わないのが原因。この手法ではダメだと思われる。
以上。
>>581 細かいことだが
G/SetWindowLong じゃなくて、
G/SetWindowLongPtr を推奨したい。
584 :
デフォルトの名無しさん:04/02/06 01:08
map<int, string> map1;
map1.insert(make_pair(1, "いち"));
map<int, string>::iterator iter1;
cout << iter1->second << endl;
map<int, string> map1;
map<int, string>::iterator iter1;
map1.insert(make_pair(1, "いち"));
cout << iter1->second << endl;
上の場合は上手くいくのに、下の場合はセグメンテーションエラーになるのは
なぜでしょうか?また、下の方法でcout << iter1->second を表示させるには
どうすればいいのでしょうか。
位置を教えてやればいいような気もするんですがコンパイル通らず…
いつ iter1 にイテレータを代入してるんだ?
>>575 >>if(av[1] == "-x") hoge = 0;
>>if(av[1] == "-y") hoge = 1;
BASICじゃないんだから。
もうちょっと文字列と配列について学習することをお勧めする。
答え書けば一発だけど(もう書いてあるけど)、
この調子でプログラム書いてたら、
たとえ動いたとしてもそれはたまたまと思ったほうがいい。
>>584 うえでちゃんと動いたのはたまたま。
>>585の言うとおり、iter1の初期値に代入していないから、結果は不定。
結果は不定ということは、つまりOS関係のファイルが*全て*こわれてても
文句は言えないということだ。
「変数は初期化する」
この大前提を守りましょう。
>>586 > 結果は不定ということは、つまりOS関係のファイルが*全て*こわれてても
> 文句は言えないということだ。
ありえない。自分でそんな糞OSとコンパイラを作らないかぎり。
ありえなくはないだろう
動作させたやつが管理者権限あれば。
MS-DOS ならありうるかも。
初期化忘れてました。
レスどうもです。
「不定」と「未定義」を混同しちゃいけないな。
不定と未定義はどう違うんですか?
字が
不定の方が環境に優しい
>>587 そんなあなたに nasal demons をどうぞ。
596 :
デフォルトの名無しさん:04/02/06 09:51
開発環境Win2K,VB6.0&VC++6.0で、内容としてはVBの要素が強いのですが、
フックルーチンはC++、あまりにも環境依存なのでこちらで質問させていただきます。
VB6.0でPrinterオブジェクトを利用した出力処理があるのですが、
プリンタの設定でファイルに出力する場合にファイル名を入力するダイアログがでてきます。
このダイアログを出さないようにしたいのですがなにかよい方法はないでしょうか?
(最初考えたのは、WinSpool の StartDocPrinter をフックして、
DOCINFOにファイル名を加えてやればできるかなと思ったのですが
それより先に StartDocDlg というよくわからないAPIを呼んでいて
ダイアログもそこででているようで行き詰ってしまいました・・・)
597 :
デフォルトの名無しさん:04/02/06 10:48
環境依存になるのですが、教えてください。
XP+SP1+IME2003の環境において
Win32APIのImmGetRegisterWordStyleを利用して
品詞の数を取得したいのですが、戻り値が0になってしまいます。
また、品詞情報の取得のできません。
IMEの他バージョンでは正常に取得できます。
IMEのバグかもしれませんが情報がありましたら教えてください。
スレ・板違いでしたら誘導お願いします。
598 :
デフォルトの名無しさん:04/02/06 10:54
質問です。
WindowsのVisualC++ 6.0で、PostMessageを使っています。
PostMessageのLPARAM,WPARAMでは入りきらない大きいデータを受け渡ししたいと思っています。
現在、Post側でデータオブジェクトをnewして、そのポインタをLPARAMで送信、メッセージハンドラ側で
そのデータオブジェクトを使った後deleteしようとしているのですが、delete時にプログラムが落ちてしまいます。
このような、Messageをまたいだ動的確保メモリオブジェクトの利用は不可能なのでしょうか?
不可能である場合、Messageで小さくないデータを渡す方策として、どのような手段があるのでしょうか?
>>591 不定
毎回動作が変わる可能性があることが保証されている。
未定義
仕様では定義されていないが、
処理系ごとに定義されている。
常に同じ、 オプションによってスイッチング可能、不定、の
3種類のどれかで定義されている可能性がある。
って認識で合ってる?
>>599,600
個人的な見解ですが、未定義は不定よりも広義なんじゃないかなぁと思います。
不定というのは、不定であると「仕様が定義されている」状態。
未定義は仕様として定義されていない状態。
どっちも基本的には「どうなるか知ったこっちゃない」という意味で、不定であっても
未定義であっても、変化するかもしれないし、変化しないかもしれない。
asisで言葉以上の意味はないと思った方がいいんじゃないでしょうか。
>>601 例えば、「関数の実行結果が不定である」と「関数の実行結果が未定義」と言うのではぜんぜん違う。
不定は、実行結果は知ったことじゃないけど、とにかく実行結果を得られる。
(プログラムが飛んだりしないことが保証されている。)
未定義は、実行自体がどうなるかわからない。
本当に初心者の質問で申し訳ないんですが、独習Cという本でCを勉強しようと
思っていて、コンパイラのmicrosoft netframework sdkを書いてある通りにインストール
して、テキストで簡単なプログラム書いて、コマンドプロンプトで実行してみたところ、
C:\>cl TEST.c
Microsoft(R) 32-bit C/C++ Standard Compiler Version 13.00.9466 for 80x86
Copyright (C) Microsoft Corporation 1984-2001. All rights reserved.
TEST.c
c1 : fatal error C1083: ソース ファイルを開けません。'TEST.c': No such file or d
irectory
このような文が出るのですが原因が分かりません。
windows xpで、パソコン買ったばかりなので特に変な設定はしていないと思うのですが。。。
>>598 送信側と受信側が別プロセスとか
アプリ-DLL間のやりとりでnewとdeleteが一致してないとか
>>603 原因はエラーメッセージの通り
TEST.cの名前を確認(綴り間違いは無いか)し、
TEST.cをパスをつけて指定するか
TEST.cのあるディレクトリに移動してからコンパイラを呼ぶか。
>>606 ありがとうございます。
パスをつけるというのは良く分かりませんが、
clコマンドの後ろにテキストファイルを直接ドラッグしたら出来ました。
clコマンドを使うときは
C:\>cl "C:\Documents and Settings\。。。。。\My Documents\cprogram\TEST.c"
こんな風にディレクトリを移動させてからでないとファイルを発見できないということでしょうか?
C:\>という一番大きなところでOKかなと思っていたのですが。。。
構造をちゃんと理解してないんですかね。。。
最上位のディレクトリからファイルのフルパスを指定してもできないことはないが
ふつうは cd <dirname> で目的のディレクトリに移動する。
プログラミング始める前にディレクトリ(フォルダ)の階層構造について調べろ
>>607 それがパス
ディレクトリの移動は CD を使う
CD/?で使い方がでる
これ以上はスレ違いなので自分で勉強しろ
help > "C:\適当なファイル名.txt"
と打ち込めばコマンドの一覧が指定したファイルに出力される
>>604 どうもありがとう。
原因がわかりました。単に私が2重にdeleteしていただけでした。単なる私のバグでした。
ごめんなさい
oTZ
611 :
デフォルトの名無しさん:04/02/06 15:05
C++を使ってWindowアプリケーションを作りたいのですが、
調べていると、MFCとかVCLなど色々なAPIがあることを知りました。
C++を使うからには高速に動作するものを作りたいのですが、
どのAPIを使えばいいのでしょうか。
MFCは動作が遅いなどと聞いたのですが、VBやJAVA並なのでしょうか?
それはAPIじゃなくてクラスライブラリ
素のWIN32APIを使うのが一番速いが、
クラスライブラリを使ったってVBやJAVAと違って
ネイティブコードになるのでそれらよりはずっと速い
>>611 漏れはプログラミング初めて半年だが、
Win32API以外まったく分からん。
最初は生のWin32APIで書いていくと、
Windowsプログラムの仕組みがよく分かると思う。
以上、MFCを理解できない香具師の独り言
>612,613
なるほど。
クラスライブラリを使っても十分高速なものができるのですね。
動作はWin32APIが一番速いと言うことですので、これを使ってやってみます。
ありがとうございました。
最近の高性能なPCでは、
表面上の違いが分からないのでは
遅いマシンで動かしてみると、愕然とすることもある。
真および偽をあらわす Boolean 型って、
標準的なライブラリに含まれていますか?
べつにクラスじゃなくて自分で typedef してもいいんですが、
なにか標準的なものがあるならそれに従おうと思って。
bool
620 :
デフォルトの名無しさん:04/02/06 17:30
/*
彼女とはBまでいったのですが
なかなかCさせてもらえません
どうすれば皆さんの様にC++までマスターできるのでしょうか
教えて下さい、最近はfree()されそうで怖いです
*/
_Bool
まずは「はじめてのC」を熟読しろ
1999 年、ついに新しいプログラミング言語 C の仕様
「ISO/IEC 9899:1999 - Programming Language C」(略称 C99) が
1999/12/01 付けで規格として出版されました。
ここでは、その新機能を説明します。
(中略)
今まで C 言語の整数型は char、short int、int、long int 型がありましたが、
今回からこれに加え _Bool 型と long long int 型が使用可能になります。
http://seclan.dll.jp/c99d/c99d05.htm#dt19990614X
624 :
デフォルトの名無しさん:04/02/06 17:33
>>621 いつまでがんばってもfalseのままで。。。
だ、だめだ…
俺は激しく時代から取り残されている。
C には bool なんてなかったし、
C++ に名前空間なんてなかった…
>>620 付き合うのやめたら ?
free() ならいいけど、闇雲にやってると SIGSEGV で kill() されるかもしれないし。
世の中には、J○va とかのもうちょっと優しい人もいるから、乗り換えるのが吉かも。
あと、なんで符号付き&符号なしローテートがないんだろうね…
そんなもんはインラインアセンブラで書けってこと?
628 :
デフォルトの名無しさん:04/02/06 17:36
>>628 ((((((;゚Д゚))))))ガクガクboolbool
630 :
デフォルトの名無しさん:04/02/06 17:39
>>626 kill()はちょっと不味いですね
j○va系かー、でもpublicっぽいのは好きじゃないんですよね
ネストしまくりそう
今の C は激しいんだなぁ…
複素数型まであるんだね。
そのうち四元数まで盛り込まれたりして。
ネタはマ板かUNIX板でどうぞ。
C99 の仕様を見てたら、
なんと可変個数の引数を取るマクロも定義できるんだね。
いままで GCC の独自拡張機能を使うしかないと思ってた。
これで printf のラッパーマクロが作れる。
・配列のサイズは固定でなければならない
・printfには%lfはない
などと言うと時代遅れといわれます。
俺、C++ で例外と実行時型情報を使うことに
生理的嫌悪感があるんだけど、そんなやつ他にいない?
そんなことやりたいなら Java とか C# 使えよ…って思うんだが。
>>627 ローテートが無いプロセサもあるし、プロセサが扱えるビット幅以上のデータのローテートは激しくうざいから。
>>635 使いたくなければ使わなければすむだけの話。
後半部分は納得できない。
>>631 C++ならboostにquaternionがある
640 :
デフォルトの名無しさん:04/02/06 18:02
Visual Studio .Net を用いて、
COM利用を勉強にとりかかったところです。
参考にしているページは下記です。
ttp://www.asahi-net.or.jp/~kv8s-yjm/another/yja008.htm COMコンポーネントのインスタンスを作成する下記の文章
hResult
= CoCreateInstance(&CLSID_Class1, 0, CLSCTX_INPROC_SERVER,
&IID__Class1, (void**)&pIClass1);
をコンパイルすると
error C2664: 'CoCreateInstance'
: 1 番目の引数を 'const GUID *__w64 ' から 'const IID &' に変換できません。 (新しい機能 ; ヘルプを参照)
がでます。一応、OLEViewerを用いてIDは確認しているのですが...
どうしてでしょうか?
>>640 CoCreateInstanceのプロトタイプ宣言を確認してみた?
初めまして。BCB4.0で、VCLを使ったdllを作ろうと
しています。
BCB4.0のヘルプファイルには「VCL コンポーネントを含む
DLL の作成」という項目があり、「YES」「NO」という2つのボタン
を有するフォームを作成する例が掲載されています(多分、BCB
5.0以降でも同じような内容があると思います)。
しかし、実際に作ろうとしてBCBの「ファイル」→「新規作成」
→「ダイナミックリンクライブラリ」を選択すると、フォームの無い
プロジェクトが作成されてしまいます。dllを作成するプロジェクト
にフォームを追加するにはどうすればよろしいのでしょうか?
あっすいません。専用のスレがありましたので、そちらで質問します
errno.h は C90 で標準になっているんですが、
そこで定義されているエラー番号というものは
どの程度標準化されているものなんでしょうか?
なるほど…
EDOM = 関数の定義域のエラー
ERANGE = 関数の値域のエラー
ってわけか…
>>635 使わない奴に嫌悪感ならわかるが、
なんで使うことに嫌悪感なんでしょう?
パフォーマンス犠牲にするから?
当時はJAVAも無かったからなぁ
>>649 それも不当だと思うんだがなあ。たいていオプションでオフにできるし。
比較するなら同じことを言語機能を使わずに実現する場合と比べてくれないとさ。
必要だから使うしそのための機能が言語にあれば利用する。必要なければ使わない。
RTTIフレームワークで実現できなくはないけど
例外はリソース解放とかまで考えると相当きつくない?
例外使うのが嫌なんじゃなくてそもそも例外を考慮した設計を
してないってだけならそれこそ筋違いだと思う。
何でもかんでも例外で済ますのも問題だけど、
一切使わないというのも勿体無いと思うなー。
自身が理解できないからじゃないの?
>>651 >例外はリソース解放とかまで考えると相当きつくない?
前はこれで例外のありがたみが分からなかったんだけど
スマートポインタを使うようになって便利だなと感じるようになった。
>>655 > ポインタ変数がchar型int型と変わったらポインタもchar型対応のアドレスサイズ、int型対応のアドレスサイズと変わるということですか?
ANSI の規格の範囲でそういう処理系を作ることができると言う話。
そういう処理系では、
#define NULL ((char *)0)
int *ip = NULL;
ってやると何が起こるかわからない。
でもそんな処理系見た事ある奴はいないからあまり心配しなくていい。
> これも↑と一緒の意味ですか?
これは、0 (= int) とポインタのサイズの問題を言っている。
int *ip = 0;
とした場合は、コンパイラが自動的にヌルポインタに変換してくれる。(=常に正しく動く)
しかし、
int i = 0;
int *ip = (int *)i;
とすると、コンパイラはポインタに内部表現 0 の整数を代入しようとする。
これは、int とポインタのサイズが同じでかつヌルポインタの内部表現が 0 である処理系に限ってうまく動く。
こっちは、上と違ってそうでない処理系がそれなりにあるので注意すること。
>>655 > ポインタ変数がchar型int型と変わったら...
http://www.catnet.ne.jp/kouno/c_faq/c5.html#17 の回答の一番上の例を参照。
>>656 > なぜならポインターの大きさは、intの大きさと違うかもしれない。
違う。ヌルポインタの内部表現を 0 と定義すれば、
その程度は変換されるはず。
これは多分可変個引数(もしくはプロトタイプなしの関数呼び出し)で起きる
問題のことを話しているんだと思う。
0 とだけ書くと int と見做されて渡されるけど、
ポインタと int のサイズが違えば引数がずれてしまう。
他にも C++ だとオーバーロードの解決の時に、
int とポインタの両方を受け付ける場合には、
NULL は int だと認識されてしまう。
だからキャストが必要なんだけど、
ヌルポインタの内部表現を 0 にすることでこの問題が解決されるわけではない、
と言ってるんだと思う。
例えば 64 ビットの環境では
int が 32 ビットでポインタが 64 ビットであることがある。
そういう場合、NULL が 0 と定義されてると(例えば C++ では常に 0 と定義されている)、
printf("%p%d\n", NULL, 3); と書いてしまうとおかしなことになる。
>>656 >int i = 0;
>int *ip = (int *)i;
>とすると、コンパイラはポインタに内部表現 0 の整数を代入しようとする。
iが const int ならヌルポインタに変換されるんだっけ。
C++3rd に const int NULL = 0; って話が出ていたような
気がするんだけど
const int i = 0;
int *ip = (int*)i;
これならば iは正しくヌルポインタに変換されるのだろうか。
>>659 G++ 3.3.1 では代入できないみたいだが、
それは最新の仕様なの?
というか、そんなことをしても何のメリットも無い気がするのだが。
>>657 自己レス
ちょいと
>>656 の内容を誤解していた。
そもそも int* p = (int*)i; がコンパイルすらできないだろうということか。
でも、どちらにしろあそこで言おうとしてることとは別の問題だと思うけど。
そうなんですが、どうなのだろうと疑問に思ったもので
g++ではどんなエラーがでますか?
662 :
デフォルトの名無しさん:04/02/07 00:01
***すれ立てるまでもない質問はここで 第50刷***
http://pc2.2ch.net/test/read.cgi/tech/1075637619/ からきました。
cygwin の g++を使って環境に依存しないコードを書きたいと思っています。
まずmainとWinMainが問題なのでスタティックライブラリに押し込めてしまって、
ライブラリ内のmainかWinMainから void Main() を呼び出すようにしようと思いました。
○ライブラリ側 main.cpp
#if defined(TARGET_WIN)
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
... 引数の保存など ...
Main(); return 0;
}
#else
int main(int argc, char* argv[]) {
Main(); return 0;
}
を g++ -c main.cpp -o main.o; ar r libmylib.a main.o とし、
○アプリ側コード app.cpp
#define TARGET_WIN (1)
void Main()
{
}
を g++ -c app.cpp -o app.o とし、
最後にリンクしようとして
g++ app.o libmylib.a としましたが、_WinMain@16 が定義されていないというエラーが返ってきます。
何が起こっているのかわかりません。
ライブラリの中身までWinMainを探しに行ってくれないのでしょうか?
>>661 ごめん。勘違いしてた。
int* へ明示的にキャストしたらエラーがなくなった。
というか、これは int でもエラー出ないし。
CとC++ で const の扱われ方が違ってましたね。
C++ では良くても Cだと上手くいかないのかな。
C でもうまくいったよ。
でも、sizeof (int) != sizeof (int*) の環境じゃないからなぁ...。
nurupo
こういうときこそ規格の出番ですよ。
■ C++の場合
ISO C++ 規格 ISO/IEC 14882:1998より
|5.2.10 Reinterpret cast
|(略)
|64) Converting an integral constant expression (5.19) with value zero
| always yields a null pointer (4.10), but converting other expressions
| that happen to have value zero need not yield a null pointer.
|5.19 Constant expressions
| (略)
| An integral constantexpression can involve only literals (2.13),
| enumerators, const variables or static data members of integral
| or enumeration types initialized with constant expressions (8.5),
| nontype template parameters of integral or enumeration types,
| and sizeof expressions.
以上により const int i = 0; なら i は constant integral expression で、
なおかつ値が 0 であるから、ポインタ型にキャストすれば null pointer に
なることが保証される。
一方、int i = 0; ならば constant じゃなくなるので値が 0 であっても、
ポインタ型にキャストして null pointer になることは保証されない。
■ C の場合
ISO C 規格(C99だけど) ISO/IEC 9899:1999 より
|6.3.2.3 Pointers
|3 An integer constant expression with the value 0, or such an expression
| cast to type void *, is called a null pointer constant. If a null pointer
| constant is converted to a pointer type, the resulting pointer, called
| a null pointer, is guaranteed to compare unequal to a pointer to any object
| or function.
|5 An integer may be converted to any pointer type. Except as previously
| specified, the result is implementation-defined, might not be correctly
| aligned, might not point to an entity of the referenced type, and might
| be a trap representation.56)
|
|6.6 Constant expressions
|6 An integer constant expression96) shall have integer type and shall only
| have operands that are integer constants, enumeration constants, character
| constants, sizeof expressions whose results are integer constants, and
| floating constants that are the immediate operands of casts.
const 変数も integer constant expresssion に含まれないため、const int i = 0;
であっても、ポインタ型へのキャスト結果は実装定義となる。
へぇ~ へぇ~ へぇ~ へぇ~ へぇ~
結局のところ、コンパイル時に 0 として認識するもの以外は null pointer への変換は保証しないってことなんだと思う。
ポインタ型へのキャストに対していちいち特別なコード(0と比較してその場合は null pointerにする)を生成せずに
済むようにしてるんだろうね。
intptr_t って環境依存だったっけ?
672 :
デフォルトの名無しさん:04/02/07 01:40
Cそのものじゃないんですけど、メトリクスを調べる方法ってありますか?
JAVAだったらEclipseのプラグインであるようなのですが、
CではぐぐってもLOCカウンターぐらいしか見つからなくて...
QACやRSMという商用を使えばある程度わかるらしいのですが、
お金がかかるのでGNUなどがあればうれしいです...
知りたいのは、LOC・経路複雑度・ステップ数 云々
メトリクスって子宮の事?
if文やswitch文の条件式がコンパイル時に決定するもの(定数など)なら
コンパイラが分岐のないコードを生成してくれることを期待しても良いですか?
期待はできるけど、
ふつうに条件分岐書いた場合、
決して呼ばれることのない部分のコードも生成されなくちゃいけないことになってるはず。
またその場合、警告が出る可能性が高い。
大きなコードが含まれるなら
プリプロセッサかC++ならテンプレートを使って
メタプログラミング的なことやった方が綺麗かも
>>673 メトリクスを大きく外れないレベルで説明しますと、
ソースコードを分析して、数値化する方法です
たとえば、
ある関数の経路複雑度が高いと
その関数のFullPathチェックが一般的にテストできるかどうかがわかったりします
要は読みにくいプログラムのどこが特にわからないかというものが理解できるので、
仕事では値が悪いところを徹底的にレビューしたりするんですよ。
等とまじめに答えるテスト
>決して呼ばれることのない部分のコードも生成されなくちゃいけないことになってるはず。
消されるよ。
>>675 というか,おっしゃるとおりに元はテンプレート使ってやろうとしてたのですが,
テンプレート引数の部分特殊化の壁にぶち当たるので,
その回避手段の一つとしてお聞きしたんです.
テンプレート使っても回避できるのですがいかんせんソースの見通しが悪くなるので・・・
>>677 みたいですね.さっきコンパイルしたら特に警告されませんでした.
アセンブリ読んだわけではないので確かなことは言えませんが.
>>675 て言うか、
> 決して呼ばれることのない部分のコードも生成されなくちゃいけないことになってるはず。
なんていいかげんな知識をどっから仕入れたんだ ?
>>675 > 決して呼ばれることのない部分のコードも生成されなくちゃいけないことになってるはず。
それって、処理系依存では?
最適化のやり方による、ということだと思ってました。
決して呼ばれることのない部分でもコンパイル時のチェックは行われる、
なら正解だと思うが。
>>576 Cは始めたばっかで、その関数の存在さえ知らなかった。
㌧クス。
>>586 おしっしゃる通り、昔から文字列と配列については苦手です。
もっと勉強します。
忠告㌧クス
684 :
デフォルトの名無しさん:04/02/07 12:28
multimap<int, string> map1;
multimap<int, string>::iterator iter1;
iter1 = map1.begin();
map1.insert(make_pair(1, "111");
cout << iter1->second << endl;
multimap<int, string> map1;
map1.insert(make_pair(1, "111");
multimap<int, string>::iterator iter1;
iter1 = map1.begin();
cout << iter1->second << endl;
下はうまく動くんですが、上はエラーになるのはなぜでしょうか?
ともに初期化していると思うんですが。
マップに要素が挿入されるまでメモリが確保されないからですか?
そのためmap1.begin();が正常に動かないとか考えたんですが…
>>684 簡単に言うとその通り。
multimapが空の時のbegin()が何を返すかちゃんと調べれ。
おまけに君はbegin()で得たiteratorはいつまでも使えて、
いつまでも先頭を指しているとか考えているような気がするが大丈夫か?
> 「オプションコンテキスト応答深度の上限を超過: 再帰をチェックしてください」
の、 bcc5.5.1 の人、英語版をインスコして上手く行きましたか?
僕も、まったく同じ環境で、やっぱり ブースカ使ってみたいのでつが・・・
それから、英語版の bcc がどこから持ってくるのか分からなくて・・・
>>684 一般的にinsert前のイテレータはinsert後に使用できる保証がない。
それはさておき、map1[1] = "111";でいいんじゃない?
>>687 よく見れ。multimap だから operator[] は使えないはず。
>>684 Effective STL を読むことをお勧めしておく。
ところで括弧の対応が取れていないのはコピペミス?
>map1.insert(make_pair(1, "111");
690 :
デフォルトの名無しさん:04/02/07 18:51
VC++.netを使って、コンソールアプリを作っているんですが、
stdoutをバイナリモードで開くにはどうしたらいいですか?
stdoutでファイルを出力しようとすると、0Aが0D0Aに自動変換されるので。
_setmode(_fileno(stdout), _O_BINARY );
cygwin の g++ 3.3.1 を使っています。
main()をライブラリに入れた場合はちゃんとうまくいくのですが、
WinMain()をライブラリに入れると_WinMain@16 が定義されていないというエラーが出ます。
○ライブラリ側 main.cpp
#define TARGET_WIN (1)
#if defined(TARGET_WIN)
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
... 引数の保存など ...
Main(); return 0;
}
#else
int main(int argc, char* argv[]) {
Main(); return 0;
}
を g++ -c main.cpp -o main.o; ar r libmylib.a main.o とし、
○アプリ側コード app.cpp
void Main()
{
}
を g++ -c app.cpp -o app.o とし、
最後にリンクしようとして
g++ app.o libmylib.a としています。
なぜWinMainはライブラリ内まで探しに言ってくれないのでしょうか?
どうしたらライブラリ内のWinMainをスタートアップにできますか?
よろしくおねがいします。
>>693 #include <windows.h>
してるか?
main関数内でstatic宣言した2次元配列をある関数に何度も放り込んでたら
勝手に一部の値が変化するのですが、staticの場合は値は保持されるんではなかったんでしょうか?
関数の詳細と、「勝手」の意味によるな。
つーか、main()関数内でstatic宣言ってのはローカルと生存期間は殆ど変わらないだろ。
>>697 二次元配列って書いてあるから、スタック溢れないようにするためだと思う。
>>694 しています。ここに例を示すために短くした時に省いちゃっただけで。
ないと HINSTANCE などが定義されていなくてコンパイル通りません。
よろしくお願いします。
スタートアップをWinMainにしてないだけだろ・・・
>>700 cygwinのgccは自動判別してしまうみたいなのです。
手動で設定できる方法があれば教えてください。
>>701 私も沢山ググったので空のmain()の定義というのはやってみました。
「空のmain()」という言葉の意味が理解できなかったので
int main(); // 宣言だけ
int main(){} // 中身が空
int main(int argc, char* argv[]);
int main(int argc, char* argv[]){}
のそれぞれは試したのですが、宣言だけだとリンクできないですし、
中身が空なら、たしかにリンクはできるのですが
WinMainを呼んでほしいのに定義した中身が空のmain()が呼ばれてしまいます。
ムリヤリ外部参照を生成したらどうだろう。
typedef int WINAPI WinMain_type(HINSTANCE, HINSTANCE, LPSTR, int);
WinMain_type WinMain;
static WinMain_type* const external_reference = &WinMain;
とか。
704 :
デフォルトの名無しさん:04/02/08 17:02
他で誘導してもらいました。
C言語での基本的な学習(ポインタ、構造体とか)は終わったつもりなんですが、簡単な二次元
のウィンドウ(例えば、Y=aX+bの直線)を表示させる方法がわかりません。
色々ググってたらOpenGLというのを見つけましたが、これを勉強すればいいんでしょうか?
OpenGLは3Dとかを作れるらしいですが、2Dを簡単に作る方法は他にないですか?
>>704 質問するなら
>>1 ぐらいちゃんと嫁。
> ただしその場合、質問者は必ず、環境を書きましょう。
>>705 すみません。。。
環境はWinXP Home コンパイラはBorland C++ Compiler 5.5です。
709 :
デフォルトの名無しさん:04/02/08 17:33
C++の文法は覚えたんですが、次に何を勉強したらいいのかわかりません。
W2K VC.NET2003(AC)
710 :
デフォルトの名無しさん:04/02/08 17:35
711 :
デフォルトの名無しさん:04/02/08 17:36
Windowsアプリケーションを作ってみたいです。
>>711 本屋に行って「VC.NETで作るWindowsアプリ」みたいな
タイトルの本を1冊買って来て、そこに乗ってるサンプルを
全部打ち込みで作ってごらん。
やってみればある程度目鼻が利くようになるし、
次に何を勉強したらいいかも見えてくる。
713 :
デフォルトの名無しさん:04/02/08 18:12
>>712 わかりました。
本屋でその手の本を買ってきます。
遅くなってしまいましたが
>>581 >>582 どうもありがとうございました。これでうまくいきました。
>>583 それも試させていただこうと思います。
どうもありがとうございますた(_O_)。
715 :
デフォルトの名無しさん:04/02/08 20:40
#include <stdio.h>
int reheight();
int main(){
int i,max=1,g,h;
float height[2];
for(i=0;i<2;max++){
scanf("%f",&height[i]);
height=reheight(height);
for(i=0;i<3;i++)
printf("%f",height[i]);
}
int reheight(float height){
inti,j;
for(j=1;j<3;j++){
for(i=0;i<3;i++){
if(height[i]=height[j]){
height[j-1]=height[j];
}else{
height[j-1]=height[i];
}
}
}
return height;
}
うまくいきません。お願いします。
for(i=0;i<2;max++){
717 :
デフォルトの名無しさん:04/02/08 21:13
#include <stdio.h>
int reheight();
int main(){
int i,g,h;
float height[2];
for(i=0;i<2;i++){
scanf("%f",&height[i]);
height=reheight(height);
for(i=0;i<3;i++)
printf("%f",height[i]);
}
int reheight(float height){
inti,j;
for(j=1;j<3;j++){
for(i=0;i<3;i++){
if(height[i]=height[j]){
height[j-1]=height[j];
}else{
height[j-1]=height[i];
}
}
}
return height;
}
少し省いて書いたので・・・
でもそこ以外でおねがいします。
if(height[i]=height[j]){
int reheight(float height){
return height;
int reheight();
そりゃあもう いろいろ間違ってるけど ガンガレ
i の forループの中でまた i 使ってる
悪いことは言わん、引き数にfloatを使うのはやめておけ。
723 :
デフォルトの名無しさん:04/02/08 21:53
間違えてるとこと指摘されるだけじゃわかりません。
①何が問題で②どうすればいいのかをお願いします。
>>722 なぜfloatの引き数だめなの?
>>723 自分で考える事しないと身につかないよ。
>>723 俺は考えた、多分有名なプログラマーの人は引数にfloatをつかわないってことだよ
この頃は流行らんが、
try & error
引数どころか、普通 float は使わないわけだが。
今時ハードウェアの制約がある場合以外でメリットないよ。
728 :
デフォルトの名無しさん:04/02/08 22:47
実数使うのにfloat使っちゃ駄目ですか?
doubleにしとけ。15年前からそう決まってる
まぁ、配列使ってるのに引数が配列じゃなかったり、
プロトタイプ宣言と引数のリストが違ってたり、
戻り値にint指定しときながらfloatの型を返そうとしたり、
if文が比較演算子でなく代入演算子使ってたり、
そもそも何をするプログラムかすら説明しようとしてないくせに
他のスレに丸投げするようなヤツを助ける気になんか
ならんということだ。
世の中なめんなってことだな。
>>731 本日付で2ちゃんねるで一番優しい男だからな。
あと30分で終わるが。
733 :
デフォルトの名無しさん:04/02/08 23:30
#include <stdio.h>
float reheight();
int main(){
int i,g,h;
float height[2];
for(i=0;i<2;i++){
scanf("%f",&height[i]);
height=reheight(height[2]);
for(i=0;i<3;i++)
printf("%f",height[i]);
}
float reheight(float height[2]){
inti,j;
for(j=1;j<3;j++){
for(i=0;i<3;i++){
if(height[i]<height[j]){
height[j-1]=height[j];
}else{
height[j-1]=height[i];
}
}
}
return height;
}
こう?でも動かない。
ifはただのミスです。
734 :
デフォルトの名無しさん:04/02/08 23:49
>>718と
>>721はただのミス。
>>719と720は同じことを指摘してるんですよね?
>>719のreturnは?
>>730 身長を入力。height[x]へ順に格納。関数へ。height内部の比較入れ替え処理。結果をmainへ。
printfでheight[x]を表示。
736 :
デフォルトの名無しさん:04/02/09 00:43
fopenして数値を読み書きするのはfgetcじゃ駄目なんですか?
どう読み書きしたいんだろうか。
とりあえず関数を列挙しとくので、
あとは好きにして頂戴。
fprintf, fscanf, fgets, fgetc, fread, fwrite
>>667-668 >>670 遅レスすまそです。やはりそういうことになってましたか。
確かに値が 0 の場合に限って、キャストが無くても
コンパイル通りますね < C++
さんくすでした。
739 :
デフォルトの名無しさん:04/02/09 01:02
>>737 調べたらどうもやりたいことはfscanfで出来そうです
ありがとう
#include <stdlib.h>
int main(){
char *p = malloc(1000000);
p = realloc(p,10);
while(1) ;
}
というコードを実行して psでメモリ使用量を見るとたくさんメモリを使っています。
reallocの行を free(p)にするとメモリ使用量は減ります。
そういうもんなんでしょうか。それともたまたまですか?
そういうもんですが、必ずこのようになるわけではありません。
小さくするreallocは、何もしないでそのまま返すって実装も多そうだね。
中身をコピーしなくて済むから。
>>741 結局たまたまってことですか?
メモリ使用量が減るのを期待して mallocしてデータ移して freeするのは
愚かなことでしょうか?
>>742 gcc 2.95ですがポインタの位置は変わっています。
ある程度以上でかい領域なら普通はプールしないだろうが、
「free/deleteがOSにメモリを返却するとは限らない」
ってのは有名な話。
>>745 malloc するサイズを大きくしていくと、プールしなくなる前に NULLが返ります。
747 :
デフォルトの名無しさん:04/02/09 02:40
どっかで見たんですが
char a[3] = "abc";
この宣言で、aの配列には3文字入ってnul文字は付加されないと書いてあったんですが、
僕は「文字列を入れてるんだから無理やりa配列の4番目にnul文字は付加されるだろ」
と思ったんですが。
その付加されない理由とは、宣言の時だからでよろしいんですか?
配列にアクセスするときって普通にメモリ破壊が起きますよね。(ポインタでアクセスするから)
つまり上の例は宣言の時だからメモリ破壊が起きずnul文字が付加されないってことですね?
領域が3つしかないのに、4文字入るわけないだろ
まぁそうやね。
代入と初期化は別物ってことだ。
750 :
デフォルトの名無しさん:04/02/09 06:42
>>747 >その付加されない理由とは、宣言の時だからでよろしいんですか?
違います。
enum Hoge { mona, giko, zonu };
と定義されている列挙型を
enum Hoge { mona, giko, zonu, kusakabe };
というように値を追加したいのですが、このような事はできるのでしょうか?
列挙型Hogeを含んだクラスを機能拡張のために継承したいのですが‥‥
752 :
デフォルトの名無しさん:04/02/09 14:40
STLのstringに入ってる文字列の,最後の1文字だけを削除したい場合は,
どうやったら良いんでしょうか.なんか,eraseとかあるようですが,イテレータが・・・
>>752 ちゃんとものしゃべれよ、この引き篭もり!
>>752 std::string hoge="hogehogehoge";
//size_typeで指定
hoge.erase( hoge.size()-1, 1 );
//イテレータで指定
hoge.erase( hoge.end()-1 );
俺もどこかのスレで読んだ。char配列のサイズと、初期化子の文字数
(除・ヌル文字) が一致するときは、ヌル文字を無視して初期化するらしい。
実際コンパイラもエラーにしないんだよね。さすがに char s[3] = "abcd";
だとエラーになってしまいますが。ただの文字配列として初期化して、要素が
余ったときにその最初の要素にヌル文字をセットすることにでもなって
いるんではなかろうか<規格
vc6だと
char abc[3] = "abc";
error C2117: 'abc' : 指定された配列には、初期化子が多すぎます。
でました。怪しいことできませんでした。
もともと自動変数以外は0に初期化されるから
余った部分は全て0になるでしょう
762 :
デフォルトの名無しさん:04/02/09 17:42
>>754 有難うございます.
イテレータが何たるものかあやふやな理解だったために,
誤解していました.
> //size_typeで指定
> hoge.erase( hoge.size()-1, 1 );
こんな記述もあるんですね.
こっちの方が簡単でした.
有難うございました.
構造体のソートが出来ん・・・
なんか猫みてて一日一章づつ進んで行ってるんだけど
次の日には前にやったやつわすれちゃってさー
俺って猫以下なのかなー
>>765 それだけだったのか、とそのままやってみたが、Cだとプリコンパイラ済みヘッダ使えないのかな?
互換性が無いよ云々いわれてしもうた。
とりあえず、
>>758 通りましたわ。
Cって怖いな。
>>765 いやあ、自力でソート関数作ろうと思ったけど、構造体そのものの
理解が足りんようです
ご親切にどうもありがとう
>>768 構造体のソートは、ただ単純に、比較するメンバの優先順位を決めて
優先順位の低いメンバから高いメンバへの順で一回ずつソートして行けばOK
まぁ、速度を必要とする時は、駄目だけど…
毎回ソートしなくても、比較を複数回やればいいじゃん
borlandC++コンパイラ5.5で2Dゲーム作ろうとしてるんですが、
directX SDKとwin32API、どっち使うのがおすすめですか?
というか、directSDK=win32API?
>>773 何から伝えれば良いのか、分からないまま時は流れて
浮かんでは、消えて行く、ありふれた言葉だけ
776 :
デフォルトの名無しさん:04/02/09 20:49
>>773 yaneSDK3を使えば。
俺は使わないけどな。
もしくは、EL.Hを使うべし
俺はこっちな。
Allegroだろやっぱ。
週末、職場に缶詰だったので随分間が空いてしまいましたが
>>703 思いつかなかったです!なんとご教授いただいた方法でちゃんとリンクできました!
ありがとうございます。
ただ…当初の目的が
ソースがWinMainとかで機種依存な状態になるの嫌だな。という所なので、
できればアプリ側(非ライブラリ側)にそういう情報を入れたくないのですが、
何かよい方法はないものでしょうか?
>752
pop_back()じゃだめ?
>>782 GNU ldの、リンクする・しないを決めるのが.oファイル単位になってる実装を利用すれば、
>>693のmain.cppに
void dummy(void){}
を追加して、アプリ側のソースで
void dummy(void);
static void (* const external_reference)(void) = &dummy;
これでいけそうな気はする。
str.resize(str.length()-1);
C++でWindowsプログラムを作りたいんですが、
何から始めたらいいのでしょうか・・・
やっぱり参考書とかですかね?
>>787 おまいはどの程度の知識を持っていて、何がやりたいのか?
C/C++の知識は0に等しいです・・・
DirectGraphicsとかDirectSound、
ゲームよりのプログラミングが学んでみたいです。
やっぱり、まずは基礎ですよね・・・
>>787 そら、英文法しらんで英作文は出来んだろ。
ゲーム作るったら英語で小説書くようなもんだぞ。
>>789 DirectX使うならC++もさらりとやったほうがいいかもしれんが
とにかくCをマスターしろ。C++はその後だ。
>>788,790,791,792
分かり易いレス有難うございます。
C→C++→DirectXですか・・・
まずはCをマスター出来るよう頑張ります。
795 :
デフォルトの名無しさん:04/02/10 07:23
配列の初期化で質問なんですが、
const CRect rcStatic[2];
これを初期化したいのですが、どうやったらいいのでしょう?
CRectはMFCのクラスです。
const CRect rcStatic[2] = { CRect(0,0,10,10), CRect(10,10,20,20,) };
これはコンパイルエラーでした。
>>795 const CRect rcStatic[2] = { CRect(0,0,10,10), CRect(10,10,20,20) };
すいません。これで通りました。
797 :
デフォルトの名無しさん:04/02/10 08:20
set_new_handlerのテストをしようと思い以下のプログラムを実行すると固まってしまいました。
void noMoreMemory() {
cout << "memory error\n";
abort();
}
int main() {
set_new_handler(noMoreMemory);
int *pBigDataArray = new int[100000000];
cout << "ok\n";
}
固まらないようにしてnewのメモリ確保の失敗をテストする方法はないでしょうか?
環境はWin2000+VC++.NETです。
普通固まらんが。
スワップ中とか?
>>797 abort とはこりゃまたきついな。
C++ なんだから素直に throw しちゃいなさい。
あと、何で endl 使わないの?
それと、多分 100000000 くらいなら確保できちゃうんじゃない?
多分、そのメモリを 0 で初期化するのに時間を食って
固まってるように見えてるんだと思う。
>>799 100000000*sizeof(int)
が何MBか計算してみろ。
実メモリなくたって1GBでも確保できるが・・・
>>757 #include <stdio.h>
int main(){
int i;
char a[3]="abc", *ptr;
ptr=a;
a[4]='d';
for(i=0;i<=4;i++){
printf("&a[%d]=%d\n",i,ptr+i);
printf("a[%d]='%c',%d\n",i,*(ptr+i),*(ptr+i));
}
return (0);
}
この例だと、NULLは無視されないよ。無理やり、a+3に書き込む。
804 :
デフォルトの名無しさん:04/02/10 14:21
合意の上でないとね。
>>802 a[4]への代入は遊びだな(w
少なくとも
>char a[3]="abc"
とやってしまうと、a[3]にNULLが入るから、
>>747の言ってる事は間違っていないと。
スマソ。処理系によって違ってた。
vc7.1だとa[3]=0だけど、gcc/linuxだとa[3]=不定。
>>798-801 単にスワップしてただけだったみたいで(?)しばらく待ってたら無事エラーを出してくれました。
ありが㌧。
ところでgoogleで検索すると妙にset_new_handlerについての記述が少ないのですが
普通はnewの失敗に他の方法をとるのでしょうか?
ライブラリの参照のときによくbohyoh.com参照してたのに、気が付かなかった。
vcは規格からわざとはずしてあることになるのかな?
確率としては低いかもしれないけど、破壊する可能性があるし。
>>810 bad_alloc が発生するような環境でそのプログラムを使用しない・・・。
要は放置・・・。と上司が申しておりますタ。
アプリの性質によるだろうけど。
>>806 >>char a[3]="abc"
>とやってしまうと、a[3]にNULLが入るから、
入らんって
vc7.1だが、丁寧に'フ'が入ったぞ(デバッグビルド)
>>806 そもそもa[3]へのアクセスは未定義でしょ。
どんな値で初期化されるなんて問題じゃない。
>>818 そういう問題なのかな?
プログラムが大きくなってくれば、a+3がどっか別で割り当てたところを指す可能性はあるんじゃないの?
だから、それも含めて未定義なんだよ。
>>784 感謝!WinMain自体じゃなくても同じオブジェクトファイルの中身を使っていれば
ちゃんとリンクできました!!
せっかくなのでダミーではなくvoid Mainをクラスの仮想メンバにして
そのベースクラスをWinMainと同じオブジェクトファイルに入れて
ちょっとエレガントな感じになったりして。
みなさん本当に感謝です。
>>816 >>char a[3]="abc"
>とやってしまうと、a[3]にNULLが入るから、
と書いている以上、
int main( void )
{
char a[3]="abc";
return 0;
}
でどういうコードが生成されるかを見るべき。
a[]の領域は 0~2 の 3 つしか確保されていない以上、
a[3] の値をデバッガや printf() で表示しても無意味。
VC++ は多分 a[3] を4バイトで確保して(sizeof a は 3 だけど)、
0x00636261 を mov してるよ。
昔文字列をそういう風に初期化してるコードを生成してるのを見たことがある。
そうなってるのは勘違いによるバグを防止するためだろ
実装がそうだからといってa[3]にアクセスしていいとは言わない
勘違いによるバグを防止するためではないと思うが。
単に4バイトに達してない部分が 0 で埋められてるだけで、
char a[4] = "abcd"; だったら多分 VC++ でも a[4] に 0 は入んないよ。
>>822 >>a[]の領域は 0~2 の 3 つしか確保されていない以上、
>>a[3] の値をデバッガや printf() で表示しても無意味。
「確保されてないから無意味」というのは意味がわからん。
a[3]=*(a+3)なので、a[3]の領域に何が入っているかは確認できるだろう。
a[3]の値に意味が無いというのであればその通りだが。
で、a[3]の値だが、これは不定が正解だろう。
ANSI Cでは文字列リテラルは定数ではなくて静的な配列で、この文字列
に対する変更は未定義。
*p = "abc";
*(p+1) = 'd';<-鼻から悪魔が出てもおかしくないコード
しかし、ローカルの配列の初期化子として使用した場合は、
ローカル配列にこれらの内容がコピーされるので
s[3] = "abc";はs[3] = {'a', 'b', 'c'};と解される。
もちろんs[1] = 'd';も問題ない。
K&Rのころは多分コピーしてなかったはずで、
static char s[] = "abc";
と書かないとエラーだった。
>>825 俺も書いた後そう思ったが、
確実に'\0'が代入されたとしても、そうなっているのは~
と読み替えてくれ
Linux 上 で gcc-2.95.4 を使っています。
#include <stdio.h>
int main(void)
{
extern char *__progname;
printf("%s\n", __progname);
return 0;
}
上のようなコードで結果は実行ファイル名を表示します。
*BSD 方面では割と使われているみたいなのですが、
この __progname というのは、やはり環境依存なんですよね?
どれくらい移植性があるんでしょうか?
>>826 >a[3]=*(a+3)なので、a[3]の領域に何が入っているかは確認できるだろう。
標準Cに従うのなら、見る事自体が未定義。
char a[3];
でa[3]を読み書きするのはNGで
ptr == (a+3) はOKなんだっけ?
ok
デリファレンスしたらNG
>>826 > で、a[3]の値だが、これは不定が正解だろう。
未定義が正解。
>>829 の言う通り、「見るだけ」でも鼻から悪魔が出てくるかもしれない。
833 :
デフォルトの名無しさん:04/02/11 15:03
C言語でたとえば下記のような構造体
struct {
long a;
short b;
char c;
};
を作ると、メモリイメージは
-------------------
a用の4バイトの領域
b用の2バイトの領域
c用の1バイトの領域
-------------------
となると思うのですが、
(構造体アラインメントが1バイトの場合)
C++でたとえば下記のようなクラス
class {
public:
int test(int x);
long a;
short b;
char c;
};
を作った場合、メモリイメージとしてはどのように なるのでしょうか?
(というか、クラスのインスタンスの中で、メンバ関数はどうやって保持されて、
どうやって呼び出されるのでしょうか?)
どなたか、教えてください。
834 :
デフォルトの名無しさん:04/02/11 15:08
ビット演算子はいつどういうときに使うんですか?
>>833 メンバ関数はインスタンスごとに保持されるわけではない。
メンバ関数には、普通、呼び出しに使われたオブジェクトへのポインタ(this)が暗黙に渡される。
関数内でメンバmをあらわすのにthis->mとかけるのはこれを反映している。
836 :
デフォルトの名無しさん:04/02/11 15:20
Windowsでゲームを作っているのですが、ちょっと困っています。
ゲーム画面を描写するためのウインドウが別のプログラムの管理するウインドウの
下に完全に隠れてしまうと、何故かは解りませんがシステム全体の応答速度が
極度に劣化するため、ゲームのウインドウが別のウインドウに隠れたとき、画面の
更新を行わないようにしたいのですが、なかなか良い方法が見つかりません。
今のところ、ゲーム画面からフォーカスがはずれたときPauseをかけるよう
プログラムを設定していますが、これではモードレスダイアログボックスの
動作に影響がでてしまいます。
ゲームクライアント領域に別のウインドウのクライアント領域が重なっているか
調べるよい方法はないでしょうか?
>>835 > メンバ関数はインスタンスごとに保持されるわけではない。
おいおい、仮想関数って知ってるか ?
> メンバ関数には、普通、呼び出しに使われたオブジェクトへのポインタ(this)が暗黙に渡される。
> 関数内でメンバmをあらわすのにthis->mとかけるのはこれを反映している。
意味わからん。
(説明は正しいが、メンバ関数の保持とどう関係あるのかがわからんと言う意。)
>>833 vtbl, vptrで検索してみると判るかも。
>>837 仮想関数でも、インスタンスが持っているのはvtblへのポインタだけじゃないの?
>>837 >おいおい、仮想関数って知ってるか ?
単にメンバ関数といえば非仮想関数の事だと思っていたが。
>>833の例だって仮想関数じゃない。
それに仮想関数だって(典型的な実装では)インスタンスごとに関数ポインタテーブルへの
ポインタを持つだけで、決してインスタンス単位で関数を保持しているわけじゃない。
>意味わからん。
>(説明は正しいが、メンバ関数の保持とどう関係あるのかがわからんと言う意。)
(非仮想)メンバ関数の仕組みについて
>>833が誤解しているように見えたから、
どういう仕組みでメンバ関数が実装されているか情報を提供しただけだ。
質問への回答としては一行目だけで十分だったかもしれん。
841 :
デフォルトの名無しさん:04/02/11 16:43
普通のCのコンパイラってリンクするとき動的リンクですか?静的リンクですか?
たいていは動的リンクと書いてると思うんですが。
もし動的リンクの場合、関数などの情報を持ったオブジェクトファイルはプログラム実行時にリンクされますよね。
それで、実行可能ファイルを作って、それからオブジェクトファイルのフォルダを違う位置に移動した場合、
そのプログラムはオブジェクトファイルの場所が分からないですよね?(タブン)
でも普通に実行可能ファイルは実行されました。これはなぜなんですか?
静的リンクをしているということですかね?
(僕はBCCを使用しています)
>>841 なにかとてつもない勘違いをしているような気がする。
>>841 言いたいことはわかる。
安心しろ。普通は静的リンクだ。
>>842>>843 普通は静的リンクなんですか?
それだったら安心しました。
僕の本にはたいていのコンパイラは動的リンクをするというようなことを書いてあったから・・。
>>844 但し標準ライブラリなどは DLL の使用がコンパイラの標準設定に
なっていることが多い。
そういう場合はコンパイラやリンカのオプションで対応する事。
構造体とファイル操作の練習してます以下のようなプログラム組んで、
onamae.txtの中に入ってる
ABCを構造体に入れて表示させると
NAME...ANAME...
NAME...BNAME...
NAME...CNAME...
となるんですが、なぜかどなたか教えてもらえませんか・・・
#include<stdio.h>
#include<string.h>
typedef struct RankData{
charname[5];
doublescore;
}RankDataType;
int main(void)
{
RankDataTyperank_data[100];
FILE*name_fp;
FILE*score_fp;
inti=0;
intk=0;
charbuf[4];
name_fp=fopen("namae.txt","r");
for(i=0;fgets(buf,4,name_fp)!=NULL;i++)
{
strcpy(rank_data[i].name,buf);
printf("NAME...%s",rank_data[i].name);
}
return 0;
}
>>845 >となるんですが、なぜかどなたか教えてもらえませんか・・・
そういう風にプログラムが書かれているからだろ?
>>844 > 僕の本にはたいていのコンパイラは動的リンクをするというようなことを書いてあったから・・。
その本の名前を晒せ。
なんとなくポインタが分かった気がする、&でアドレス取って*で受け取るん
だろ?
配列関係のルールがメンドイだけだじゃないの?
ポインタが解った気がする、ってのが一番ダメ。
「気がする」ではポインタを使わないでください。
後処理大変なんです。
じゃー全く分からないに変更します(´・ω・`)
>>835 つまり、メンバ関数とメンバ変数は全く別の管理であり、
メンバ関数は、通常の関数(非メンバ関数)+thisポインタ
と考えていいんでしょうか(もちろんクラス外から呼び出せない)?
仮想関数の場合はvtblというテーブルを使って関数を
探してくるみたいですが・・・?(838さんありがとうございます)
この辺がようわからんのよね~、C++は。。。
俺もわからんー。
普通に構造体に関数ポインタ入れるのと同じじゃねえの?
sizeofで関数が要するコードのサイズが出たら笑うよな。
んで、そのメンバ関数の中では暗黙に渡されるthisポインタにより
メンバ変数を参照出来ると。
アセンブリ吐かせてみるのがお勧め。
A::func(int a,int b);
というのがあったとすると、
A::func(A * const this,int a,int b);
と呼ばれている、というように考えておけばいいのかな。;
最後のセミコロンにワロタ
861 :
デフォルトの名無しさん:04/02/12 12:11
ポーカーを作っているのですが、役のデータをどこに置けばいいか教えてください。
ユーザーがいじりやすいよう、グローバル構造体みたいにしたく、
マクロなんかと同じようにヘッダファイルに置いていたのですが、
複数から呼び出すとデータが重なるらしくエラーになります。
関数に入れておいて、使いたい時に引数で持ち帰る方法もあると思いますが、
何かパッとしません。
const YakuStruct Yaku[YAKU_SUU]=
{
{"ブタ" ,{0,0,0,0,0,0},{0,0},0,0},
{"ワンペア",{0,0,1,0,0,0},{0,0},0,0},
{"ツーペア",{0,0,2,0,0,0},{0,0},0,1},
{"スリーカード",{0,0,0,1,0,0},{0,0},0,3},
{"ストレート",{0,0,0,0,0,0},{1,0},0,6},
{"ロイヤルストレート",{0,0,0,0,0,0},{0,1},0,6},
ヘッダにはextern付きで宣言だけ入れて
本体のデータはcのソース一箇所だけで定義する
>>862 コンパイルは出来ましたが、includeしていないファイルでは
使えませんでした。
//Main.c
#include "YakuData.h" //ここに存在している
#include "Card.h"
#include "Yaku.h"
こういう感じに入れて、Card.cで使うと定義されていない識別子と出ます。
だからインクルードして使うんだって。
externつければ複数で読んでも大丈夫。
実際に定義するところではexternはじゃまかもしれん、
そのときは#define使って見えないようにする
そのうちこんなやり方はしなくなって関数経由になると思うけどな
>>864 externの使い方を間違えていたみたいです。
本にチラッと乗っていたので呼んでみたのですが
新しい領域をなんたらとか全然分かりませんでした(^^;。
ただ、staticを使うと同名のグローバル変数を使えると書いてあり、
それでやったら、最初に書いた使いたい.cごとにインクルードして使う
やり方が出来ました。重くなったりしてしまうかもしれませんが。
>そのうちこんなやり方はしなくなって関数経由になると思うけどな
mainでYakuStruct yaku[YAKU_SUU]を宣言して、
GetYakuData(yaku);でデータを得て、
ShowYaku(yaku)やCheckYaku(card,yaku);みたいに使うときに
引数にするという感じで良いのですか?
#ifdef _MAIN_C_
const YakuStruct Yaku[YAKU_SUU]=
{
{"ブタ" ,{0,0,0,0,0,0},{0,0},0,0},
{"ワンペア",{0,0,1,0,0,0},{0,0},0,0},
{"ツーペア",{0,0,2,0,0,0},{0,0},0,1},
{"スリーカード",{0,0,0,1,0,0},{0,0},0,3},
{"ストレート",{0,0,0,0,0,0},{1,0},0,6},
{"ロイヤルストレート",{0,0,0,0,0,0},{0,1},0,6},
};
#else
extern const YakuStruct Yaku[YAKU_SUU];
#endif
>>865 static は確かに動作するが、インクルードしたそれぞれに
実体ができてるので注意。まあconstなら悪影響は無いかもしれんが
書き換える場合、いくら変更しても別の場所からは変わって無いと言う事態に…
>>866 ありがとうございます。ただ条件付コンパイルはまだ理解していないので
勉強して試させていただきます。後、コンパイル、スコープなどを
余り理解していないみたいなので、もう少し勉強します。
>>862>>864>>866 お答えいただきありがとうございました。
>>867 なるほど。分かりました。static const YakuStructで行きます。
ありがとうございました。
870 :
デフォルトの名無しさん:04/02/12 14:40
コピーコンストラクタはどういうときに必要になるんですか?
いまいちよくわからないのですが。
暗黙のコピーコンストラクタ(メンバのコピー)ではまずいとき
>>836 >ゲームクライアント領域に別のウインドウのクライアント領域が重なっているか
>調べるよい方法はないでしょうか?
Win32APIなら、GetUpdateRgn によって、一部の領域が他の
ウィンドウに隠されているかどうかが解ると思う。実際に使ったことはないが。
>>870 class Hage
{
Hige* m_hige;
public:
Hage() : m_hige(new Hige()) {}
virtual ~Hage() { delete m_hige; }
Hage(const Hage& hage) : m_hige(new Hige(hage.m_hige)) {}
...
};
とか
class A{
public:
void say(){ cout << "A::say()" << endl; }
void say(int n){ cout << "A::say(int)" << endl; }
};
class B : public A{
public:
void say(int n){ cout << "B::say(int)" << endl; }
};
int main(int argc, char* argv[])
{
A a;
B b;
a.say();
b.say(); // error (undefined)
a.say(1);
b.say(1);
}
gcc 3.2.2@redhat9.0で上のコードをコンパイルすると
b.say()が未定義といわれます.
B::say(int)だけを定義するとB::say()が未定義になってしまうようなのですが
これはC++の仕様でしょうか?
仕様でそのように決まっております
はい...そのようですね.さきほど調べました.
要するに非仮想関数は再定義するな,ということですね.
ありがとうございます.
いや、別に再定義してもいいと思うが…
█
むしろ漏らさず再定義しろと
>>809訂正。かなり亀レスだけど訂正。「ポカーン」とか「そんなものは誰でも知ってる」とか言われそうだけどとにかく訂正。
>だから"abc"は{'a','b','c','\0',}の簡易表現(シンタックスシュガー)だということで、'\0'の領域はないから捨てられてたんですね。
おもいっきり上に貼ってあったリンクと矛盾してましたね。
ちがいますね、"abc"は{'a','b','c',}の簡易表現(シンタックスシュガー)ですね。
nul文字は配列に空きがあったら入れるんですね。
>>882 ん、なかなか見所のあるヤシ
そのくらいこだわった方が身についてよろしい
>>882 それで char a[] = "abc"; の時に '\0' が入れられることを説明できるのか?
>>882 char s1[]={'A','B','\0'},s2[]="AB\0",s3[]={'A','B'},s4[]="AB";
printf("%d %d %d %d\n",sizeof(s1),sizeof(s2),sizeof(s3),sizeof(s4));
↑を実行すれば解かると思うけど、実際には、
>>809の考え方で良い
>>884 いや、'\0'が入らない理由を言ってるんです。
>>885 char s1[3] = "abc";
char s2[3] = {'a','b','c','\0'};
これはs2がエラーになりますよ(初期化子が多いという)。
その要素数のない配列のメモリの取り方がよく分からないですね。
僕の本には「[ ]を使った場合、初期化子の数を見て要素数を決める」と書いてあるんですが、
s4[]="AB";の場合だと、2個分のメモリ領域を取ると思うんですが、さらに空き領域がある場合は'\0'を追加する
と決めてあるんですかね・・・。
>>886 >s4[]="AB";の場合だと、2個分のメモリ領域を取ると思うんですが
'A'、'B'、'\0'の3文字
"abc" は配列の初期化の際には { 'a', 'b', 'c', '\0' } のシンタックスシュガーのようなものであるが、
'\0' の入る領域が用意されていないなら { 'a', 'b', 'c' } のシンタックスシュガーとして機能する、
ということで十分だろ?
889 :
基本的なところで詰まった:04/02/13 14:18
char s[256];
printf("パスを入力してね\n");
fgets(s, 256, stdin);
fopen(s, r);
と、fopenを使ってファイルを開こうとしてるわけですが、
これをWindows環境で実行すると、パスを"\"で入力した場合に問題が出てきますよね。
これを解決する、もっともビューティフルな方法って何がありますかね?
なにこの質問・・・ AA(ry
889はとてつもない勘違いをしていると思われ
>>889 藻前は「'\n'→改行」の変換は実行時に行われていると思っているのか?
894 :
デフォルトの名無しさん:04/02/13 16:39
また蒸し返してごめん、初心者なんですが、
>>885のsizeof(s2)の値が
なんで4になるか分からないです。誰か教えてちょだい。
'A','B','\','0','\0'で5になるか、
'A','B','\0'で3になるかどっちかかと思ったんですけど。
なんでその中間が思いつかないのか
"AB\012"は何文字かとか理解できてないんじゃないか?
あ、\の後の文字がエスケープシーケンス文字になる場合って、\と強制的にくっついちゃうんですか?
そしたら
>>896の前者は没で、
ほんで、文字列を初期化で代入するときは、
もうすでに\0がついてるとかは関係なく、絶対に\0は付加される?のですか?
?????????????????????????
#include <stdio.h>
#include <string.h>
main()
{
char s[] = "AB\012";
printf("%d, %d, %s\n", sizeof(s), strlen(s), s);
}
ってやったら4, 3, AB と出てきてますます訳が分からなくなりました;;
>>900 strlen が \0を文字列の区切りとして見なすから、
\0 以降の文字をカウントしないだけ。
勘違いゴメソね。
\012 は8進数だから改行コード
>899
強制的にくっつかなかったらどうやってエスケープするんだ?
だから\文字がほしいときは\\にするんだろ。
"\012"は'\0' ,'1', '2' じゃ無いよ。
\と0から始まる数字で8進数値を表す。
"\0"は"\00"や"\000"と同じ。
末尾の"\0"は絶対に付く。ヌル文字も文字のうち。
>894ぴくりともしないな。頭パンクしたんじゃなかろうか…。
>872
情報提供ありがとうございます!早速調べてみます。
894は無事に理解できたんでしょうか?
「FTP」というリンクをクリックしてダウンロードして実行してインストールしてコンパイルして回線切って氏ね
マシンスペックありあまってるならC++BuilderXのほうがいいぞ。一応GUIだ。一応。
クリックしても何にも起こんないか、
エラーが出るかのどっちかなんだよ。
こんだけ考えても いまいち分からない私は もうこの道は 諦めたほうがいいnでしょうか。
>"\012"は'\0' ,'1', '2' じゃ無いよ。
>\と0から始まる数字で8進数値を表す。
>"\0"は"\00"や"\000"と同じ。
ここが。全然。特に3行目が。ごめん、みなさん。
今ちょっとピンときて、
printf("Hello\156World\0x6EGoodBye\n");
ってやったらHellonWorldと出てきちゃいました。全然ひらめいてなかった。
\0x6Eを\x6Eに直してやってみそ
HellonWorldnGoodByeになった!なんで改行されないんでしょう?
\nと\156と\x6Eは違うということですか?
\nは\x0Aだ
>>915 ASCII文字コード表を小一時間眺めてみれば?
えええ?
\0は\+000(エスケープシーケンスの0番目)ってことではない・・・のですか・・・?
んだから\+nで改行のエスケープシーケンスになるかと思って。
ホントに泣きそう・・・というかいい加減私ウザイですね・・・、ごめんなさい。
何気に2/8/10/16進変換はWindows標準の電卓が便利だったりする。
'\n' '\t' '\a' '\0' '\x31' 等は、
'A' 'a' '0' '$' '@' 等と同じく、「1文字」なのよ。
改行文字がソース上で表せないから、便宜上「\」マーク+記号で特殊な文字を表してるだけで。
int main() {
char s[] = "Hello world.\nGood bye.\n"
"\nは\\nじゃないよ\n";
int i;
printf("%s", s);
for (i = 0; i < sizeof(s); ++i) {
printf("%02.2d ", s[i]);
}
}
>>918 >\0は\+000(エスケープシーケンスの0番目)ってことではない・・・のですか・・・?
違います。
「\n」は改行(文字コード:0x0A)文字にエスケープする。
「\000」は「\」の直後の「0」以降の数字を8進数とみなし、
1バイトのコードにエスケープする。
つまり、「\000」は8進数の0を示す。
もちろん、「\0」以降は0~255までを示す8進数字ならなんでもいい。
なぜ八進数を用意したのだ?
二進と十進の方がよいのに。
chmod(filename, 0755);
>>921 実行結果を見て、最初の\nのところで、
「なんで92って出ないんだ!?」って思ったのはやっぱり勘違いしていたからですね・・・
\0や\nはそれ自体が1文字として別にあるんですね・・・勉強になりました。
>>922 あー、だから\156でnが出てきたんですね!
>>920や今までのを見て、やっとみなさんがおっしゃる8進数という意味が分かりました。
うれしい・・・。
みなさんこんな私に愛想を尽かさず、丁寧に教えて下さって本当にありがとうございます。(TT)
こんどは感動で涙が出そうです。感謝の嵐です、本当に。ありがとうございます!ありがとうございます!
7時間半に及ぶ感動のお勉強劇・・・ステキ
>>919 人のマシンでこの電卓が関数電卓になってるかどうかで
使ってるかどうかわかるんあ
Windows の電卓って、意外と高性能なんだよな。
32 桁までいけるし。
ポインタと配列の違いとはどういうことでしょうか?
>>931 AWK をラップして使ったんでいい肝。
2進が使えないけど。
Windows の電卓は数式をペーストできるので、
計算したい式をどこかで編集してペーストするのも便利。
>>934 ありがとうございます、
そのページを読んでみます。
STLのイテレータで質問なんですが、これって
コンテナの再配置(挿入したり削除したり)が
行われた後でも有効なんでしょうか?
それともやっぱ無効になっちゃいますか?
複数のスレッドからvectorにアクセスするプロ
グラムを書いているんですが、アクセスする
たびにコンテナの先頭からの相対位置で指定
しないといけないのかな?
無効になる。
>>936への>937に対するどうでもいい補足
vector限定なら、予めreserveした領域はinsertしてもそのまま使える。
また、insertしなければ(当然)そのまま使える。
eraseした場合もeraseした要素より前の要素についてはそのまま使える。
再配置後、イテレータが無効になるのはvectorだけじゃなかったけ?
deequeも無効になったけか?
とりあえず、setとmapは保証されてたような・・・。
set と map は再配置しないし...。
>>941 すまん、なんか勘違いしてるからつってきます。
>>923 > なぜ八進数を用意したのだ?
カーニハンとかが使ってたミニコン (ミニコンポじゃねーぞ) の PDP7 とかの機械語が 8 進数ベースだったから。
ちなみに、C 言語はそれ以外にも printf("%d\n", 010) とやると 10 と出力されないとか、8 進数基調のところがいくつか見られる。
>>943 >010) とやると 10 と出力されないとか
こういうのは8進数基調というより、単に8進数を扱いやすいだけというべきだよな。
>>944 扱いやすいだけなら、0o277 とかで充分だと思うけど。
ついでに、0b11111111 とかも用意してもらえたらよかったのに。
946 :
デフォルトの名無しさん:04/02/14 14:26
再帰関数の再帰って英語で何だっけ?
recursive かと思ったんだけど、辞書に載ってなかったので。
>>947 どうもです。
研究社の新英和中辞典にも載ってないってことは
結構専門的な言葉なのかな。
recurse でも載ってない。
951 :
デフォルトの名無しさん:04/02/15 11:14
BorlandC++Builder使ってます。
TObjectを継承したクラスAを作ろうと思うんですが…うまくいきません。
デストラクタが基本クラスTObjectと矛盾すると言われてどうしてもうまくいかない
のです。
なぜなんでしょう?どなたが教えてください
どなたさん、ご指名ですよ。
どなたさん、ご足労ありがとうございました。
自己解決しましたので
955 :
デフォルトの名無しさん:04/02/15 20:42
関数の戻り値で2つ以上の値を返す事ってできないんですか?
int hoge(){
int a,b;
...
...
...
return a,b;
}
みたいな感じなんですが。
int hoge(){
int a,b;
int n[2];
...
...
..
n[0]=a;
n[1]=b;
return n;
}
こうならOKなんでしょうか?
957 :
デフォルトの名無しさん:04/02/15 21:02
>>956 それってC++標準ライブラリじゃないですよね?
gccでコンパイル通りますか?
958 :
デフォルトの名無しさん:04/02/15 21:06
>>955 戻り値を構造体にまとめてしまうとか、
ポインタ型の引数を受け取って
そのポインタの中身を書き換えて返すとかする。
グローバル変数にしてしまって、関数内でそれを書き換えさせる
ド顰蹙ものの解決法も。
int hoge(){
int a,b;
int n[2];
...
...
..
n[0]=a;
n[1]=b;
return n;
}
はダメ。戻り値の型はintなのに、int配列(の先頭アドレス)を返そうとしてる。
またnの内容は関数内でしか有効でないので、アドレスを渡しても受けたときには
そこにあったnの内容は消えている。文字列でも同じ。
昨日はエロゲーで徹夜したので、きょうはもう寝る。
>>957 導入じたい難しくないから、自分でためしてみろや。
やるきねー奴だな。
>>955 俺も初心者だが考えてみたよ。
これでどうだろう。
#include <stdio.h>
int *hoge(void);
int main(void)
{
int *p;
p = hoge();
printf("n[0]=%d, n[1]=%d", p[0], p[1]);
return 0;
}
int *hoge(void)
{
int a=1,b=2;
int n[2];
//...
//...
//..
n[0]=a;
n[1]=b;
return &n[0];
}
ちなみに、return n+0; でもうまくコンパイルできた。
int *np; np = n; return np; でもうまくコンパイルできた。
ただし return n; は警告が出た。
添え字無しのnを「配列の先頭を示すポインタ」とみなし
てくれるのは、あくまでも式の中ということかね。
>>963 >警告が出た
そりゃ、ローカル変数のアドレスを返そうとしてるからだ
ローカル(auto)変数のアドレスを返しちゃいかんよ。
いや、返すこと自体は構わないが、その中身を参照しても正しくは動かない。
(動くこともあるかもしれないが、それは偶然)
せっかくコンパイラが警告を出してくれているのだから
「とにかく警告が出なくなればいい」ではなくて、
せめてその意味くらいは考えよう。
>>963 >>958に書いてあるようにhoge内で定義された領域に
hoge外部からアクセスしちゃだめ。
2つ程度ならポインタ型の引数を受け取るのが簡単。
void hoge(int *a, int *b)
{
*a=1; *b=2;
}
みたいな
これもFAQに近い内容なんで簡単にまとめておくと
1 出力先の変数のアドレスを引数として受け取るようにする
2 返したい値を全て含む構造体を導入してそれを返すようにする。
2' C++であれば標準ライブラリの std::pair の利用法を参考にするとよい。
>>964-967 ありがとうございます。間抜けなことをしてしまった…。
ローカル変数のアドレスではなく値を直接返すように直しました。
今回のような場合は、
>>966の方法が簡単そうですね。もし、
>>955の、
「関数の戻り値で2つ以上の値を返す」形にこだわる必要があるなら、
やはり(C言語では)構造体を使うことになるのかな。
#include <stdio.h>
struct s_type {
int a;
int b;
};
struct s_type hoge(void);
int main(void)
{
struct s_type to;
to = hoge();
printf("a=%d, b=%d", to.a, to.b);
return 0;
}
struct s_type hoge(void)
{
struct s_type from;
from.a=1;
from.b=2;
return from;
}
>>968 #include <stdio.h>
struct s_type {
int a;
int b;
};
void hoge(s_type* ps){
ps->a=1;
ps->b=2;
}
int main(void){
struct s_type s;
hoge(&s);
printf("a=%d, b=%d", s.a, s.b);
return 0;
}
>>968 なぜstd::make_pairを使わない?
>>968 >>969に替わって補足
>>969はポインタを使って渡す方法ね
例みたいなメンバが二つしかない構造体ならあんまり問題にならないんだけど、
大きな構造体の場合、データを丸まるコピーするのは高価な処理になるから、
ポインタを使って渡そうっていう話です
ただ、二つ程度のメンバならポインタを使わないほうがたぶん速い
さらにはコンパウンドリテラルとか使ったときに最適化確率アップかも知れず
まあ、ここらへんは環境依存
C でプログラムはじめたんだけど、モジュールの分け方に定石のようなの
はあるんでしょうか?
作りはじめはいいんだけど、いろいろ追加してるうちに、モジュールが
互いに関数とデータを参照しあって、モジュールに分けてる意味が薄れていってし
まうってことが多くて・・。
>>974 ある部品を作ったら、それができる限り単独で動くようにする。
他の部品に依存する場合、依存関係はできる限り一方向にする。
「できる限り」というのがどの程度を差すのかは要件に依存する。
市松模様をつくりたいものです。
int n=8,x=100,y=100,a=40; // nは8マス,xとyは座標,aは中に置くコマの大きさ
int xx=140; // xxは座標
int m=1; // mは1マスと言う意味
// 四角形1マスの色(白)
Hdr = CreateSolidBrush(RGB (255,255,225));
HdrOld = SelectObject(hdc,Hdr );
// 四角形1マスを描く1
Rectangle(hdc,x,y,x+a*m,y+a*m);
SelectObject(hdc,HdrOld);
DeleteObject(Hdr);
//四角形1マスの色(緑)
Hdr = CreateSolidBrush(RGB (0,155,0));
HdrOld = SelectObject(hdc,Hdr );
//四角形1ますを描く2
Rectangle(hdc,xx,y,xx+a*m,y+a*m);
SelectObject(hdc,HdrOld);
DeleteObject(Hdr);
これだとxが100yが100の所に白と、xが140yが140の所に緑が1つずつしか書けない
のですが、これに何か付け加えて8マス×8マスの市松模様を作れませんか?
これを繰り返せばいいのかと思っているのですが、どのようにすればいいのか
よく分かりません。お分かりになる方教えていただけないでしょうか?
(APIです)
978 :
デフォルトの名無しさん:04/02/19 21:53
何の後始末?
コピペ元のスレの後始末かと
>>975 最初の考えはそんな感じなんだけど、つづかんのです・。
最初からもっと詰めとかないとだめってことなのかな?
プロは、どうやってるんだろう。
>>980 ERモデリングでもやってみれば?
必要な属性と動作を取り出すのには初心者には楽かと。
当方VB厨ですが、勉強がてらに
>>976のを書いてみました。
晒してよかですか?
ええよ
じゃぁ、汚いコードかもしれませぬが遠慮なく貼らせていただきます。
int n = 8, x = 50, y = 50, a = 40;
int xx = 10;
int nLeft = 0, nTop = 0;
HBRUSH brOld, brNega, brPosi;
brNega = CreateSolidBrush(RGB(255,255,225));
brPosi = CreateSolidBrush(RGB(0,155,0));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
nLeft = (i * x) + xx;
nTop = (j * y) + xx;
brOld = (HBRUSH)SelectObject(hdc,
(((i % 2) == (j % 2)) ? brNega : brPosi));
Rectangle(hdc, nLeft, nTop, nLeft + xx + 1, nTop + xx + 1);
SelectObject(hdc, brOld);
}
}
DeleteObject(brNega);
DeleteObject(brPosi);
C系を最初に覚えた方に質問です。
VB6.0できるようになるまで、どれくらいかかりました?
当方おそらく、1週間くらいは合計でやってると思いますが、全然できません。
#include とかないっぽいし(POINT とか RECT とか自分で定義するの?)、
毎回コントロールをプロジェクトで追加しないといけないし、
なんかめんどくさ。つーか、久しぶりに起動するともう全然覚えてないし。
ポインタとか、いまいちわかりづらくなってるし、
覚えるこつってあるんですかね?
MSDN読むしかないのかな?