【初心者歓迎】C/C++室 Ver.8【環境依存OK】
1 :
デフォルトの名無しさん :
04/07/31 18:09
C++BuilderXでGUIアプリを作成する場合には MFCは使えるのでしょうか?
BCC5.5.1 で DirectDraw を使っています。 以下のコードを含むプログラムを1000回ほど繰り返すのですが、 このコードの違いだけで 40FPS もの差がでており、?な状況です。 //遅いコード tmp = func(); *p = tmp; //速いコード *p = func(); tmp = *p; p はサーフェス上のピクセルデータを指す WORD 型へのポインタです。 このような差が出てしまう原因として、どういったことが考えられるのでしょうか? よろしくお願いします。
書き忘れていました。 tmp の型と、func() の戻り値の型は DWORD です。
前者と後者、全く意味の異なる記述なんだけど。 それだけじゃわからねーから、ソース上げろ
ごちゃごちゃしてますがこんな感じになっています。 else if (pixelinfo.bpp_ == 16) { LONG srcpitch = srcddsd.lPitch / 2, dstpitch = dstddsd.lPitch / 2; WORD* const srcptr = static_cast<WORD*>(srcddsd.lpSurface); WORD* const dstptr = static_cast<WORD*>(dstddsd.lpSurface); DWORD srcclr0=0, dstclr0=0, newclr0=(*blendfunc)(dstclr0, srcclr0, alpha); for (int sy = srcrect2.top; sy < srcrect2.bottom; ++sy) { for (int sx = srcrect2.left; sx < srcrect2.right; ++sx) { DWORD srcclr = srcptr[srcpitch * sy + sx]; if (!trans || srcclr != clrkey) { int dx = dstx + (sx - srcrect->left); int dy = dsty + (sy - srcrect->top); WORD* dp = dstptr + dstpitch * dy + dx; DWORD dstclr = *dp; if (srcclr == srcclr0 && dstclr == dstclr0) { *dp = newclr0; } else { *dp = (*blendfunc)(dstclr, srcclr, alpha); //(1) srcclr0 = srcclr; dstclr0 = dstclr; newclr0 = *dp; //(2) } : (1)の部分を newclr0 = (*blendfunc)(dstclr, srcclr, alpha); (2)の部分を *dp = newclr0; と変えてコンパイルしているだけなのですが、 何かお分かりになりましたらよろしくお願いします。
>>10 俺もVRAM通してるから、と一瞬思ったが、それだと下のは逆の結果にならないか?
>//遅いコード
>tmp = func();
>*p = tmp;
>//速いコード
>*p = func();
>tmp = *p;
転送元サーフェスも転送先サーフェスもシステムメモリ上に 作成しました。何でなんですかね…。
DWORD newclr0; と WORD* dp; では宣言している場所が違うから。 見た感じだけど、その程度のプログラム量なら マシン語になった際 newclr0 はスタック上に存在するが、 dp はレジスタを使っている気がする。
めんどくさいからアセンブリリストか実行可能な最小のコード上げた方がいいと思うよ。
*dp = (*blendfunc)(dstclr, srcclr, alpha); //(1) newclr0 = *dp; //(2) srcclr0 = srcclr; dstclr0 = dstclr; newclr0 = (*blendfunc)(dstclr, srcclr, alpha); //(1') *dp = newclr0; //(2') srcclr0 = srcclr; dstclr0 = dstclr; こうなってても変わらん?
16 :
デフォルトの名無しさん :04/08/01 00:31
あの、シフト演算子をオーバーロードする際に、次の引数へ移行するにはどうすればよいのでしょうか。お願いします。
>>16 次の引数も何も、オーバーロードはそれだけで完結するんだが。
std::cout << a << b << c;
とかやりたいの?
(((std::cout << a) << b) << c);
>>17 ああいやoperator<<()で独自の機能を持たせようとしてるんですけど、独自の機能もたせるとシフトしてくれないんですよ。何かいい方法あるでしょうか。
シフトを独自の機能で置き換えてるんだからあたりまえじゃないの?
あと、
>>16 をどう読んでも
>>18 にはならない。もっと日本語がんばれ。
>>18 operator<<()の中にシフトのコードもインラインアセンブリなんかで書く。
this-><< 使え
入力ファイルの一行目にファイル名が書いてあります。 そのファイル名を出力するファイル名にしたいのですが 実行すると「出力先ファイルを開けませんでした。」と出ます。 なぜなんでしょうか? 入力ファイル名をきちんとgetできているか putsで確認したところちゃんとgetできていました。 printf("入力ファイル名を入力してください。 :"); gets(infile); if((fin=fopen(infile, "r")) == NULL){ printf(".cume ファイルを開けませんでした。\n"); exit(1); } fgets(outfile, 256, fin);putchar('\n'); puts(outfile); if((fout=fopen(outfile, "w")) == NULL){ printf("出力先ファイルを開けませんでした。\n"); exit(1); }
>>23 fgetsは改行文字も読み込むから、まずそれを捨てろ。
改行文字 fgets() でググって色々調べたところ len = strlen(outfile); outfile[len - 1] = '\0'; ↑の二行を追加することで問題が解決しました。 ありがとうございました。
前スレで嘘を教えたらいかんとか言われたんだけどさ。 きちんと本を読んで書いたし、 違う場所があるなら違う場所を言えばいいのになぁ・・・ 自分にも相手にも、質問者にも為にならないし
>>27 俺は指摘した本人ではないが、
>2.
>外部変数(グローバル変数)になった時だけ、両方の意味が同じになります。
同じではない。
グローバル変数にstaticをつけると、関数につけるのと同じで、
他のファイル(翻訳単位)から参照できなくする。
>少しの違いといえばintなら0で初期化されるかされないかの違いぐらいで、
どちらも0で初期化される。
>staticを使ったからといって通用範囲が狭くなるわけでもありません。
狭くなる(上述)。
>>28 autoだって元々参照できないでしょうに。
他のファイルから参照って言うのはつまりincludeした場合ですか?
グローバル変数は全部初期化されるんですね。
俺が勉強した時(2、3年前)にautoは初期化されないと読んだような気がしたので。
>>29 >autoだって元々参照できないでしょうに
autoはローカル変数だけだぞ?
void func(void) {auto int a;} /* ok, 単にint a;と書いても同じ。初期化されない。 */
auto int b = 4; /* error */
>他のファイルから参照って言うのはつまりincludeした場合ですか?
/** a.c **/
int g;
/** b.c **/
extern int g;
/* ここでgを使う */
スコープと記憶クラスを混同しまくってる悪寒。
>>30 未熟さ故の過ちなので許してください。
>autoはローカル変数だけだぞ?
初めて知りました。
有難うございます。
>>他のファイルから参照って言うのはつまりincludeした場合ですか?
>/** a.c **/
>int g;
>/** b.c **/
>extern int g;
>/* ここでgを使う */
autoがローカル変数のみという事が解ったので
こちらも自然と解りました
有がとうございます
>>27 その書き込みのときに読んだ本の名前、晒しといたほうがいいんじゃないか?
参考書籍の間違いくらい自分で見つけられないと後で苦労すると思うけどなあ。 うのみにする方が問題。
std::vector<unsigned char> array(...); std::string<char> s(array.begin(), array.end()); ってできないんですか?
なんで片方だけunsignedなんですか?
>>37 string<char> → basic_string<char>
・・・なんかgccだとstring<char>が通った。ナンダコレ
>>39 #include <iostream>
using namespace std;
template <typename T> class A {};
typedef A <char> Achar;
int main () {
cout << typeid (A <char>).name () << endl;
cout << typeid (Achar <char>).name () << endl;
return 0;
}
これでもエラー出ませんね.実行すると
1AIcE
1AIcE
と出力します.因みに当方は3.3.4です.
gccショボイな。 -Wall -ansi付けても警告も出ないのか?
-pedanticも付けてね
>>42 -Wall -ansi -pedantic
で何事もなかったようにコンパイルします.
ガーソ
vector<string> get(); なんてメソッドを作ったらアホって言われた。 速度なんてどうでもいいクラスだからこうしてるつもりだったけど やっぱり void get(vector<string>&) って書くべきですか?
別に前者でいいんじゃないか?どうせvoid get(...)の中で コピーするわけだろう?
え〜? vector<string> get()は2回コピーするから2倍遅いよ。
49 :
デフォルトの名無しさん :04/08/02 12:34
クラス名やメンバ変数に名前をつけるときに何か気をつけることある?
int count[0x100 * 0x100]; の「0x100」部分が何をやってるのかわかりません。 ごめんなさいごめんなさい 助けてください。
0を最初につけると8進数 0xを最初につけると16進数 1〜9が最初ならば10進数
>>52 >>53 ありがとうです;;
ココを16進表記するのはどんな時ですか? 数字以外を入れたいとき?
>>54 気分次第。 256 より 0x100 の方が見た目キリがいい(かどうかは書いた本人次第だが)でしょ?
134217728 よりも 0x8000000 のが見やすいからです
0x5f5e100 100000000
>>57 そういう場合は下を使うだろう
ってか態々100000とか見やすいのを醜くする方が頭可笑しいよな
うう・・・ 皆ありがとうでした。 がんがります。
キリがいいかキリが悪いかはあまり関係ない。
16進で書くべきものはキリが悪かろうと16進で書く。
これが
>>57 アドレスを指すなら多くの人は16進を選択するだろう。
61 :
デフォルトの名無しさん :04/08/03 00:51
#include <iostream> using namespace std; class A { protected: int a; public: A(int v) { a = v; } }; class B : public A { protected: int b; public: B(int v) { b = v; } int get() { return a; } }; int main() { B bb(10); cout << bb.get() << endl; return 0; } test.cpp: In constructor `B::B(int)': test.cpp:18: no matching function for call to `A::A()' test.cpp:5: candidates are: A::A(const A&) test.cpp:9: A::A(int) このエラーはどうしたらいいのでしょうか?
B(int v) : A(v) { b = v; } じゃない?
63 :
デフォルトの名無しさん :04/08/03 01:06
>62 ありがとう御座います。 表示されました。
ごめん、あげちゃった
65 :
デフォルトの名無しさん :04/08/03 02:13
std::listってどんなときに使うの? std::dequeでよくね? つーか、ぶっちゃけいらないんだけど・・・
コピーコンストラクタが重いとき
要素へのイテレーターや参照が無効になるのが嫌なとき。
68 :
デフォルトの名無しさん :04/08/03 10:29
x = (50, 2); これはどういう理屈で2を返すんでげすか?
カンマ演算子の働き
70 :
デフォルトの名無しさん :04/08/03 13:14
アクセルしたらブレーキして下さい
もちろんしますよ
クラッチしたらシフトチェンジして下さい
51です。 しつこくアホですみません;; data[0]="a"; data[1]="b"; count[(data[0]<<8)+data[1]]++; こういう書き方ってできるんでしょうか? やってることは、分布数えソートで文字列「ab」の分布を数えてるのですが・・・・・ 何で配列の添字に数字以外が入ってるのかわからない;;
二重引用符(文字列定数)ではなく引用符(文字定数)じゃないのか。 data[0]='a'; data[1]='b'; char型変数二文字分をまとめて2バイトの数値にして、 テーブルのインデックスに使ってるんでしょ。 具体的には、ASCIIコードな環境では'a'は0x61、'b'が0x62なので、 count[0x6162]の値をインクリメントしてる。
俺だったらマクロ噛ましてcount[MAKEWORD(data[0]<<8, data[1])]++;
MAKEWORD(data[0], data[1])の方が良くないか?
つか、論点ズレすぎ
ありがとうございました。 勘所がわかって感涙しております。 精進しまつ。
>>79 見てるのは他人のソースなので、完成したら貼らしてもらいます。。
81 :
デフォルトの名無しさん :04/08/03 19:38
初心者歓迎なのは、初心者をいじめたいからなの?
当たり前だ。
夏満開
んー、教えてクンはどこのスレにいっても歓迎されん罠。 「初心者歓迎」のタイトルを見て教えてクンが集まってくるから、 叩かれる事も多い。 それで剣呑に見えんじゃないの、このスレ。 自分的には、まともな質問者にはそれなりにきちんと回答してるつもりだけど。
初心者をいじめてるのも初心者
86 :
デフォルトの名無しさん :04/08/04 04:19
protected:があるのに、private:ってつかうのか?
それはpublicがあるのにprotectedって使うのか?という質問に似ている。
派生のprotectedならいらんけど
89 :
GROAD ◆4C1MajRa36 :04/08/04 05:09
すみません 質問させていただきます 環境はWin32APIです 今回、初めてブラウザ補助ツールを組むことになったのです (ダウンロード補助) 小ウィンドウにアドレスを入力させ親ウィンドウに情報を受け渡してから接続させたいのですが肝心のアドレス(URL)の認識とアクセスのさせかたがわかりません とりあえず調べてみたのですが書いてあるサイトは見つけられませんでした。 どの関数を使えばいいのでしょうか? ヒントだけでもいいので御教授頂けると幸いです
「アドレスの認識」なる特殊用語の詳細を求む。
91 :
デフォルトの名無しさん :04/08/04 05:28
コンストラクタって、なんか、難しいな。
92 :
デフォルトの名無しさん :04/08/04 05:36
C++をやってみたいのですが、初心者が読んでも理解できる本はありますか? 他のプログラムはBASICしかしりません。
93 :
GROAD ◆4C1MajRa36 :04/08/04 05:37
>>90 説明が下手で申し訳ありません
URLのことです
96 :
デフォルトの名無しさん :04/08/04 05:40
>95 無理な根拠を上げよ。
>96 無理では無い根拠を挙げよ。 つか、ぐだぐだ言ってないで本屋なり図書館なり行けっての。 検索したり推薦図書などのスレもあるのに。
99 :
GROAD ◆4C1MajRa36 :04/08/04 05:50
>>99 もう一度いうがwinsockで間違ってない
期待してたのはプロセス間通信か?
回答を理解できない程度で気分悪いことするなよ
102 :
GROAD ◆4C1MajRa36 :04/08/04 06:04
はい。 データさえ落とせればいいのですからプロセスで大丈夫です (リンクを確率させる必要はありません)
┌─────────┐ │ 基地外警報!!! | │ 基地外警報!! | └―――──――――┘ ヽ(´ー`)ノ ( へ) く
なんで自分に知識もなく、それを説明する能力もないのに作りたがるのかな。 そんなに自分のアイディアに自信でもあるんだろうか。
馬鹿と天才は紙一重と言うからな。
& や | といったビット演算で得られるビットパターンというのは、 その数値の内部表現を表しているのでしょうか? NULLポインタに限らず整数の0でも、内部表現が0とは限らないというのを どこかで聞いたんですが、たとえば整数0の内部表現に1のビットが含まれて いるとき、ビット演算で1を取り出すことが出来るのでしょうか。
>>106 unionを使えば簡単だでや?
union {
void *pvValue;
double dValue;
long lValue;
};
pvValue = (void *)&lValue;
printf("%08X\n", lValue);
dValue = 0.01;
printf("%08X\n", lValue);
return 0;
メンバ関数ポインタについて質問があります。 class A{}; class B :public A { void Func(){} }; ↑のようにclass Aから派生したclass Bがあったとき B b; A *a=&b; void (A::*pFunc)()=(void (A::*)())b.Func; (a->*pFunc)(); ↑こんな感じで、 基本クラスのメンバ関数ポインタpFuncに class Bの関数を(void (A::*)())にキャストして代入し、 呼び出し時も(a->*pFunc)()で呼び出しても 見た目は動いているように見えます。 このように書いても問題はないのでしょうか。 危険な部分がありましたら教えてください。
virtual
111 :
デフォルトの名無しさん :04/08/04 12:54
>>108 危険すぎます。
実行したらペンタゴンにpingを打ちまくっていますw
>>109 >>111 レスありがとうございます。
やはり危険ですか。
キャストについて理解してないのでこんな質問を
してしまったわけですね…
というかそんな変な書き方が横行しているわけもなく
メンバ関数ポインタの型が完全に一致していれば、問題ないんでは。 もっとも、そんな奇天烈なコードが本当に必要なのか見直すのが先だけど。
>>114 実装したかった内容は、
配列、リスト等に様々なクラスのメンバ関数をポインタとして持ち
逐次実行できるような構造です。
仮想関数だと似たようなことはできますが、
実行できる関数がvirtualのついている1関数に限定されてしまうので
悩んでいます。
単に呼び出す可能性がある物は仮想関数にしとけば良いんでは。 キャストするにしても呼び出す関数はコード内で指定しているわけだから 仮想関数だと限定云々は良くわからん。
>様々なクラス これを一緒くたにすること自体が問題 「できること」と「するべきこと」は違うのよ >そんな奇天烈なコードが本当に必要なのか これを深くかみしめたまい
1.リストに格納する予定のオブジェクトに必要な機能を洗い出す 2.必要な機能を実現する為の関数をもった抽象クラス=インターフェースを作る。 3.各クラスでそのインターフェースを継承して関数を実装する 1の手順を踏まずにコードを書き出して混乱してるんじゃないのか。
>>107 ありがとうございます。せっかく書いていただいたのですが
よく分かりません^^; つまり、どういうことなのでしょうか
>>115 LokiのFunctor(boostにもある?)を使えば以下のようなことができるけど,
こんなことじゃなくて?
#include <iostream>
#include <loki/Functor.h>
#include <functional>
#include <list>
using namespace std;
struct A {
void show () const {cout << "A" << endl;}
};
struct B {
void show () const {cout << "B" << endl;}
};
typedef Loki::Functor <void> Functor;
typedef list <Functor> Functor_Container;
int main () {
A a0; B b0;
Functor_Container fc; fc.push_back (Functor (&a0, &A::show)); fc.push_back (Functor (&b0, &B::show));
for_each (fc.begin (), fc.end (), mem_fun_ref_t <void, Functor> (&Functor::operator ()));
return 0;
}
出力:
A
B
>>116 >>117 >>118 私も構造自体だめなんだと薄々感じています。
見直した方がよいのかもしれないですが、
他人に見せることのないオナニーコードなので
突き進もうと思います。
キャストが怖いとのことでしたので、
temlateを使って妥協することにしました。
struct A
{
virtual void Call(){}
virtual ~A(){}
};
template <class T>
struct B : public A
{
T* pThis;
void (T::*pFunc)();
B(T* tThis,void (T::*tFunc)()){pThis=tThis;pFunc=tFunc;}
virtual void Call()
{
if(pThis)
(pThis->*pFunc)();
}
};
↑こんな感じにしておいて配列、リストにでも入れようと思います。
std::list<A*> a;
岩盤の中を爪楊枝で削りながら突き進んでる姿が浮かびました
>>119 昔GCCスレに書いたもの(何だか今見れないので)を差し上げましょう.
これでビットパターンを見れるので,いろいろ観察して遊んでみて下さい.
#include <iostream>
#include <bitset>
template <class T> std::ostream & output_as_bits (std::ostream &p_os, const T &p, bool ascending_order = true) {
std::bitset <sizeof (T) * 8> p_bit; const char *pp (reinterpret_cast <const char *> (&p)); char byte_digit (1);
for (size_t i (0); i < p_bit.size (); ++ i) {
p_bit.set (i, static_cast <bool> (*pp & byte_digit));
if ((i + 1) % 8) byte_digit <<= 1;
else {byte_digit = 1; ++ pp;}
}
if (ascending_order) {
p_os << "L"; size_t i (0);
while (i != p_bit.size ()) {p_os << p_bit.test (i); ++ i;} p_os << "H";
} else {
p_os << "H"; size_t i (p_bit.size ());
do {-- i; p_os << p_bit.test (i);} while (i != 0); p_os << "L";
}
return p_os;
}
int main () {
int i0 (10); float f0 (10);
output_as_bits (std::cout, i0) << std::endl;
output_as_bits (std::cout, f0) << std::endl;
return 0;
}
>>120 うわー、そのものずばりな機能です^^;
今検索させてもらいましたが、
すごい機能ですね…。
>>124 mem_fun_ref_tがちょっとかっこ悪いんですけどね.
126 :
デフォルトの名無しさん :04/08/04 14:41
>>123 へぇ〜、カッコイイコード書くじゃん
>>122 みたいな馬鹿ばっかかと思ってたけど、骨のある奴いるんだね
バカは認めるけど どうしてそのタイミングで引き合いに出すのか せっかくならもっと笑いになるよう努力してください
>>125 いやまあ、そういったかっこ悪いとかはまあ…
でも、解決しましたです。
教えていただきありがとうございました。
>>123 おお、、ソースまでありがとうございます。
弄りながら、これから色々試してみることにします。
Lokiやめてboostにしてみました. こちらはmem_fun_ref_tでテンプレートパラメータを渡す必要がないですね. #include <iostream> #include <functional> #include <list> #include <boost/function.hpp> #include <boost/bind.hpp> using namespace std; struct A { void show () const {cout << "A" << endl;} }; struct B { void show () const {cout << "B" << endl;} }; typedef boost::function <void ()> Functor; typedef list <Functor> Functor_Container; int main () { A a0; B b0; Functor_Container fc; fc.push_back (boost::bind (&A::show, a0)); fc.push_back (boost::bind (&B::show, b0)); for_each (fc.begin (), fc.end (), mem_fun_ref (&Functor::operator ())); return 0; }
>>130 訂正.
- Functor_Container fc; fc.push_back (boost::bind (&A::show, a0)); fc.push_back (boost::bind (&B::show, b0));
+ Functor_Container fc; fc.push_back (boost::bind (&A::show, &a0)); fc.push_back (boost::bind (&B::show, &b0));
アドレスを渡さないとコピーしちゃうみたいですね.
確かに便利だが、実現ツールが準備されていて「設計見直せ」というレスが薄ら寒く見えるのが悲しい…
選択肢は多い方が良いんじゃないか? それに本当に設計を見直した方が良いのかは質問者が決める事で、 質問スレの意義は選択肢を提示するところにあるんじゃないだろうか。
文脈がよくわかりませんがもっともですね
WindowsAPIのデバイスコンテキストについてなんですが デバイスコンテキストを使ってLineToやTextOutを使って描画した線や文字というのは 一体どこに保存されているのでしょうか? デバイスコンテキストなのか、それともビットマップなのか・・・ 是非ともご教授下さい。 お願いします。
デバイスコンテキストに選択されているビットマップ
保存なんてされませんぜ、あにき
保存はされないな。強いて言えばビデオメモリか
>>135 保存されない。試しに描いたWindowの上に他のWindowを重ねてみれば、
描いたはずの絵が消える。もし保存したければ、ビットマップに一度描いて
それをWindowに描画する処理が必要。
配列って{}で囲むんですよね? あるソース見て char[][5] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10 } ってのがあったのだが、これってOKなの?
>>140 printfしたら
↑こんなのがいっぱい出てきました。
2ちゃんで表示できているか心配です。
やはり表示できませんでした。ごめんなさい。さようなら・・
>>140 OKだよ。
だけど古いコンパイラではエラーになるかもしれない。
>>141 制御文字に当たるから書き込んでもうまく表示されるわけないだろう。
そうだ、'\0'が抜けてた。
147 :
デフォルトの名無しさん :04/08/05 02:08
C++の文法は覚えたけど、オブジェクト指向がよく分からない。
シナリヲと配役が決まったらあとは演技させるだけ、だが?
149 :
デフォルトの名無しさん :04/08/05 02:27
糞レスはいらん。
150 :
デフォルトの名無しさん :04/08/05 02:50
AGE
レスどうもです うーむ・・・保存されないんですか てっきり、画像データみたいな感じでメモリかどっかに保存 されてると思ってたんですが見当違いみたいですね それじゃあ、プログラム内でウィンドウそのものを画像データ化 (キャプチャーソフトの様な感じで)というのは出来ないのでしょうか? こんなことを聞いているのは何故かと言いますと、ネットワークを介 したお絵かきソフトを作りたいなと思いサーバ・クライアント間で 画像データを共有出来る方法を探ってるわけです ちなみに、ネットワーク部分はほぼ完成しているので、後は画像データさえ 作れれば何とかなると思うのですが・・・これが良くわからないのです 是非、何かアドバイスをお願いします 後、長文失礼しました
>>151 サーバに画像用のメモリ確保してクライアントはそっちに書き、各クライアントに配信するか
サーバにクライアントのマウス情報を送り、サーバはそのマウス情報を(ry
してクライアントはそのマウス情報にそって(ry
画像キャプチャしながら送りあっていたら28.8kの通信速度じゃ無理だ。
>>151 描画コマンドはメタファイルとして保存できる
描画結果だけならDIBセクションとか使ってDIBにBltすればいい。
>>152 実は、リアルタイム通信じゃ無かったりします
クライアント1が描いてる間、他のクライアントは絵の内容を見れません
イメージとしては
C1が絵を描く→描き終わったらSへ画像データを送信→C2が画像を見る
※C・・クライアント S・・サーバ
なので、絵を見たり描いたり出来るのは同時に1人だけです
>>153 メタファイルというのは初耳です
DIBセクションというのは、BitBltみたいな感じなんでしょうか
ちょっと調べて見ます
どうもありがとうございました
うぅ・・サゲ忘れてた・・
158 :
デフォルトの名無しさん :04/08/06 02:08
環境依存だということなので、こちらで質問させていただきます。 空のフォルダを削除するにはどうしたらいいのでしょうか? googleで検索してもなかなか見つからず、 やっとサンプルコードが見つかったと思ったら、ないヘッダがインクルードしてあって 結局分かりませんでした。
161 :
デフォルトの名無しさん :04/08/06 02:31
c++には、javaの親クラスを指す superのようなのはないんですか?
>>158 C++なら,
#include <cstdio>
int main () {
std::remove("hoge");
return 0;
}
Cなら,
#include <stdio.h>
int main () {
remove("hoge");
return 0;
}
とか.hogeはパスです.
>>157 言われた通りにデータ構造体に void* lpBMPを追加して
直接RGBの値(輝度?)を設定して画面全体が水色になったサーバ上の絵を
クライアントに送りました
[クライアントのデータ受信](データ受信時に画像作成)
hBitmap = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, &g_RcvPictureData.lpBMP, NULL, 0);
こんな感じにしてみたんですが、残念なことにクライアントでは画面真っ黒な状態です・・・
サーバでは水色になってるんですが
lpBMPだけじゃダメなんでしょうか・・・
うーむ・・デバイス独立ビットマップっていうぐらいだから、DCに依存しないと思うんですが
謎です・・・困った
>>162 158ではないが、今のremoveはフォルダ/ディレクトリを消せるのか。知らなかったよ。
>>165 中身・・・ですか
サーバ側では送信データのlpBMPに対して
((char*)g_SndPictureData.lpBMP)[offset+2] = 127;
このように直接値を入れて、これをそのままクライアントに送ってるのですが
これだと中身は送られてないんでしょうか・・・
>>164 Linuxのmanによると,
>remove deletes a name from the filesystem. It calls unlink for files,
>and rmdir for directories.
と書かれています.
標準ライブラリなのでたぶん158の環境でも大丈夫だと思うんですけどね.
ディレクトリの削除が可能かどうかは実装依存
>>167 removeは標準ライブラリじゃねーよ
本日のバカ
----------------------------------------------------------
169 名前:デフォルトの名無しさん[sage] 投稿日:04/08/06 03:58
>>167 removeは標準ライブラリじゃねーよ
----------------------------------------------------------
removeがディレクトリを消せるかどうかは環境依存だな 少なくともLSI-Cや古いMS-Cでは消せなかった
>>168 じゃ,その可能性も考慮してboostで.
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
int main () {
boost::filesystem::path dir ("hoge");
boost::filesystem::remove (dir);
return 0;
}
>>158 Windowsならwinodws.hのRemoveDirectory
unixなら、remove()内部で対象がファイルならunlink()、 対象がディレクトリならrmdir()を呼ぶように実装するのが当たり前だろ?
179 :
デフォルトの名無しさん :04/08/06 09:31
>>177 ばかはおまいだろ、屁理屈野郎
空のフォルダを削除するプログラムを書くのは
環境に依存しないよ
173
181 :
デフォルトの名無しさん :04/08/06 09:35
>>179 libc5 removeで検索しれ池沼
>>158 環境依存だと判ってるなら環境が何か書けよ。
すいません、教えてください。 #include <stdio.h> main(void) { int i; char math; printf("計算したい加算乗除を選択してください。\n足し算:A\n引き算:B\n掛け算:C\n割り算:D\n"); gets(math); if (math = "a"){ printf("足し算をします。\n"); } else { printf("その他の計算を行います。\n"); } return 0; } 今はif文のテストとしてメッセージだけを表示されるように組んでます。 何故だか分からないんですけどエラーが出るんです。 どうすればいいのか、どなたか教えていただけませんか?
>エラーが出る コンパイルが出来ないのか、実行時エラーなのか、エラーメッセージ書け、ヴォケ >char math; >gets(math); getsの引数はchar *型を指定する。gets(&math)にすればコンパイルは通る、が実行時にアボン >if (math = "a"){ 文字列定数"a"はchar *型、char型のmathとは比較できない。 Cで文字列を比較するならstrcmpを使う。 char math[BUFF_SIZE]; とかにすれば、BUFF_SIZE-1文字までの入力なら動く。 どうでもいいが、入力を促すメッセージでは大文字の"A"なのに、 小文字の"a"との比較で良いのか?
>>151 裏画面つくってそこに描画してる…?
つくってるだけで終わってませんよね。
//裏画面Bitmap作製
DWORD *lpBMP;//画素データへのアドレス
HDC hBackDC=CreateCompatibleDC(NULL);
char bmbuf[sizeof(BITMAPINFOHEADER)];
BITMAPINFO &bi=*(BITMAPINFO*)&bmbuf;
BITMAPINFOHEADER &bih=bi.bmiHeader;
ZeroMemory(&bi.bmiHeader,sizeof(BITMAPINFOHEADER));
bih.biSize=sizeof(BITMAPINFOHEADER);
bih.biWidth=width;//ウィンドウ幅
bih.biHeight=-height;//ウィンドウ高さ
bih.biPlanes=1;
bih.biBitCount=32;
HBITMAP hBitmap=CreateDIBSection(NULL,(BITMAPINFO*)&bih,DIB_RGB_COLORS,(void**)&lpBMP,0,0);
ZeroMemory(lpBMP,sizeof(DWORD)*width*height);
SelectObject(hBackDC,hBitmap);
//描画は全部裏画面へ
TextOut(hBackDC,x,y,str,lstrlen(str));
//WM_PAINT等の最後では裏画面を表に転送
//hDCは表画面のデバイスコンテキスト
BitBlt(hDC,0,0,width,height,hBackDC,0,0,SRCCOPY);//裏画面→表画面にコピー
転送するのは裏画面ビットマップ全体。
画素データだけならlpBMP〜lpBMP*(DWORD)*width*heightに全部入っている。
>>184 if (math = "a"){
→if (math == "a"){
ってオチですか…?
比較は「==」ね。
ああすまん。リロードしてなかった。 185が大量に突っ込んでました…。
>>185 レスありがとうございます。
エラーは
「error C2664: 'gets' : 1 番目の引数を 'char' から 'char *' に変換できません。 (新しい機能 ; ヘルプを参照)
整数型からポインタ型への変換には reinterpret_cast、C スタイル キャストまたは関数スタイル キャストが必要です。」
と
「error C2440: '=' : 'char [2]' から 'char' に変換することはできません。(新しい動作 ; ヘルプを参照)
この変換には reinterpret_cast, C スタイル キャストまたは関数スタイルのキャストが必要です。」
です。
ちょっと分からないんですけどchar *型って何ですか?
大文字のAと小文字のaは普通に間違えてました。指摘どうも。
>>187 比較ってしたとすると具体的にどんな事をするんですか?
あ、==でなく=は素で見落としてた。 >ちょっと分からないんですけどchar *型って何ですか? いくら初心者歓迎とはいえ… char型へのポインタを格納する型。 Cには「文字列型」はないので、charに文字を格納し、 charの配列で文字列を扱う。
>>184 #include <stdio.h>
#include <conio.h>
main(void)
{
int i;
char math;
printf("計算したい加算乗除を選択してください。\n足し算:A\n引き算:B\n掛け算:C\n割り算:D\n");
do {
math = getch();
switch (math) {
case 'A' :
printf("足し算をします。\n");
break;
case 'B' :
printf("引き算をします。\n");
break;
case 'C' :
printf("掛け算をします。\n");
break;
case 'D' :
printf("割り算をします。\n");
break;
}
} while (math != 'A' && math != 'B' && math != 'C' && math != 'D');
return 0;
}
何かハードル高そうですね・・・・ 勉強不足だったようです。 出直してきます。 ご迷惑おかけしました。
>>191 作り直していただき、ありがとうございます。
でも、192で書いたとおりです。
すいませんでした。
>加算乗除 引き算の立場は?
剰余は?
>>186 サーバでもクライアントでも、裏から表へBitBltしてます
サーバから送るのは、(void**)&lpBMP 画素データと
HBITMAP hBitmap これでしょうか
↑これが裏画面ビットマップ?
>>197 アドレス渡しても意味無いんだよ、Cからやり直して来い。
送るべきデータは
lpBMP〜(lpBMP+((width+3)&~3)*height)
C言語勉強してWin32APIつかって簡単なソフト5つほど作ったレベルなんですが、 C++にさっさと移行したほうがいいんでしょうか?Cの一通りの知識は頭に入ってるとは 思います。テクニックはほとんどないですが。 できればCからのC++への移行に最適な参考書を紹介していただければ幸いです。
もうしばらくC使ってた方がいいぞ
すいません。
<環境>
WindowsXP
BCC5.5
です。
>>159 標準でついてきてないヘッダで、
DLしたサンプルにもついてないヘッダです。
>>178 BCCスレに行こうかと思ったところ、このスレの【環境依存OK】が目に入ったもので。
>>162 ,
>>174 ,
>>175 ありがとうございます。
試してみます。
204 :
デフォルトの名無しさん :04/08/07 19:43
プログラムをコンパイルしようとしたら、 「インクルードファイルxxx.hをオープンできない」というエラーが発生しました。 A. コマンドラインコンパイラのパスが設定した後、 インクルードファイルやライブラリファイルの場所を指定したBCC32.CFGを作成しなければなりません。 これは、List 4のようなファイルです。 List 4 BCC32の設定(BCC32.CFG) -IC:\Borland\Bcc55\Include -LC:\Borland\Bcc55\Lib コマンドラインコンパイラは、コンパイルが成功すると自動的にリンカ(ILINK32)を呼び出します。 場合によっては、リンカを明示的に呼び出すことがあります。 この場合は、同様にILINK32.CFGファイルを設定してください。 また、BCC32.CFGやILINK32.CFGには、これ以外にもコンパイラやリンカに設定するオプションをあらかじめ指定できます。 このファイルはbinのディレクトリの中に作ればいいんですよね。 普通にテキストファイルじゃダメっすか?
テキストファイルだけど拡張子はcfg
206 :
デフォルトの名無しさん :04/08/07 19:57
ちゃんとcfgになってますね。 以前にc言語をダウンロードした時にもpathを通すために path=%path%;c:\progra~1\networ~1\mcafee~1c:\lsic86\binのパスや ジャバのパス path=c:\windows;c:windows\command;c:\j2sdk_nb\bin などをms-dosに書き込んであるのですがそれが影響を及ぼしたりしますかね?
試してから聞け
208 :
デフォルトの名無しさん :04/08/08 00:12
初心者質問ですまん。 C言語環境で貴様の使っている、リストとかハッシュテーブルとかのライブラリを教えてくれ。 やっぱ、俺様ライブラリなん?
std::list, std::hash_set
210 :
デフォルトの名無しさん :04/08/08 00:29
boost
ABDEFGHIJKLMNOPQRSTUVWXYZ
>206 BCC32.CFG.txtだったら殴るぞ。
208-214 なんか和んだ・・・
217 :
デフォルトの名無しさん :04/08/08 23:08
virtualをつけなくても関数の再定義が出来るのに、どうしてvirtualをつけるんですか?
全部作れ!って事をあらわすためだ
仮想関数にするためです
220 :
デフォルトの名無しさん :04/08/09 03:37
list<CHoge*> hoge; list<CHoge*>::iterator p; って、どういう意味なの?
221 :
デフォルトの名無しさん :04/08/09 03:40
>>220 list<CHoge*>型のhogeを定義。
list<CHoge*>::iterator型のpを定義。
222 :
デフォルトの名無しさん :04/08/09 03:54
ごめん、質問の仕方が悪かったです。 CHoge*って、ポインタを使ってるけど、なにか意味あるの?
223 :
デフォルトの名無しさん :04/08/09 04:25
定数とグローバル変数について教えてください。 C言語でグローバルな定数を書く場合、ヘッダファイルに#defineや enumで定義するのが普通かと思います。 これと同じことをconstを使ってやりたいのですが、単純に#defineのように 書くとリンクエラーになります。 こういった場合、どのようにするのが定石でしょうか? お願いします。
すいません、解決しました。 もうちょっと調べてから書き込むべきでした。 お騒がせしてすいません。(でもまだ誰もみてないよな・・・)
226 :
デフォルトの名無しさん :04/08/09 05:02
見てないよ。
>>217 ポリモフィズムを実現するため。
関数オーバーロードでは出来ない。
ライドだろ
まぁ、「オーバーロードでは出来ない」だけ抜き出せば確かにそうかもしれん。 レスとしては不適切だが、角度とか。
おれの読んだ本にはメンバ関数にはすべて virtual をつけろと書いてあったので、 その通りにほとんど全メンバ関数につけている。
>231 俺、わりとfriend classとコンボでprivate virtual使うなぁ。 こいつの為のインターフェイスですよ。って明示的な感じだし。
>>231 理由が
>virtual 宣言した時と比べて 4 byte 節約・・・
かよ。virtualで宣言しているメリットと比較するとあまりに弱いな。
組み込み型でメモリとぼしいなら最初からC使っとけって気もするし。
なんだかねぇ。
>233 あくまで一例だろ。 non virtualの利点が思いつかないなら、C++なんぞやらずにJavaつかっとけ。
>>234 ちょっと読んでみたけど
> virtual キーワードがあるのは、このようにコストを減らせるようにするためです。
> int 型のデータメンバを1つしかもたないようなクラスでは、virtual にした場合、virtual
> にしないのと比べてコストが2倍になります。これはかなり大きな違いです。
アホかと思った。これ読んだ時点でその後読む気なくすなぁ・・
JavaあがりのC++プログラマいわく なんにも考えないですべてバーチャルにしとけばいいじゃん
すべて Virtual で正解
コンストラクタもかよ
>>236 ぶっちゃけ Palm で開発してたときはそうしたけど
さすがに人に勧めるようなことは言いたくない
SDLのようにマルチプラットフォーム対応のプログラムを 自作するにはどうすればいんですか?
>>240 対応するプラットフォームについて熟知すべし
c++初心者なんですが、 char *operator<<(bookmark obj1){ return obj1.title; } 呼び出し時に cout << obj; (上のクラスオブジェクト) という風に使います。 警告:関数の戻り値が自動変数のポインタ/参照となっています。 (return obj1.title;) エラー:不当なオペランドです。 (cout << obj;) って、出ます。お教えお願いします。
(std::ostream& os, bookmark obj1) { return os << obj1.title; } じゃないのか
std::ostream &operator<<(std::ostream &os, bookmark obj1) { return os << obj1.title; }
virtualって、奥が深いんだな
>>243 >>244 勘違いしてました。stdクラスではない方のクラス内で定義しよう
としてた。おかげで、思うように動きました。
ありがとうございました。
メンバtitleはプライベートなので
そのままでは使えないのでメソッドでchar*を返すようにして
使ったんですけど、なんか回りくどいような気がするんですが、
どうなんでしょう。
これしか方法無いなら、無視して下さい。m(_ _)m
bookmark側をprivateにしたければこうするしかない。 char* bookmark::get_title(){return this->title;} std::ostream& operator<<(std::ostream &os, bookmark& obj1){return os << obj1.get_title();}
friend関数にすればいいじゃん
なるほど。。。friend関数ですか。 C++って奥が深いんですね。(泣) ていうか、全然分かって無い事が発覚。一からやります。 レスありがとう。
friendみたいに中を荒らされるのはやだな〜
>>250 自称友達ほど性質の悪いものはないよな。
>>250 メンバ関数という形をとっていないだけで、クラスbookmarkのインターフェースの一部なのだから、
privateなメンバにアクセスできても不自然ではない。
>>251 自分が相手をfriendと認めるだけであって、自称友達という表現は当てはまらない。
確かに自分が認めちゃったんだから荒らされても文句いえないやね。
>>252 そりゃそうなんだけどさ。ただ全体的にfriendはできるだけ
増やしたくないよな、ヒッキーみたいなこと言ってるけど。
クラスじゃないし、その場で実装が完結するから問題ないじゃないか。 オペレータはfriend関数で書くというのは一種の定石のひとつだし。
256 :
デフォルトの名無しさん :04/08/10 04:02
friend関数って、使うこと無いんだが。 俺はひょっとしておかしいのか?
>>252 自称友達だからfriendと認めるわけだから、当てはまらないわけではない。
>>256 二項演算子を作るときは使わないとしょうがない。
>>258 += で + 作ったりできるから、それでも必要になる場面は少ない。
class Hoge { public: Hoge& operator+=(const Hoge&); Hoge(const Hoge&); }; inline Hoge operator+(const Hoge& h1, const Hoge& h2) { return Hoge(h1) += h2; }
+をメンバ関数として実装して良いのは 他の型を引数に取らない 対称性を失ってもよい のどちらかになると思うんだが。 complex a = 1; a = 2 + a; string s = "abc" s = "123" + s;
あ、出来るのか。 ごめん、寝ぼけてた。
人が書いたソースを読むのってかなり勉強になるな。
265 :
デフォルトの名無しさん :04/08/10 15:33
has-a関係って、 class CHoge{}; class CBar { CHoge hoge; }; のことで、いいんだよね?
class hoge { public: hoge& operator +=( const hoge& ); hoge operator +( const hoge& r ) const { return hoge(*this) += r; } }; とか書いてたけど、ひょっとしてだめ?
VisualStudio.NET2003にて #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { char** p = (char**)new char[10][10]; p[0][0] = 1; return 0; } なんでp[0][0] = 1;のところで落ちるんですか?
メモリが確保されてないから。
正しくはこう char (*p)[10] = new char[10][10]; p[0][0] = 1;
引数付きのコンストラクタを持つオブジェクトの配列を動的に確保する方法ってありますか?
STLでいけるんですね。 でも、それを使うと実行ファイルが大きくなるっていう弊害が… 別に方法はないんですか…?そうですか…
STLつかうと一気に実行ファイルサイズが10倍に?!
>>274 環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない。
>>275 すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。
const int N = 10; Object *p=::operator new(sizeof(Object)*N); for(int i=0; i<N; ++i){ new(&p[i]) Object(好きな引数); }
>>277 uninitialized_fill使えよ
それぞれ違う値で初期化したかったら困るジャン
>>274-276 _| ̄|●
>>277 試してみたんですけど、二つエラーが出ます。理解が浅くて申し訳ないですけど、どこがいけないのででしょうか?
処理系はBCCです。
#include <iostream>
class test{
int a;
public:
test(int n){ a = n;}
int get_a(){ return a;}
};
int main()
{
const int N = 10;
test *p=::operator new (sizeof(test)*N); ←void *型はtest *型に変換できない
for(int i=0; i<N; ++i){
new (&p[i]) test(8);
}
for(int i=0; i<N; ++i){
cout << p[i] << "\n"; ←<< 演算子が使われたがクラス ostreamではtest型のための定義が存在しない
}
return 0;
}
>>277 uninitialized_fillを使うとどうなるんですか?よければ教えて貰えるとありがたいです
279さんが言うように違う値で初期化したい場合、方法ってあるんですか?
質問が多くてごめんなさい
訂正です。 コードの下のほう for(int i=0; i<N; ++i){ cout << p[i].get_a() << "\n"; } の間違いでした。これでエラーは一つ消えました。
>>281 >void *型はtest *型に変換できない
キャストしろ
うわっ、さらにdeleteもし忘れてる… もうだめかもorz
キャストしたら上手くいきました。ありがとうございます
#include <iostream>
#include <memory>
class test {
int a;
public:
test(int n) : a(n) {}
int get_a() const { return a; }
};
main()
{
const int N = 10;
test* p = static_cast<test*>(::operator new(sizeof(test)*N));
std::uninitialized_fill_n(p, N, 8);
for (int i=0; i<N; ++i) {
std::cout << p[i].get_a() << std::endl;
}
for (int i=0; i<N; ++i) {
p[i].~test();
}
::operator delete(p);
}
>>280 こうなる
>>285 とりあえず、コンパイラ通してみました。
いくつか理解できない表現がありますけど、勉強して一つ一つわかっていけるようにがんまります。
>>286 placement new(これ>new (&p[i]) test(8);)使うと
デストラクタは自分で呼ばないといけないから、注意
>>266 もし std::string の operator+ がメンバ関数で定義されていたら、
○ std::string("xxx") + "yyy"
× "xxx" + std::string("yyy")
というような非対称性が生じる。
型変換用のコンストラクタがなければ実害はないかもしれない。
>>280 > 279さんが言うように違う値で初期化したい場合、方法ってあるんですか?
uninitialized_fill() のかわりに uninitialized_copy() を使う。
引数は単純な配列でいいだろう。
しかし、 std::vector 使っとけ。
291 :
ディフォルトの名無しさん :04/08/11 13:52
VC6.0で2つのダイアログ(1つはメニュー画面表示用+1つは実処理部)のような 構成で作成しようと思っています。 メインのダイアログで、1つはcreateでもう1つはDoModalで2枚のフォームを 描画させているのですが、そうするとタスクバーのアイコンが2つ表示されて しまいます。 なんとかして1つのみの表示にすることはできないでしょうか?
292 :
デフォルトの名無しさん :04/08/11 18:06
ヒープメモリ上にクラスのインスタンスを作成する場合、 newを使えばクラスのコンストラクタが自動的に呼ばれるんですが、 mallocでメモリを確保してコンストラクタを呼ぶということは出来ないんでしょうか。
placement new
297 :
デフォルトの名無しさん :04/08/11 18:43
cでenumは使えまつか?
>294 写真をとるときの掛け声
はい、ちーにゅう
微妙に中国語っぽいな
私への充て付けか?<ちい(さい)にゅう
303 :
デフォルトの名無しさん :04/08/12 12:12
はい、貧乳
長所新車です。 Cは数値計算とかくらいしかやったことないんだけど、簡単な反復マクロを書きたいんだけど、 sendkey sleep の使い方を教えて下さい。
>sendkey >sleep Cの話と違うし
>>306 そのメッセージがわかんないのですよ。
enterを送るときとか nを送るときにどうしたらいいかってことが。
309 :
デフォルトの名無しさん :04/08/12 14:52
winです。
わざとやってるのか?
311 :
デフォルトの名無しさん :04/08/12 15:22
素です。
例えば nを押す 0.2秒 nを離す ってのはCではどう書けばいいのかってことですたい。
>>312 の通りだとこうなるけどsendkeyなんてものはない、VBAのSendKeysのことか。
keybd_event(N, 0, 0, 0);
Sleep(200);
keybd_event(N, 0, KEYEVENTF_KEYUP, 0);
315 :
デフォルトの名無しさん :04/08/12 15:39
>>313 暇つぶしです。
できれば数値計算の結果をテキストにためて行くような形にしようかと思ってます。
パチスロ何かにも応用できるんですかね?
316 :
デフォルトの名無しさん :04/08/12 15:40
>>314 ありがとうです。
sendkeyってのは言い方を思いつかなかったので使いました。
317 :
ディフォルトの名無しさん :04/08/12 19:05
VC6.0で2つのダイアログ(1つはメニュー画面表示用+1つは実処理部)のような 構成で作成しようと思っています。 メインのダイアログで、1つはcreateでもう1つはDoModalで2枚のフォームを 描画させています。 モードレス側のダイアログを ModifyStyleEx(WS_EX_APPWINDOW, 0); にて、アイコンを消すことが出来たのですが、ダイアログが背面に移動した 際、もう片方のダイアログを前面に持ってきた際に移動することが出来ず、 背面に残ったままになってしまいます、 現在表示されている1つのアイコンで2つのダイアログの表示位置を平行に (同じ階層)に表示することは出来ないでしょうか?
>>316 お前定義の適当な単語出して教えてください、って頭腐ってるな。
>>318 こんなとこで叩いてるお前が腐ってる
確かにちょっとアホっぽいけど、ニュアンス的にわからんでもないし、初心者歓迎スレで初心者叩くな
320 :
デフォルトの名無しさん :04/08/12 20:16
学校の宿題をやっているのでが、分からない所があるので質問します。 1!+2!+3!+・・・+n!和が7777より小さい場合における最大のnと、 その時の和を求めるプログラムをfor文を用いて作成せよ。 という問題なのですが、とりあえず int wa=0; for(int n=1;wa<7777;n++){ int m=1; for(int i=n;i>=1;i--){ m=m*i; } cout << "階乗は" << m << "\n"; wa=wa+m; cout << "和は" << wa << "\n"; } cout << "最大のnは" << n-1 << "\n"; cout << "その時の和は" << wa-m << "\n"; と記述して実行しようとしたら「cout << "その時の和は" << wa-m << "\n";」の部分で 「mが未定義です」とエラーが表示されてしまいました。for文内で定義した関数は for文外では使用できないのでしょうか? また、その部分を無視して実行した時、なぜか最大のnの値が9と表示されてしまいます。。 試しにfor文内にcout文を入れて実行してみたら正しくnの値は8と表示されるのですが。。 なぜこの違いが発生するのでしょうか・・・。 長くなりましたがどなたか教えてください。。
>>319 こんタコが、初心者と雑草は叩かれて踏まれて強くなんだよ
>>320 変数は宣言したブロックの中だけで有効。
つまりこの場合外側のforの中だけ。
それとint m=1はforのループのたびに実行される。
>>320 >for文内で定義した関数は
変数だろ。
>for文外では使用できないのでしょうか?
出来ない。
>なぜか最大のnの値が9と表示されてしまいます。。
>for(int n=1;wa<7777;n++){
このfor文を出る前にn++されるから。
324 :
デフォルトの名無しさん :04/08/12 20:34
>>322 ,323
ありがとうございます。
勉強になりました。
cout << "最大のnは" << n-1 << "\n"; (n-1)になってるからいいんじゃないの? cout << "その時の和は" << wa-m << "\n"; なんでmを引くの?
そもそもnも変数の使用できる範囲超えて使われてる
>>321 TPOも無視してただただ踏んで回るしか能の無い「自称回答者」は
臭いから来なくていいです ;-)
>>327 お前も十分臭いよ 腐臭をあちこちのスレに撒き散らすなボケ ;-)
329 :
デフォルトの名無しさん :04/08/13 13:10
>>328 意味不明ですね。
「あちこちのスレ」など関係無く、このスレの話なわけです。
致命的な点を指摘されて悔しいのはわかりましたが、それならなおのこと
ちゃんとした理屈をこさえてから書き込まなくてはいけないと思いますよ。
馬鹿にしか見えませんから ;-)
;-) ウンコマンが大好きな顔文字。臭いからこないでねw
2chの定理:最後にレスしたほうが負け
テンプレートクラスで自分のクラスを引数に取る場合 例えばコピーコンストラクタで template<class T> class A { public: A(const A&) {} // A(const A<T>&) {} }; この2つは等価なのでしょうか? 試したところ同じようですが、何か違いがあったりするんでしょうか?
>>334 VC++6.0SP6のデバッグビルドで出来たコードを比較してみましたが
違いは見られませんでした。
サイズが増える要因はなんでしょうか?
もしかすると>334は、 (ソースコードの)サイズが増える と言いたかったのではないであろうか?
>>333 同じ。
クラステンプレートの名前と同じ名前を、名前空間の修辞をつけず、後ろに "<" を続けなければ、
A<T>のようなテンプレート引数リストをつけた型名と同じになる。
LSI-C使ってます。 ”#include <curses.h>”という記述を含むものをコンパイルしようとすると、 ”インクルードファイル 'curses.h' をオープンできない”と表示されます。 ライブラリにcurses.hが存在しないみたいなんですが、どういった対処法がありますか?
>>339 curses.hの入ったライブラリをインストールするとか.
>>339 LSI-Cを捨てる。
冗談は兎も角、16ビットコンパイラでしかないLSI-Cから安定して使える
cursesライブラリを探すくらいなら32ビットコンパイラに移行した方がいい。
例えばcygwinなら環境ごと丸々揃えられるだろ。
342 :
デフォルトの名無しさん :04/08/14 10:40
ツールバーを表示したいのですが、サンプルソース通りにやっても正常に動作しません。 どうしてでしょうか。 【状況】 コンパイルは通るが、できた実行ファイルを実行すると、 ウィンドウも表示されぬままに強制終了してしまう。 サンプルのコピペも試してみたけれど、同様の状況。 【参考にしたサンプル】 猫でもわかるのステータスバーの項1 【環境】 WindowsXP BCC5.5
先ほどはCreateToolbarExでやっていたのですが、 今度はCreateWindowExでやってみました。 これもまた上手くいきませんでした。 なぜでしょうか? 【状況】 コンパイルは通る。 できた実行ファイルを実行すると、ウィンドウは表示されるが ツールバーは下地(?)だけしか表示されない。 そこをクリックしても反応がなく、 ダブルクリックすると見たことのないダイアログがほんの一瞬表示されて消える。 【参考にしたサンプル】 猫でもわかるのステータスバーの項3 【環境】 WindowsXP BCC5.5
344 :
デフォルトの名無しさん :04/08/14 13:39
>>344 0から始まった方(0オフセット)がCでは美しいし,普通でしょうね.
あと,テンプレートのTはきっとcharに限らないのだろうから
int Tokenize(T* buf, const T &code, int limit)
の方が良いのでは?
346 :
デフォルトの名無しさん :04/08/14 14:17
>>345 なるほど。
オブジェクトのコピーが負荷になる場合を考えてって理解でいいですか?
どうもありがとうございます。
考えすぎて眠れませんでした。
>>344 こんな感じでいいんじゃないでしょうか?
bufも中は触らないのでconst付けました.
template <class T>
int Tokenize(const T* buf, const T &code, int limit) {
for (int iCurPos (0); iCurPos < limit; ++ iCurPos)
if(buf [iCurPos] == code) return iCurPos;
return -1;
};
348 :
デフォルトの名無しさん :04/08/14 14:22
だめだ…分からない… 今日は丸一日使ったが分からない。 分かったことと言えば… 【分かったこと】 ※CreateToolbarExを使った場合。 リソースファイルをリンク(?)しない状態ではツールバーが表示される(画像なし・ボタンだけ)動作は正常。 リソースファイルをリンク(?)すると、起動した瞬間にウィンドウも開かず強制終了する。 誰か分かる方よろしくお願い致します。
>>349 ソースも上げないでその字面だけで判断するのは不可能だ
猫はビュー数を見れば分かるとおり、多数の人が利用しているわけで
起動しないほどの重大なバグがある可能性はきわめて低い
猫の所為にしないで自分に原因があると考えるのが自然だ。
で、どうしても写し間違いが無いと言い張るのなら
一つ一つのAPIの戻り値をチェックしてエラーが出ている個所を突き止めろ。
>>350 ありがとうございます。
APIの戻り値チェックというのをやってみます。
/*
写し間違いはないと思います。
最初は全部手で打ち込んでいたのですが、
この不具合の原因に見当が付かないのでコピペでも試してみました。
結果は同じでした。
*/
352 :
デフォルトの名無しさん :04/08/15 01:30
質問です。 ファイルから、一行の文字列を読み込んでbuf[1024]の配列に、 a bc d efg\n\0 が入っているとすると、そのスペースを区切りにして、 新たなa[32][128]の配列に、 a[0]→a\0 a[1]→bc\0 a[2]→d\0 a[3]→efg\0 と入れたいのですが、どうしたらできますか?
char *t=strtok(buf, " \n"); char (*p)[128]=a; while (p) { strncpy(a++, t, 128); t=(0," \n"); }
while (t) { strncpy(p++, t, 128); t=(0," \n"); }
どうもでした。 strtokや、strncpyを調べてみます。
ありがとうございます。なんとかできました。
ええっと最近VC++をはじめたのですが、 void CMyDlg::OnBnClickedSerch() { MessageBox("やぁ"); } こうかくとMFCのMessageBox関数が呼ばれるのですが、 APIのMessageBox関数を呼ぶにはどうすればいいのですか?
::
APIチェックの戻り値を調べるのがよく分からなかったので、
さらにツールバーのサンプルを探してみたのですが、
BMP画像に問題があるようです。
【状況】
サンプルのツールバーのBMP画像を、
自作したもの(大きさ・数は同じ)に差し替えただけで、
ウィンドウも開かずに強制終了する。
>>342 と同じ状況。
サンプルと同じ色数、それ以下の色数でも試したが結果は同じ。
CPP、Hファイルを全く変更せずに試したので、写し間違い等のミスは皆無です。
付属していた画像をそのまま使った場合は期待通りの結果が得られる。
ツールバー用のBMP画像を作るに当たって何らかの決まりがあるのかと思って検索してみましたが、
その事について特に言及してあるサイトは見つかりませんでした。
原因が分かる方よろしくお願いします。
【参考にしたサンプル】
ttp://www.geocities.jp/kissy2005jp/documents/win32api-sample.html の『ツールバーを作る』のサンプルソース。
【環境】
WindowsXP
BCC5.5
Pixia(ツールバーのBMP画像を作るのに使用したペイントソフト)
自作したBMPとやらの仕様、 もしくはエラーが帰ってきたときのエラーコードくらい書けよ 具体的なことは何一つ言ってないじゃないか。
>>361 BMPは普通のBMPです。
エラーは帰ってこずに強制終了します。
普通って? ヘッダの形式は?色数は?RLEかかってる? トップダウンとボトムアップどっち?
>>363 すいません、分かりません。
調べてきます。
365 :
デフォルトの名無しさん :04/08/15 15:13
奇妙な現象が、、、 以下のコードが実行できます。 int main() { int sum=0; for(int i=0;i<5;i++) sum += i; sum=0; for(int i=0;i<5;i++) sum += i*i; } これはint iを2回宣言していることにならないのでしょうか? 環境はVC++.NETです
世の中には標準では無い仕様を 標準だと思いこんで使ってきてしまった人もいるのですね。
>>362 エラーはページ違反とかのダイアログの話ではなく、APIの戻り値を見るんだよ。
調査して説明しろといっても無理な相談だろうから、
どこかへのリンクではなく、実際に使っているソース一式と
正常な結果を得られるbmp、異常終了するbmpをまとめてあぷろだにあげとけ
いるのですyp!
370 :
デフォルトの名無しさん :04/08/15 15:18
365です。 C#からは変数のスコープが変更になり、 for(int i=0;;) ではiはfor内でのみ有効になったはずです。 でもC++はiはforの外でも有効だったはずです。
釣りだったか。気づくのが遅かった…
>>365 あのな・・・・実行できることじゃなくてコンパイルできることに疑問を持てよ。
浸透圧の高い液体で顔を洗うと痛いよ。
375 :
デフォルトの名無しさん :04/08/15 15:25
365です。
だからコンパイルできることがおかしいと言っています!!!
しかも実行もできます。
仕様が変更になったはずはないので、、、
>オプションでエラー吐かせる事もできる
これはどうすればいいのでしょうか?
>>369 、
マジレスするとコンパイルできない方がおかしい。 昔のVC++はおかしな糞コンパイラだった。 以上。
377 :
デフォルトの名無しさん :04/08/15 15:29
C++の仕様ではコンパイルできないはずです。 { for(int i;;) } とすればiのスコープはfor内だけですが、、
int main() { int sum=0; for(int i=0;i<5;i++) sum += i; sum=0; for(int i=0;i<5;i++) sum += i*i; } forの外でi使ってるようには見えないが。
379 :
デフォルトの名無しさん :04/08/15 15:31
>>376 今のC++の仕様が策定される前のコンパイラを責めるなよ。
多機能(各々に任す)計算機のプログラムを作成せよ。ソースの説明をせよ。 という問題の答えを教えていただきたいです。
宿題は宿題スレへ
382 :
デフォルトの名無しさん :04/08/15 15:33
365です。 以前は、 for(int i=0;i<10;i++){ sum += i; if(i>3) break; } for(int j=i;j<10;j++) sum += j*j; といった高度な書き方ができたはずです!! 少なくともVC6.0では
>>382 安心しろ。あなたが高度じゃないだけだから。
384 :
デフォルトの名無しさん :04/08/15 15:34
int i; for(i=0;i<10;i++){ にすればいいだけだろ。アホか。
全部自作自演とか
386 :
デフォルトの名無しさん :04/08/15 15:37
365です。 まあ、仕様の不完全なC++ではなく、C#を使うのでまったく問題ありませんが、、、
{int i; for(i=0;i<10;i++){
君の脳はさぞかし不完全なんだろうな
390 :
デフォルトの名無しさん :04/08/15 15:41
for(int i=0;;){ } for(int i=0;;){ } がコンパイルできたり、できなかったりするところが不完全ですが何か? ちなみにVS.NET Proを使ってますが何か?
>>390 それは、「不完全なコンパイラが存在する」と言っているだけ。
┌─────────┐ │ 基地外警報!!! | │ 基地外警報!! | └―――──――――┘ ヽ(´ー`)ノ ( へ) く
>>390 コンパイルできたり、できなかったりするのは天候の所為ですよ。
引田天功
>コンパイルできたり、できなかったりするのは天候の所為ですよ。
須らくデウスの行いだと?
>>390 君は丁度、C++の変遷を目の当たりにできる僥倖に遭遇できたのだよ。
>>359 ぉぉ、できました。どもありがとうです。
あともうひとつ、
int len;
char A[100] = "abcde";
len = strlen(A);
こうすると"size_tをintに変換しました。"という警告がでます。
警告が出ないようにするにはどうすればいいんですか?
>>397 size_t len;
char A[100] = "abcde";
len = strlen(A);
マニュアルくらい読んでから質問しろ
システムカラーで書けばええやん
>>401 ありがとうございます。
システムカラーというのを調べてみます。
コンソールプログラムで、キー入力があったときに ループから抜けるようにしたいのですが、どうやったら可能でしょうか? gcc-cygwin環境です、よろしくお願いします。 >#include <stdio.h> >int main() >{ > int c; > c = getchar(); > while(c == EOF){ > function1(); > c = getchar(); > } > function2(); > return 0; >}
kbhit
407 :
デフォルトの名無しさん :04/08/15 23:48
selectじゃあ・・・
C言語を練習するとき、どんなプログラムを作ると良いですか? 今使えるのがprintf、scanf、while、for、switch、ファイルの入出力くらいなんですけど
住所録
DWORD型(unsigned long)の変数をlong型に変換する方法ってあります?
ありがとうございます。 ncurses-5.4をインストールしまして、 #include <ncurses.h>を加えて gcc には -lncursesオプションを渡しましたが undefined reference to `_kbhit' と怒られました。 行き詰まりましたのでまた後で挑戦します...
conio
415 :
デフォルトの名無しさん :04/08/16 01:58
VisualCでSTLのStringを使いたいんですが、 文字列に改行を入れたい場合どうすればいいんでしょうか。 string str("abcd"); str=str+'\n'+"ABCD"; SetWindowText(GetDlgItem(hDlg,IDC_EDIT),str.c_str()); という感じで標準コントロールのエディットボックスに 文字を表示させてみてるんですが「abcdABCD」となり改行してくれません。 どなたか教えてください。お願いします。
416 :
デフォルトの名無しさん :04/08/16 01:59
即レスありがとうございます。助かりました。
418 :
デフォルトの名無しさん :04/08/16 03:31
std::fstreamで開いてるファイルのサイズを、 現状より短くしたい(後ろを切り捨てたい)んだけど、 なんかいい方法ある?
419 :
デフォルトの名無しさん :04/08/16 03:36
>>418 UNIXならtruncateとかftruncateがあるな。
'\r' == 0x0D '\n' == 0x0A っていう理解でよろしいでしょうか?
>>419 それだとfstreamで開いてるファイル
いったん閉じた方がよさげだよね
くっ、やはりそういう環境依存な方法しかないのか
>>423 小さいファイルなら内容を全部覚えておいて、
新たにファイル作成するって方法もある。
でも、そんなことするぐらいなら環境依存な
方法を使った方がいい罠。
425 :
デフォルトの名無しさん :04/08/16 18:25
さっきまでバグはありつつもコンパイルはエラー無しで通っていて いろいろ弄りながら試行錯誤でバグ潰ししてたんですが、 なにをやってしまったのか急にリンクエラーが出ました。 error LNK2001: 外部シンボル 〜 は未解決です fatal error LNK1120: 外部参照 1 が未解決です。 みたいな感じです。 Libのリンク設定忘れみたいな環境的なこと意外で こういうエラーって出るもんですか?
どっかの変数にstatic付けてしまったとか?
引数書くの忘れてる関数定義がありました… お恥ずかしい。 なんかライブラリのファイル壊れたかなぁとか思って 再インスコしそうなところでした。助かりました。 ありがとうございました。
住所録が完成しました 次は何を作るのが良いですか?
ホヤの養殖
433 :
教えてください :04/08/16 21:09
遅くなってすみません。 MinGWでは可能なのですが、Cygwinではconio.h(のkbhit)が使えなかったようです。 ずいぶん長いこと混乱していましたが、ncurses.hのgetch()を使ってようやく解決しました。 select()は難しそうなので結局断念しました。 どうもありがとうございます。
435 :
デフォルトの名無しさん :04/08/16 23:36
猫でもわかるで復習しています。 C言語編の第1部の26章でつまづきました。 エスケープシーケンスで、色を変えるプログラムが出てくるのですが、 エスケープシーケンスが普通に文字列として解釈されてしまいます。 これは、なぜなのでしょうか。
NT系のOSでは無理です
レスありがとうございます。 そうなのですか。 NT系だとなぜ使えないのでしょうか?
無理じゃねえよ。 16bitコンパイラとansi.sys組み込み。
cygwinを使うとか。
16bitコードを吐くコンパイラがないとだめなんですね。 簡単に実現する方法としては、cygwinでエミュレートするということですね。 どちらかの方法で実現してみます。 ありがとうございました。
441 :
デフォルトの名無しさん :04/08/17 20:01
std::stringメンバの入った構造体をmemsetするとアドレス違反になります。 構造体にstringは駄目で塚?
>>441 一般にオブジェクトの内部に直接触れるべきではない。コンストラクタを使って適切
に初期化する必要がある。
メンバ変数をprivateとして宣言するのは何のためか考えてみるといい。
>442 何か斜め上行ってますね。
444 :
マイク ◆yrBrqfF1Ew :04/08/17 22:03
>>441 そういえばvtbl overwriteというsecurity-holeがあった気がするな。
すごいアホな質問なんですが外部クラスを利用するときはヘッダとcppに分けて書くのが一般的だと思うのですが ヘッダにクラスの実装を直接書くこともできるのはわかるんですが、これは分けて書く場合と比べてどのように違うのでしょうか。
>>445 中間ファイルとかLib作るのにヘッダにガリガリ書かないな
GNU G++ の STL とかはヘッダにガリガリ書いてるね
テンプレートクラスはインクルードファイルに書くしかないしな。
>>446-447 ありがとうございます。
>>448 ありがとうございます。
実はその点についても聞こうとしていたのですが、テンプレートクラスはヘッダとcppに分けたとき、外部参照が未解決のようなエラーが出て、
ヘッダにまとめて書いたら正しく動作した覚えがあります。
このことからテンプレートクラスの場合はヘッダにまとめて書くのが一般的なのかと思ったのですがどうなんでしょうか。
450 :
デフォルトの名無しさん :04/08/17 23:06
他人のソース見てるんですが、 ヘッダに書かれているDECLAREってなんですか? 例えば DECLARE( int A, ;); って感じで書かれてます。 どういうときに、どんな意味で使うものなんでしょうか?
>>450 ヘッダすべてをDECLAREで検索してみ
>>451 すいません、ちょっと意味が、、、
どのヘッダもあんな感じに書かれてますが、
本とかでも見たことないし、よく分からないであります。
>>452 どっかで DECLARE が定義されてるはずだからそれを探せ、
という意味だと思う
#define DECLARE(...) ....
みたいなのがどっかにあるはず(インクルードファイルも遡って探してね)
発見しました。 なんかグローバル変数の宣言用にdefineしてあったみたいですが、 何の意味があるのか訳わかんないです。 気持ち悪いですがしばらく放っておくことにします。。。 ありがとうございました。
return rush;
456 :
デフォルトの名無しさん :04/08/18 02:12
return ace;
458 :
デフォルトの名無しさん :04/08/18 02:48
質問です。 言語はC++です。 int型の数値をchar型の文字列に変換したいときは どのような関数を作ればよいですか? 同じように、 double→char など。 初心者の質問で申し訳ないですが 宜しくお願いします。
C++ならstringstream
itoa() itof()
itof()ってあるの?
いらねーだろ。
パパー2匹釣れたよ!
渓流行って足滑らせて死ね!
>>464 もしかして、スレのテンプレ入りを狙ってるのか?
class A { public: void Func(){} } aa; struct B { int b; } bb; float cc() { return 1.0f; } // アドレステーブル void *Adr[] = { (void*)&aa, (void*)&bb.b, (void*)&cc, }; というような、なんでもありの配列 Adr の初期値に、 aa.Func() のアドレスを入れたいのですが、うまくいきません。 // アドレステーブル void *Adr[] = { (void*)&aa.Func, // error (void*)&bb.b, (void*)&cc, }; とすると、void を void* にキャストできないとエラーが出ます。 どのようにすればよいのか、アドバイスをお願いします。
&aa::Func じゃない?
それ以前に「なんでもありの配列」を作ること自体どうかしている。
インスタンスメソッドを、インスタンスの指定無しで呼び出せるわけ無いだろハゲ
>>467 C++ では「メンバ関数のポインタ」は取れても、特定インスタンスに
結び付けられたメンバ関数ポインタ(いわゆるクロージャ)は取れん。
やりたければ boost::function と boost::bind 使え。
あとメンバ関数ポインタのサイズは一般に sizeof(void*) よりでかい
から、そのキャストは規格上許可されてない。
皆さん色々ありがとうございました。 このやり方では無理なのですね…。 ”静的なインスタンスのメンバ関数”の「先頭アドレス」を コンパイルの時点で知ることができれば、 どのようなやり方でも構わないんですが、 何か良い方法はないでしょうか…。
>>473 なんか勘違いしてないか?
メンバ関数はインスタンスごとに生成されるわけじゃなく、
共通の関数にインスタンスの参照が渡される。
特定のインスタンスの特定のメンバ関数を呼びたいなら、
インスタンスの参照とメンバ関数のアドレス(メンバ関数ポインタ)の両方が必要。
これをまとめて使いやすくしたのがboost::functionやboost::bind
MAPファイルの生成ではダメなの?
インスタンスのメンバ関数をコールバック関数として登録したいんじゃない?
SigC++だな
>>467 で言うような事が実現出来たとしても、キャストする前の型が判らなければ、
void*型のポインタだけがあってもどうしようもないと思う。具体的にどういう使い
方をするのか判らないので憶測でしかないけどね。
ということで、boost::function辺りを使うのが吉かと。
480 :
デフォルトの名無しさん :04/08/18 19:30
VC++6で while(!fin.eof()){ fin >> str1; tp = strtok(str1,"<>");//<>で区切った文字列 cout << tp; while(tp != NULL){ tp = strtok(NULL,"<>"); if(tp != NULL){ cout << tp; } } } と書いたら実行はされるが、Windowsエラーが出てしまう。 while(!fin.eof()){ fin >> str1; cout << str1; } だと出ない。なんで?
tp = strtok(str1,"<>");//<>で区切った文字列 if(tp != NULL){ cout << tp;
482 :
デフォルトの名無しさん :04/08/19 01:33
#ifnde __HOGE_H__ #define __HOGE_H__ って、書くのが面倒なんだけど、ほかに方法ない? VC2003つかってます。
>>482 二連アンスコやめとけ。
アンスコはじまりやめとけ。
#pragma once 使え。
484 :
デフォルトの名無しさん :04/08/19 01:44
たかが三行(#endifを含めて)書くのがそんなに面倒なのか
doui
486 :
デフォルトの名無しさん :04/08/19 01:53
#pragma once って、MS限定?
>>486 そんなことないけど対応してるものは少ない
488 :
デフォルトの名無しさん :04/08/19 03:42
デジタルカメラからの動画像をリアルタイムで 取り込み、表示させる方法を知っている人いません? OpenCVやARToolKit等のライブラリを使わないで 1からCでプログラミングするのって難しいのでしょうか??
489 :
デフォルトの名無しさん :04/08/19 04:39
mage
>>488 君がやりたければやればいい。
難しいと思うのならやめとけ。
491 :
デフォルトの名無しさん :04/08/19 21:32
猫でC++でも勉強しようとしてたところオーバーライドのところで class Moto{ public: virtual int kaso();}; class Saki : public Moto{ public: int kaso();}; int Moto::kaso(void){ cout << "継承元です" << endl; return 0;} int Saki::kaso(void){ cout << "オーバーライドしました" << endl; return 0;} とあったところ、virtual int kaso()をint kaso()に変えてみると コンパイル時にエラーがでるか、オーバーライドされないと思ってたのですが 普通にオーバーライドされてました。オーバーライドはvirtualつけなくても出来るのでしょうか?
>>492 そうなんですか。そうなるとvirtualの意味って何なんでしょうか・・・
"virtual"を付けなくても自動的に(必ず)仮想関数になるってこと。 引数その他が違ったら別だけどね。
C++は猫で勉強しないほうがいいよ。
496 :
デフォルトの名無しさん :04/08/19 23:36
コンストラクタにvirtualをつける意味は?
オーバーライドとオーバーロードの区別は出来てる?
499 :
デフォルトの名無しさん :04/08/19 23:43
CreateWindowExで作ったメッセージボックスのみを半透明にする方法はないでしょうか? SetLayeredWindowAttributesではできないみたいなんです(ウィンドウ全体なら可能)
>>498 嘘ではなかろう。言葉足らずだが
基本クラスでの宣言でvirtual宣言されてるから
派生クラスのは明示的にvirtualしなくても勝手にそうなるってだけ。
おう、まさしく勘違い。
>>500 のことを言いたかった。
やっぱり半透明化以外にも、 エディットコントロールの… フォントのサイズ変更、 フォントの種類変更、 フォントの色変更、 背景色変更、 の仕方が分かりません。 リッチエディットまではいかなくてもWindows付属のメモ帳くらい変更したいのですが。
リッチエディットを勉強したほうが早いですか?
506 :
デフォルトの名無しさん :04/08/20 00:37
508 :
デフォルトの名無しさん :04/08/22 02:14
/bin/hosh
509 :
デフォルトの名無しさん :04/08/22 02:29
質問です。 以下の式を実行させると、 for(double a=-0.3; a<0.8; a+=0.1){ cout << a << endl; } 以下のようになるのですが... -0.3 -0.2 -0.1 2.77556e-017 <= 0にならない 0.1 0.2 (省略) 0.7 0.8 <= ここまで繰り返される ようするに、2.775563-017を0に、 繰り返しも11回に留めたいのですが、 どうすればよろしいですか? 環境は Windows ME Visual C++ 6.0 です。 よろしくお願いします。
>>509 for(int a=-3;a<8;a++){
cout << a/10. << endl;
}
>>510 レスありがとうございます。
その式だと、うまくいきました。
ですが、
for(double a=-0.3; a<0.8; a+=0.1){
cout << a << endl;
}
この式の何がいけないのか、よくわからないのですが
>>509 それは10進数表記の0.1が2進数表記では近似値的表記になる
ことに起因するもので、つまり0.1を3回足すのと0.3を足した結果
とは同値でない可能性があるということです。よって不可能です。
もしどうしてもそうしたければ、固定小数点数を使うことをお勧め
します(自分でエミュレートすることになります)。
514 :
デフォルトの名無しさん :04/08/22 02:50
IMEだと不動小数点数
>>511 0.1は2進数では正確に表せない。(現行の浮動小数点では)
#include <stdio.h>
void main(void){
printf("%64.62lf\n",0.1");
}
とかやってみ。
517 :
デフォルトの名無しさん :04/08/22 03:05
(゚Д゚)ハァ?
520 :
デフォルトの名無しさん :04/08/22 03:09
521 :
509, 511 :04/08/22 03:10
>>510 , 512, 513, 514, 515, 516
ググってみました。よくわかりました。
ありがとうございました。
Yahoo!のページ検索はGoogleと結果は同じだけど、結果のリンクを新しいウィンドウで表示するようにできないからまだいや。
524 :
デフォルトの名無しさん :04/08/22 06:41
初心者です。ええとこのページ
http://www.med.osaka-u.ac.jp/pub/cl-comp/saito/cppintro/cppintro8.html にvirtualをつけない(仮想関数でない場合)
>ポインタ変数p がクラスX へのポインタ変数と して定義されており、p の>指す実体がクラスX から派生したクラスY のオブジ ェクトである場合、
># 普通のメンバ関数 f()
>p->f()で、X::f()が呼び出される。クラスXでf()が定義されてないな ら、X >から親の方への検索で最初に見つかるf()の定義が用いられる。
との事ですがこのプログラム
http://www.med.osaka-u.ac.jp/pub/cl-comp/saito/cppintro/example3.cpp をコンパイルして実行した結果
私は「a型」オブジェクトです。
私は「B型」オブジェクトです。
私は「C型」オブジェクトです。
私は「a型」オブジェクトです。
私は「b型」オブジェクトです。
私は「c型」オブジェクトです。
私は「a型」オブジェクトです。
私は「b型」オブジェクトです。
私は「c型」オブジェクトです。
私は秘密のアッコちゃんです。
私は人に言えない秘密を持っています。
私は人に言えない秘密を持っています
となります。ええと説明文とおりだと
私は「a型」オブジェクトです。
私は「a型」オブジェクトです。
私は「a型」オブジェクトです。
私は秘密のアッコちゃんです。
私は人に言えない秘密を持っています。
私は人に言えない秘密を持っています
となるはずだと思うんですが。。違うんでしょうか?
あ、環境はRed Hat Linux 7.2 2.96-112.7.2 gcc version 2.96 です。そこのページで聞けよと言われればそれまでなんですがここの方が 早いかなと。しーましぇん。。
>>525 pa0->speak();
pa1->speak();
pa2->speak();
ここの部分でA::speakが呼ばれるってのはOKですか?
>>526 はい。それは分かるんですがそうすると実行結果が下のほうにかいた様に
なると思うんですが。。
A,B,Cそれぞれの型、およびそのインスタンスa,b,cについて idというメンバに何が入っているか理解してますか?
>>527 A::speakでprintfに渡されてる引数は何ですか?
あ、分かりました。コンストラクタで初期化とか全然考えてなかったです いやはずかしいです。。(;´∀`) ありがとうございました。
>>529 すいません。ここでコンストラクタで初期値を与えられたidを
出力してるんですね(ですよね(;´∀`)?)
>>517 既に「ググル」と言う言葉は、「インターネット検索サイトで検索する」と言う意味の一般動詞になってる。
>>532 はぁ ?
Windows環境 C++ C++のクラス内にWin32APIと同名の関数をつくりその同名の関数からWin32APIを呼び出すとC++のクラス内のほうを呼び出そうとするのですがどうすれば回避できますか?
aをbで割って余りを切り捨てた値を求めるのはどうやりますか?
>535 解決できました。 ありがとうございました。
>>536 int answer = static_cast<int>(a) / static_cast<int>(b);
539 :
509, 511 :04/08/22 12:52
以下のような処理をしたいのですが、どうしたらいいでしょうか? string a; strcpy(a, "hoge"); a = "hoge"でもいいのですが、 引数にchar* を取る場合の string型との互換の方法が知りたいので よろしくお願いします。
>>539 "hoge"をstringにしてから連結したほうが手っ取り早くないか?
>>539 a.resize(256);
strcpy(&a[0], "hoge");
規格的にいいのかは知らん
>>539 a.operator=("hoge");
a.assign("hoge");
>>541 文字列の長さ256になるけど。
>>542 じゃあ
>>541 の後に
a.resize(std::string::traits_type::length(a.c_str()));
> 引数にchar* を取る場合の > string型との互換の方法が知りたいので ここに突っ込みがないのは何故? 意味わかるの?
546 :
デフォルトの名無しさん :04/08/22 13:39
俺はわからん
>>545 CStringのGetBufferのようなもの、と解釈してみたがどうか?
548 :
デフォルトの名無しさん :04/08/22 13:42
文脈からして、char*を引数にとる関数でchar*の部分にstringを使いたいってことじゃないかな? そういう要望は多いと思うよ。 operator用意してる文字列クラスも多いことだし。
549 :
デフォルトの名無しさん :04/08/22 13:44
>>547 たぶん、GetBuffer()というよりは、operator LPCSTRみたいなことを希望してるんじゃないかな?
550 :
デフォルトの名無しさん :04/08/22 13:45
>>548 fgetsみたいに関数内で配列の中身を書き換えるもののこと?
551 :
デフォルトの名無しさん :04/08/22 13:48
>>550 あぁ、俺よく読んでなかった。
確かにどうとでも取れるね・・・
>>548 > 文脈からして、char*を引数にとる関数でchar*の部分にstringを使いたいってことじゃないかな?
すいません、そういう意味です。
553 :
デフォルトの名無しさん :04/08/22 14:00
>>536 整数なら単に割ればいい。
浮動小数点数なら割った答えにmodfを使って整数の部分を取り出す。
554 :
デフォルトの名無しさん :04/08/22 14:01
>>552 char const* なら std::string::c_str() だが、 char* なら無理。
std::string使うことに決めたなら、おとなしく適切なメンバ関数(および演算子)使え。
c_str() は駄目なんか。書き換えはいかんけど。 書き換えられる場合は string の operator=()、 operator+()でまかなえることがほとんどだと思うんだがなあ。
すまん著しくかぶった…
>>552 std::string に直接書き込むことはできない。一般に std::string は同一の記憶域を
複数の変数で使いまわす可能性がある(そうやってコピーが手軽にできるように
細工してる)から、勝手に書き換えるとほかにも影響が及ぶので。
std::string から char const* に変換したいなら std::string のメンバ関数 c_str() を
使えば良い、そうではなく書き込みたいなら
>>554 の言うように一旦 char 配列に
書き込んで operator=() なり assign() なりでコピーする。
あとコピーや読み出しよりも書き込みが頻繁に発生するなら、std::string やめて
std::vector<char> 使うって手もある。
560 :
デフォルトの名無しさん :04/08/22 14:35
ところで、自分でoperator造って使ってる人ってどれくらいいる? いちいちc_strしてる? 自分、標準C++ライブラリ使わないのでちょっと疑問に思ったんだけど。
>>561 話の流れからして operator char const*() じゃないかと。
>>560 c_str()があるのに、いちいち自分でoperator造って使ってる人なんていないだろうな。
>563 暗黙の変換の怖さを知らない初心者が、 覚えたての機能で記述の楽をしようとか考えてるんじゃないの?
>>564 MFC の CString などには C 言語文字列型への暗黙の型変換があるので、
欲しいって気持ちも分かるけどな。
お世話になります。長くなりますがご容赦ください。 【目標】 各派生クラスについて、明示的に作成されたインスタンス の数を共通のインターフェースで求めたい。 ex) CBase *pBase; CDerivedA a1, a2; CDerivedB b1, b2, b3; pBase = &a1; cout << pBase->get_count() << endl; // 結果: 2 pBase = &b1; cout << pBase->get_count() << endl; // 結果: 3 【追加条件】 上記を実現するに当たって、基底クラスは複雑になっても 構わないので、派生クラスに記述すべき定義をできるだけ 減らしたい。 以下にこれまでの試行錯誤を載せます。
試行錯誤まだ〜?
【試行錯誤 1: private static 変数に格納】 // ここから class CBase { public: virtual int get_count()=0; }; class CDerivedA: public CBase { static int countA; public: void add_count() { countA++; } virtual int get_count() { return countA; } virtual ~CDerivedA() { countA--; } }; class CDerivedB: public CDerivedA { static int countB; public: void add_count() { countB++; } virtual int get_count() { return countB; } virtual ~CDerivedB() { countB--; } }; // ---- int CDerivedA::countA; int CDerivedB::countB; int main() { CBase *pBase; CDerivedA a1, a2; a1.add_count(); a2.add_count(); CDerivedB b1, b2, b3; b1.add_count(); b2.add_count(); b3.add_count(); ... } // ここまで
誰でも最初に思いつきそうな教科書的手法です。 一応目標は達成していますが、派生クラスに要求される 記述量が多く、先に示した追加条件を満足しません。 # コンストラクタ内でカウントするのが自然ですが、 # そうすると上の例では CDerivedB のコンストラクタが # CDerivedA のコンストラクタを呼び出し、意図しない # カウントをしてしまいます。 【試行錯誤2: クラス名をキーとするmapに格納】 // ここから class CBase { static std::map<std::string, int> count_map; public: CBase() {} virtual void add_count() { count_map[typeid(*this).name()]++; } virtual void sub_count() { count_map[typeid(*this).name()]++; } virtual int get_count() { return count_map[typeid(*this).name()]; } virtual ~CBase() { this->sub_count(); } }; class CDerivedA: public CBase {}; class CDerivedB: public CBase {};
// ---- map<string, int> CBase::count_map; int main() { CBase *pBase; CDerivedA a1, a2; a1.add_count(); a2.add_count(); CDerivedB b1, b2, b3; b1.add_count(); b2.add_count(); b3.add_count(); ... } // ここまで この手法で目標を達成でき、また追加条件も満足して いますが、いくつか不満が残ります。たとえば、typeinfo ライブラリに頼っている点。コンパイラ依存でやや気持ち 悪いです。他に、map の要素へのアクセス効率も気に なります。hash_map を使えば良いのでしょうけれど、 できるだけ標準ライブラリだけで済ませたいのです。 # add_count() もできれば削りたいです。。。 【まとめ】 以上で挙げた手法以外に、よりエレガントな方法があれば 是非ご教示ください。宜しくお願い致します。 連投、長レス、スマソ。
あぁぁ……!!! よく見たら先の試行錯誤、どちらもカウントを減らす処理が滅茶苦茶でしたorz 全然目標達成していません。 その辺りも含めて良い方法を、ヒントだけでも下されば幸いです。 教えて君でホントスマソ。
BをAから継承しない。
>>1 を読んだら、「質問が長いときは」なんてあるし……。
次からソース貼るときはラウンジ利用しますです。。。
試行錯誤の2つ目ですが、sub_count() でデクリメントすべきところを
誤ってインクリメントしていました。そこを直せば期待通りです。
試行錯誤1つ目はコンストラクタと同じ理由で、デストラクタでカウント
するとまずいので、新たに関数 sub_count() を用意して、スコープから
抜ける直前に呼ぶようにしたら直りました。init() と last() みたいで、
ちょっと情けない対処法です。お暇な方はご意見や改善策などについて
お返事くださいませ。
餅つけ漏れ。試行錯誤2もやはりデストラクタでカウントしようとすると
失敗してしまいます。結局 init(), last() 作戦に頼らざるを得ないようです。
>>572 お返事有り難うございます。継承を一度しか許さない、というのは
あらゆることが驚くほど簡単になるので、魅力的な選択肢ではあるのですが……。
もう少し粘ってみたい気持ちと半々です。
>>574 DerivedBは論理的にDerivedAでもあるのだから、
DerivedBのインスタンスが生成されたときにDerivedAのカウントが増えるのは自然。
>>572 が言っているのは継承を一度しか許さぬ云々ではなくそのことだと思う。
template <typename Derived>
struct countable {
protected:
countable(bool b) : top(b) {if(b) ++count;}
int get_count() {return count;}
~countable() {if(top) --count;}
private:
bool top;
static int count;
};
template <typename Derived>
int countable<Derived>::count;
class CBase {
virtual int get_count() = 0;
};
class CDerivedA: public CBase, private countable<CDerivedA> {
typedef countable<CDerivedA> countable_type;
public:
CDerivedA(bool top = true) : countable_type(top) {}
virtual int get_count() { return countable_type::get_count();}
};
class CDerivedB: public CDerivedA, private countable<CDerivedB> {
typedef countable<CDerivedB> countable_type;
public:
CDerivedB(bool top = true) : CDerivedA(false) , countable_type(top) {}
virtual int get_count() { return countable_type::get_count(); }
};
class CBase {
unsigned& (*Counter)();
public:
CBase(unsigned& (*CountFunc)()) : Counter(CountFunc) {Counter()++;}
~CBase() {Counter()--;}
unsigned get_count() {return Counter();}
};
template<typename T> class CMiddle : public CBase {
static unsigned Count;
static unsigned& Counter() {return Count;}
public:
CMiddle(unsigned& (*CountFunc)() = Counter) : CBase(CountFunc) {}
};
class CDerivedA: public CMiddle<CDerivedA> {};
class CDerivedB: public CMiddle<CDerivedB> {};
//-------
template<typename T> unsigned CMiddle<T>::Count;
int main()
{
CBase *pBase;
CDerivedA a1, a2;
CDerivedB b1, b2, b3;
pBase = &a1;
cout << pBase->get_count() << endl; // 結果: 2
pBase = &b1;
cout << pBase->get_count() << endl; // 結果: 3
}
こういうのはだめか?
>>570
俺が思いついた不自然な振る舞い方 class CBase { protected: CBase(int &instance_counter):InstanceCounter(instance_counter) {InstanceCounter++;} int &InstanceCounter; public: int get_count() {InstanceCounter;} virtual ~CBase(){InstanceCounter--;} }; class CDerivedA: public CBase { static int countA; public: CDerivedA() : CBase(countA) {} protected: CDerivedA(int &count) : CBase(count) {} }; class CDerivedB: public CDerivedA { static int countB; public: CDerivedB() : CDerivedA(countB) {} };
>>575 丁寧なお返事有り難うございます。
ふむふむ……。なるほど、B is A だから、そもそも B のインスタンスを
数えることは A のインスタンスを含めて数えることが自然なわけですね。
で、そこら辺をすっきりさせるために、テンプレートを使って各クラスごとに
カウンタ構造体を用意してやっているといったところでしょうか。
未だソースを読むのが遅いので、もう少し理解する時間をください。
>>576 代替案をありがとうございます。こちらもテンプレートを使って、
中間クラスを作ってそこで管理…。と、これまた理解が遅くて申し訳
ないのですが、パッと見たところ A や B からさらに派生した場合の
カウントが結局同じように失敗しそうな。うぅ、ちょっとテストしてみます
です。。。
>>577 >>572 続けてお返事ありがとうございます。
こ、これは……。こんなやり方もあるんですね。参考になります。
「不自然な期待」通りの結果になることを確認しましたが……、
他の御二方同様、もう少しソースを読む時間を下さいませ。
早くこれくらいのソースをパパッと読み書きできるようになりたいです。。。
それにしても、このスレの住人は良い人ばっかりだぁ(ノд;)
少し読めてきました。勘違いなどありましたら御暇なときにご指摘ください。
>>576 さんと
>>572 さんはアプローチが似ていて、末端クラスにのみカウンタの実体
を静的に置いて、基底または中間クラスに実体への参照や関数ポインタを非静的メンバ
に持っていますね。この構造は、なるほどごく自然で、目からうろこでした。
Base1 -(参照)-┬-> DerivedA (or Middle<DerivedA>) のカウンタ実体
Base2 -(参照)-┤
Base3 -(参照)-┘
Base4 -(参照)-─-> DerivedB (or Middle<DerivedB>) のカウンタ実体
特に
>>576 さんの方法は初めに示した「派生クラスの記述量を少なく」という
条件にも対応してくださっていて、ふむふむ、と、しかし相変わらず派生クラスを
もう一度派生する方法がわからず、色々試しています。
>>575 さんのアプローチは、中間クラスも末端クラスも、カウンタの実体を
バシバシ作っておいて、カウントする際に末端クラスへの派生か否かを
フラグに取っておいてあるようです。親クラスを分離する手法は参考になります。
御三方とも、回答有り難うございました。なんとか解決しそうです。
また機会がありましたら宜しくお願い致します。
>>569 569をちょっと変えてLoki::TypeInfoを使うってのは?
Loki::TypeInfoはstd::type_infoをコンテナに格納できるようにするラッパです.
#include <loki/LokiTypeInfo.h>
using namespace std;
class CBase {
static map<Loki::TypeInfo, int> count_map;
public:
virtual void add_count() {count_map[Loki::TypeInfo (typeid(*this))]++;}
virtual void sub_count() {count_map[Loki::TypeInfo (typeid(*this))]++;}
virtual int get_count() {return count_map[Loki::TypeInfo (typeid(*this))];}
virtual ~CBase() {this->sub_count();}
};
class CDerivedA: public CBase {};
class CDerivedB: public CBase {};
map<Loki::TypeInfo, int> CBase::count_map;
582 :
デフォルトの名無しさん :04/08/24 21:08
どうして例外処理というのは重宝されるのですか? ifでいいじゃないですか。
>>581 typeinfo構造体を丸ごとmapのkeyに持って来るようなものでしょうか?
それともhash関数に内部名を通すのかしら。 Loki や Boost について知識が
乏しいので改めて調べてみようと思います。
>>569 は設計からして救いようが
ありませんが、Loki は色々使いようがありそうですので、有り難く引き出しに
しまっておくことにします。貴重な情報を有り難うございました。
>>582 例外処理、というとC++では try/catch ブロックのことでしょうが、
if 文でのエラー処理と (機能面で) 決定的に違うのは、try で関数を
呼び出して、関数内で throw した例外が関数を「抜けた後」で catch
ブロックに届くという点だと理解しています。それこそ、何重にも渡って
深く関数を呼び出しても例外が届くのです。set_xxx 系関数は戻り値が
成功フラグだったりしますが、get_xxx 系関数はそういうわけに行かず、
重宝するのではないでしょうか。
ロベールのC++教室、第二部第46章あたりに説明されています。
ttp://www1.kcn.ne.jp/~robe/cpphtml/index.html 他に、if 形式と try/catch 形式とでエラーの意味的な分類をしている
ということをどこかで見た記憶がありますが、ちょっと思い出せません。
>>583 わざわざ丁寧なご説明をありがとうございました。
>>583 Loki::TypeInfoの中で保持しているのはtypeinfoのポインタみたいです.
コンテナに格納できるように
std::typeinfoにはないコピーコンストラクタ,代入演算子を実装して
operator==はstd::type_infoのoperator==を
operator<はstd::type_infoのbeforeを使っているようです.
>>585 おお。私もつい先ほど Loki::TypeInfo のヘッダファイルを確認してみました。
てっきり std::type_info を直接比較するのは効率が悪かろうと思っていたのですが、
そもそも std::type_info::operator==() が定義されていたのですね!
std::type_info は構造体ではなくクラスだったのですね!!衝撃です。
符号化規則と照合順はコンパイラ依存とのことですが、結果は保証されて
いそうですし、今まで必死こいて string で比較していた私はなんと愚か
だったことか。Loki を使うにせよ使わないにせよ、大変勉強になりました。
有り難うございました。
そのためのtype_infoなのに……
C言語初心者ですが、javaのeclipseみたいなc言語用の開発ツールは どういうものがあり、一番使いやすいものはどれになりますでしょうか? freeソフトでも有料ソフトでもよいので教えてください。よろしくお願いします
ものすご素人質問で申し訳ないのですがshowbaseというのはいったいどういうものなのでしょう。 cout << showbase << hex << &n2 << endl; という形で説明もナシで本で使われていて何のことなのかさっぱりわかりません・・
コードの貼り付け失敗。。 int n2 = 12345; int* pn = &n2; cout << showbase << dec << &n2 << endl; int n3 = reinterpret_cast<int>(pn); cout << n3 << endl;
>>588 eclipseってC++にも対応してなかったんでしたっけ?
CDTとかって検索で引っかかりますけど.
お願いします。頼むから教えてください
>>594 あちこちで聞きまくってるようだな、氏ねよ
596 :
デフォルトの名無しさん :04/08/25 22:04
597 :
デフォルトの名無しさん :04/08/26 00:03
char* buffer = new char [10]; で10byteのバッファを確保した場合 delete [] buffer; delete buffer []; どちらもコンパイル通るんですが、 どっちが正しいの???
>>597 下はふつう通りません。
使ってるコンパイラ何?
599 :
デフォルトの名無しさん :04/08/26 00:07
BCB5です
602 :
デフォルトの名無しさん :04/08/26 09:14
VC6です
質問です。 本を見ながら勉強しています。 本に紹介があった「LSI C-86 Ver 3.30c 試食版」というのを使ってます。 でも、これだと上手くいかなくてイライラしたので、vectorで「LightC体験版」というのも使ってみました。 どちらもMS-DOS上で動くコンパイラです。 で、あるソースコードを書いてコンパイルしてみたのですが、本がすすめるコンパイラ(上)ではコンパイルできず、 下のコンパイラではコンパイルできました。実行すると上手くいきます。 何がまずいんでしょうか? ソースコードを書きます。。 #include <stdio.h> int main() { int youso[] = {2,-1,3,2,4,5,-2,0}; printf("行列を指定\n",); printf("%d %d %d %d\n",youso[0],youso[1],youso[4],youso[5]); printf("%d %d %d %d\n",youso[2],youso[3],youso[6],youso[7]); printf("行列を掛け算\n",); int kake[4]; kake[0] = (youso[0])*(youso[4])+(youso[1]*youso[6]); kake[1] = (youso[0])*(youso[5])+(youso[1]*youso[7]); kake[2] = (youso[2])*(youso[4])+(youso[3]*youso[6]); kake[3] = (youso[2])*(youso[5])+(youso[3]*youso[7]); printf("%d %d\n",kake[0],kake[1]); printf("%d %d\n",kake[2],kake[3]); return 0; } 上のコンパイラでやると6行目にsyntax error near ")"、あとkakeを変数として認識してくれないとか色々エラーが出て話にならないんですが…
>>604 古いCの規格(といっても今は主流)では、変数宣言は関数の先頭にまとめなければならない。
>>604 int kake[4];の行をint youso[] = {2,-1,3,2,4,5,-2,0}; の上か下へ移す。
(C99より古い規格のCで変数宣言ができるのはブロックの始めだけ)
"行列を指定\n"と"行列を掛け算\n"の後ろについているコンマが余計なので外す。
>>605-607 丁寧なレスありがとうございます。
うまく訂正できました。
拡張機能使ってるのなら他のCコンパイラでエラーが出ても仕方ないですね。
もう一度よく勉強します。
>>607 見方によってはC99の部分サポートとも言えるな。
610 :
デフォルトの名無しさん :04/08/26 17:20
#include <iostream> #include <string> using namespace std; int i,k; int main() { string str[4][2]= {{"就職","活動"}, {"会社","訪問"}, {"集団","面接"}, {"学校","推薦"} }; for(i=0;i<4;i++){ for(k=0;k<2;k++){ cout << str[i][k] << endl; } cout << "\n"; } } これってどうよ?
>>615 あなたのような暇人を見つけるためでしょうね
>>610 2バイト文字をコードに埋め込むなよ・・・。
↓ここでツッコミ
文字化けしてます?
質問です。 主に,行列計算を行う複雑なプログラムを作ろうと思っています。 基本的にc++でコーディングした方が,javaよりもcよりもメモリ消費が 少なくてすむし,スピードも両者より2倍近く早いというのは正しいでしょうか?
行列計算用のライブラリを使うのが一番早い
好きなの選べ
625 :
デフォルトの名無しさん :04/08/27 00:07
コンストラクタで自分自身へのthisポインタは有効なのでしょうか? class AA { public: BB b; }; class BB { public: AA a; BB(){ a->b=this; } };
>>625 初期化が完了していないことに注意が必要。
public: double GetCircle()const{return circle;} のように最後にconstがくるとその関数では数値の変更ができなくなるという意味があると思うのですが const int showdata(){return a;}のように最初にconstがくる場合はどういう意味があるのでしょうか。 そして最後につけているものとドウ違うのでしょうか、よろしければご指導お願いします。
const int型を返すからshowdata()=1;とかできない。 あんまり意味はないわな。
>>628 最後につくのはメンバ関数のconst。
最初につくのは戻り値のconst。
今日初めて本を見ながらvisual c++をはじめてるのですが、 いきなり5ページ目でつまづきました。 SDIアプリケーションから初めてすぐにビルドしたら C:\Program Files\Microsoft Visual Studio\MyProjects\test2\test2.rc(360) : fatal error RC1015: cannot open include file 'l.jpn\\afxres.rc'. というエラーがでてビルドできません。(test2というのはワークスペースの名前です。) どこをどうすれば解決するのか教えていただけないでしょうか?
const char * を返したり const int& を返したりするのは全然別の話で ちゃんと意味があるから 勘違いしないようにね。
const int&を返すと言うか! 関数内部のstatic変数以外返してはならんぞ!
intじゃなくてクラスなら*thisも問題ないけどな。
static変数返すより、メンバ変数の参照返すのが多くないか。
const char *は さしているアドレスは変えられるけど指している文字列の変更ができないポインタでしたっけ、、? const int&は 指しているint変数は変えられてもその内容は変えられないのかな。。? 最近そこのあたりをやったばかりでなかなかむずかし・・ >>関数内部のstatic変数以外返してはならんぞ! staticでないと関数の処理が終了したときにその関数内部のローカル変数は消えるから実態のない参照なりポインタなりがかえるとまずいからですよね。。? なんだかまた質問になってスイマセン・・・
char* const char* char* const const char* const
>>637 >const char *は さしているアドレスは変えられるけど指している文字列の変更ができないポインタでしたっけ、、?
yes.
>const int&は 指しているint変数は変えられてもその内容は変えられないのかな。。?
違う。参照はポインタと違って指す対象を変えられない。
const int *constに対応すると言ってもいい。
悪い、俺が混乱させたかな。 const char * や、 const std::string& を返す とでも考えてくれ。
>>639-640 そういえば参照は初期化のみ可能で後から代入ができませんでしたね。。基礎的なことを忘れておりました。
丁寧な解説ありがとうございました。
642 :
デフォルトの名無しさん :04/08/27 20:37
char buf[256]; strcpy( buf, "初心者歓迎" ); //こういう入力と出力が同じような使い方はありなんでしょうか? sprintf( buf, "%s C/C++室", buf );
>>642 その場合ならとりあえずstrcatが使える。
strcat(buf, "C/C++室");
>>643-644 動くのでつい使ってしまってました。
strcatか、無理なら別バッファ用意します。レスサンクスです。
環境依存OKって考えであれば、>642は事実上問題がないような。
知ってる方教えてほしいことがあります。 win32のコンソールアプリでCtrl+Sを無効化をしたいのですが、 どのような方法がありますか? Ctrl+Cはsignal関数でなんとか無効化は出来るのですが・・・。 よろしくお願いします。
#include <iostream> #include <string> using namespace std; class Myclass{ private: static string class_string; public: static string show(){return class_string;} }; string Myclass::class_string = "mystring"; int main() { cout << Myclass::show() << endl; return 0; } このコードが実行できることはいいのですが、static string show()const{return class_string;}とすると、 静的メンバ関数が、メモリ モデル修飾子をともなって宣言されました。となりエラーなのですが、特に処理の中でメンバやオブジェクトに変更を加えているわけではないのでなぜエラーなのかわからないです。。 よろしければご指導お願いします。
また、元のコードのstring Myclass::class_string = "mystring";をmainのなかに移すとエラーとなってしまうのですがこれについてもよろしければお願いします。 何度もすみません。
>>648 staticメンバ関数からは非staticメンバにはアクセスできないから、
メンバ関数のconstしていによる「非staticメンバを変更しない」という指定は意味が無い。
そして「staticメンバを変更しない」というconst指定はできない。
>>649 staticデータメンバの定義はnamespaceスコープに現れなければならない。
元のコードはグローバルnamespaceでの定義。
mainに移すと関数スコープなのでダメ。
Win環境に依存した質問です。 他人の作ったアプリ用のDLLを作成しています。 マルチスレッド対応が必要なので、DLL_THREAD_ATTACHで スレッドローカル記憶域を確保しているのですが上手く動きま せん。 どうやらアプリが複数のスレッドを作成後にこのDLLをロード して、ロードしたスレッド以外からもコールしているようです。 このような場合は自分でスレッドIDを元に記憶域確保したり しなければならないのでしょうか? (元のアプリに手を加える事は出来ないのです_| ̄|○)
>>654 動きました!
しかもPROCESS_DETACHは呼ばれるようで
メモリーリークも発生しません。
これで徹夜しないで済みます。
MY神様と呼ばせて下さい。
ありがとうございました。
>>655 誤 PROCESS_DETACH
正 THREAD_DETACH
です。
657 :
デフォルトの名無しさん :04/08/29 03:21
幾つものオーバーロードされたコンストラクタがあり、それも ある処理をしたい場合、 privateなinitメソッドをつくり、全てのコンストラクタないで init()するしかありませんか?
>>657 いいえ、たぶん他に方法があります。
ですが、もう少し具体的に伝わるように状況を説明したほうがいいでしょう。
たとえば class CHoge { int hoge; public: CHoge():hoge(0){} CHoge(char* p):hoge(atoi(p)){} CHoge(std::string):hoge(1){} }; なるクラスだと hoge(atoi(p))とhoge(0)とhoge(1) を3つのコンストラクタに書くのが面倒なんですが・・・
>>659 初期化している値がコンストラクタの引数によってそれぞれ違うなら、
その例に書いてあることはすべて必要な記述です。
3つのコンストラクタに init(0) init(atoi(p)) init(1) と書いてもただの無駄でしょう。
661 :
デフォルトの名無しさん :04/08/30 01:05
std::multimapに含まれているキーのリストを得るスマートな方法ないですか? key : value = A : 1 key : value = A : 12 key : value = A : 123 key : value = B : 1 key : value = C : 12 key : value = C : 123 といったpairがstd::multimapに格納されてるとして A,B,Cといったリストが欲しいのですが、begin()からend()まで地道に調べていけば いいのですが、coolな方法があるなら教えてください
662 :
デフォルトの名無しさん :04/08/30 01:36
math.hをインクルードしたにも関わらず、 sinやcos、tan関数で返って来る値がおかしいんですけど、 原因はなんなんでしょうか?
>>662 まさか角度を度で入力してるとかじゃあるまいな?
>>661 std::multimap::equal_range, std::copy, std::back_insert_iteratorでどうにかできない?
>>664 調べてみたら引数にラジアン値を指定するようでした……。
ありがとうございました。
668 :
デフォルトの名無しさん :04/08/30 15:49
クラススコープの定数を使いたいんだけども 例えばクラス名がAだとして A::LENGTH なり、A::B::LENGTH なり。 class A { public: static const int LENGTH; char c[LENGTH]; }; とやると、char c[LENGTH] で定数式が必要といわれる どうすればスマートですか? enumだと値の重複があってイヤです
>>669 その場で初期化ってどうやればいいの?
static const int LENGTH=100;
とかやると純仮想関数とみなされたりでコンパイル通らない
>>670 VC6とかの古いコンパイラ使ってながら何いってるんだ?
enumにするかあきらめろ
>>668 enumでいいじゃん。classん中で定義すりゃ
>>671-672 VC6じゃ出来ないんですね。ありがとう
NAMESPACEにでもします
674 :
デフォルトの名無しさん :04/08/30 18:06
gettimeofday()関数を使って時間の測定を行いたいのですが、 sys/time.hがないようでうまくいきません。 何か他の手段でマイクロ秒単位で測定が行えないでしょうか? 言語はCで、使用しているコンパイラはボーランドです。
675 :
デフォルトの名無しさん :04/08/30 18:14
あれはUNIXのシステムコールだ。
お邪魔します。spy++のようなイメージのものを作りたく思っています。 マウスドラッグが終わったところから、そのウィンドウのハンドルを取得するつもりで、 サイトを見ながら以下のようなプログラムを書きましたが、うまくいきません。。 理由とできれば解決策をお願いします・・・m(_ _)m //キャプチャ中のとき pts = MAKEPOINTS(LParam); pt.x = pts.x; pt.y = pts.y; hWndTo = WindowFromPoint(pt);
677 :
デフォルトの名無しさん :04/08/30 18:23
>>675 げげ、そうなのですか。ありがとうございます。
>>674 timeGetTime
GetTickCount
ms単位まで。前者奨める。
ちなみに、あまり高精度で測定しても意味はありません。
なぜなら、時間の取得にかかる時間が誤差になるからです。
>>674 窓なら
QueryPerformanceCounter()
を使えばμ秒の精度(予定)
CPUがINTEL系なら インラインアセンブラでRDTSC
でも良いかと
#include<iostream.h> double* keisan(double c); main(){ double *B; B=keisan(2.0); cout << "B[0] = "<< B[0] << endl; cout << "B[1] = "<< B[1] << endl; cout << "B[2] = "<< B[2] << endl; cout << "B[3] = "<< B[3] << endl; cout << "B[4] = "<< B[4] << endl; } double* keisan(double a){ double *A=new double[5] ; A[0]=0.0; A[1]=1.0; A[2]=4.0; A[3]=3.0; A[4]=2.0; cout << "A[0] = "<< A[0] << endl; cout << "A[1] = "<< A[1] << endl; cout << "A[2] = "<< A[2] << endl; cout << "A[3] = "<< A[3] << endl; cout << "A[4] = "<< A[4] << endl; return A; すみません。上のプログラムでAはまともに出力されるのですが、BはB[1]から 変な数値になってしまいます。この理由がわかりません。 B[0]=0;B[1]=1;B[2]=4;B[3]=3;B[4]=2;と出力するにはどうプログラムを 書き換えればよいのでしょうか?
>>678 時間取得にmsオーダーものオーバーヘッドは発生しないって
>>679 ノートのような動的にクロックが変わるものだと…?
683 :
デフォルトの名無しさん :04/08/30 19:09
>>678 ,679
ありがとうございます。
QueryPerformanceCounter()を使って、測定する事が出来ました。
>>676 確認してないけど座標系が違うんじゃないかな。
lParamのほうがクライアント座標で、
WindowFromPointはスクリーン座標だったかと。
MapWindowPointsを使って座標を変換できる。
すいません質問なんですが 他人が作ったライブラリファイルで、そのソースがないんですけど ライブラリファイルだけでその内容を見ることは出来るのでしょうか?
>>686 申し訳ないです。ライブラリについてはよく分かってないものですから・・・
Cで書かれたライブラリってのは、Cのプログラムから作ってるんですよね
逆に、ライブラリファイルからソースを抽出できるのかな?ということなんです
>>688 卵焼きってのは生卵から作ってるんですよね
逆に、卵焼きから生卵を抽出できるのかな?ということなんです
>>689 回答ありがとうございます
勉強しなおしてきます
微妙に変な比喩だけどな。
>>690 こっちの方が比喩としてはいいのではないだろうか。
英文の和訳ってのは英文から作ってるんですよね?
逆に、英文の和訳から英文を抽出できるのかな?ということなんです
ある意味、できる。逆アセンブルして読んで解釈すれば。
あるいは、ブロックが色分けされていない仕様のテトリスにおいて、 積み重なったブロック群を元のブロックに戻すようなもんか。
I'm a kitchen drink.
2次元配列と引数にとって、2次元配列を返す関数を作りたいのですが、 どうしてもうまくいきません。いろいろ調べても多次元配列を引数にとる 方法は書いていても、多次元配列を返す方法が書いていません。 AとBを受け取ってCを返す関数を作りたいとき double (*C)[2](double (*A)[2],double (*B)[2])という風に宣言したら エラーになってしまいます。 どう宣言すればよいのでしょうか? 誰か教えてください。
>>695 double (*C)(double (*A)[2],double (*B)[2])[2];
>>695 typedef double (*HOGE)[2];
HOGE C(HOGE A, HOGE B)
>>696 以下のコードで関数は配列を返せませんというエラーが出てしまいます。
どこが間違っているのでしょうか?
#include<iostream.h>
double (*tasizan)(double (*A)[2],double (*B)[2])[2];
main(){
double A[2][2];
A[0][0]=1.0; A[0][1]=0.0;A[1][0]=0.0;A[1][1]=1.0;
double B[2][2];
B[0][0]=1.0;B[0][1]=2.0;B[1][0]=1.0;B[1][1]=2.0;
double (*C)[2];
C=tasizan(A,B);
}
double (*tasizan)(double (*A)[2],double (*B)[2])[2]{
double (*C)[2];
C[0][0]=A[0][0]+B[0][0];
C[0][1]=A[0][1]+B[0][1];
C[1][0]=A[1][0]+B[1][0];
C[1][1]=A[1][1]+B[1][1];
return C;
}
>>698 ごめん。正しくは
double (*C(double (*A)[2],double (*B)[2]))[2];
ところで、そのコードは意図したように動かないと思うぞ。
初期化していないポインタを使ってはいけない。
>>684 さん、MapWindowPointsの使い方がわからなかったのですが、
それでくぐってClientToScreenにたどり着きました。どうもありがとうございました
WndClass.lpfnWndProcにC++ class内の関数をどうやれば登録できますか?
間に一個はさむとか
>>704 ありがとうございます
できればstaticにしたときの注意点や、参考になるWeb pageなども教えてください。
残念な質問で恐縮ですが。 構造体などのメンバにアクセスする際(.を打ち)、たま〜にメンバが出てくれないことがあります。 変数名が違う時やその他エラーが存在する時に出ないという事は承知している のですが、なんの問題もなく、ただ唐突にでなくなる症状があります。 こんな症状ありませんか? MicrosoftVisualC++ 6.0
>>705 staticを付けると静的関数になるのでthisポインタはない。
そこで下のようにするとメンバ関数RealWindowProcがthis付きで呼ばれる。
ただしCreateWindow(Ex)の最後のパラメータにHogeへのポインタを渡す必要があるから、
クラスのメンバにCreateWindow(Ex)を行う関数が絶対必要。
class Hoge {
static WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
virtual RealWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
};
LRESULT CALLBACK Hoge::WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
Hoge *pWnd = reinterpret_cast<Hoge *>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
if (uMsg == WM_NCCREATE)
{
pWnd = static_cast<Hoge*>(static_cast<LPCREATESTRUCT>(lParam)->lpCreateParams);
SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pWnd));
}
if (pWnd)
pWnd->RealWindowProc(hwnd, uMsg, wParam, lParam);
}
>>708 なるほど・・・。ありがとうございます。
微妙に解決しませんでしたが、ちょっとここからはDirectXの構造体の話になってしまいスレ違いということで自粛します。
とは言えこれで通常時この問題にぶち当たった時に対処できます。
ありがとうございました。
c++で作ったメソッドをjavaで使おうと思ってるのですが、 その方法を詳しく書いててお薦めのページがあれば教えて頂けないでしょうか?
>>707 ソースを見ながら少しずつやっていきます
ありがとうございました
c++の最適化について書いてる本ないですかね? javaでいうjavaの鉄則みたいなやつ
Efficient C++
>>701 そうだった。
ClientToScreenのほうが引数少なくて楽だね。ごめん。
>>707 USERDATAは誰かが別の目的で使ってたらと思うと
怖くて使えないのは俺だけ?
自分でテーブルつくって管理すればいいんだろうけど
面倒なので、たいていはSetProp/GetPropを使ってる。
もちろん速度的には不利だろうけど。
>>715 サンク使うのがいいかも。
ATLからソースをパクっt(ry
718 :
デフォルトの名無しさん :04/09/01 01:22
VCLは糞以下 なぜ、あんなライブラリを商用として提供できるの? > Borland殿
買うやつがいるからな
720 :
デフォルトの名無しさん :04/09/01 01:34
>>718 禿げあがってしまうほど、同意
ぜってー、VC++の方が使いやすくね?
質問です。 @visual c++.netを使っています。 あるプロジェクトの中にtest1.cppとtest2.sppというものがあり、 test1の中で #include <iostream> main(){} class test11{ public: static void A1(){} }; という形で書かれているとします。main関数とclass test11の順番を逆にしたら コンパイルできるのですが、上の時にmainの前にstatic void test11::A1(); と宣言しても「test11の識別子がクラス名でも名前空間名でもありません」 というエラーが出てしまいます。正しい書き方があれば教えていただけないでしょうか? Aあと、上の例でコンパイルの順番がtest1.cpp→test2.cppでtest1の一番最初にmain関数が 来ている場合、test2の中の関数を使うことは可能でしょうか? test2.cppのなかのclass test22の中のメソッドB()を使いたい場合はどういうコードを書けばよいので しょうか? よろしくお願いします。
>>721 (1)
class test11 {
public:
static void A1();
};
main() { ... }
void test11::A1() { ... }
ただし、普通はヘッダファイルを使う。
(2)の質問の答えも同様。
別スレで質問したら、相手にされなかったのでここで質問させて頂きます。 行列計算用のライブラリで計算速度が速く使いやすいおすすめのものがあれば 紹介していただけないでしょうか?
#include<stdio.h> #include<stdlib.h> int main(void){ FILE *fp; if((fp=fopen("sintai.dat","w"))==NULL){ printf("File not open\n"); exit(1); } int i; struct sintai { char *name; int height,weight; }; static struct sintai a[]={ {"nagata" ,180, 85}, {"nisimura" ,185, 95}, {"nakanisi" ,175, 80}, {NULL,0,0} }; for (i=0 ; a[i].name != NULL; i++){ printf("%s\t%d\t%d\n",a[i].name,a[i].height,a[i].weight); fprintf(fp,"%s\t%d\t%d\n",a[i].name,a[i].height,a[i].weight); } return 0 ; } これはstruct sintai a[]を初期化してsintai.datへ書き出すプログラムですが これの逆をする場合、つまりsintai.datが 先に与えられている条件でsintai.datを読み込んで struct sintai a[]へ代入する場合はどうすればいいでしょうか
>>723 C++相談室で上がってるもの以外だとoctaveのライブラリなんかどうでしょう?
727 :
デフォルトの名無しさん :04/09/01 14:49
文字列の先頭に文字を挿入するにはどうすればいいですか?
728 :
デフォルトの名無しさん :04/09/01 14:55
>>727 std::stringならinsert()
729 :
デフォルトの名無しさん :04/09/01 14:59
すいません、stringはつかわないで、普通にCharで文字列操作をする場合に どうやったら簡単にできるでしょうか。
sprintf
731 :
デフォルトの名無しさん :04/09/01 15:15
LinuxでCをやっているのですが、16進数を文字に変換することはできるのでしょうか?
733 :
727、729 :04/09/01 15:30
>>728 >>730 どうもです。
sprintf(str,"a%s",str)
みたいに、自分の先頭に足して自分に代入するのはできないですよね。
どうにか新しく余計な文字列を作らないで完結できないものでしょうか。。。
void test( void ) { int num = 0xFFFF; char str[5]; sprintf( str, "%x", num); printf( "%s\n", str ); }
>>733 (1)
char str[6] = "1234";
char tmp[6];
strcpy(tmp, str);
strcpy(str, "0");
strcat(str, tmp);
(2)
char str[6] = "1234";
for(int i = 5; i > 0; i--){ str[i] = str[i - 1]; }
str[0] = '0';
736 :
デフォルトの名無しさん :04/09/01 15:57
731です。 「cgi」で日本語入力ホームを作って入力すると%23%4d%43・・・のように出ます。 %以降のは16進数らしいんです。これを日本語にするにはどうしたらいいのでしょうか?
738 :
デフォルトの名無しさん :04/09/01 16:08
vector<int> v = { 0, 2, 4, 8, 16, 32 }; こんな感じで初期化出来ませんか?
>>738 そのままでは無理。
const int init[] = { 0, 2, 4, 8, 16, 32 };
vector<int> v(init, init + sizeof init / sizeof *init);
operator,の定義でごまかす方法もある。
>>739 なるほど。どうもありがとうございました。
741 :
デフォルトの名無しさん :04/09/01 16:24
737さん どうもありがとうございます。さっそく試してみたいと思います。
#include<stdio.h> #include<iostream.h> #include<stdlib.h> double** AA(int n) { double** A; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { A[i][j]=1; } } return A; } main(){ double** B= AA(3); cout << B[0][0] << endl; } 引数nをとって,n×nの2次元配列を返すメソッドを作りたいのですが、 上のプログラムだとコンパイルは出来ますが、実行するとフリーズしてしまいます。 おそらく、ポインタの初期化が出来ていないからだと思うのですが なかなかコードが書けません。 誰か教えてくれないでしょうか?
#include<stdio.h> #include<iostream>/* iostream.hは時代遅れ */ #include<stdlib.h> double *AA(int n) { double *A = new int[n*n]; /* C++では要素数が不明の配列の配列を作れない。*/ for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) A[i * n + j] = 1; /* 添え字を工夫 */ return A; } int main() { /* intは必須 */ double *B = AA(3); std::cout << B[0 * 3 + 0] << std::endl; delete B; /* newの後始末 */ }
#include<iostream> using namespace std; double** AA( int n ) { double** A = new double*[n]; for (int i = 0; i < n; i++) A[i] = new double[n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { A[i][j]=1; } } return A; } int main(){ double** B = AA(3); cout << B[0][0] << endl; for (int i = 0; i < 3; i++) delete [] B[i]; delete [] B; return 0; }
>>743 >引数nをとって,n×nの2次元配列を返すメソッド
>>742 皆さん,おあつい議論のところ横から申し訳ないですけど,
742さんは(もし意図的に避けてるのでなければ)STLを使った方がいいですよ.たぶん....
#include <iostream>
#include <vector>
using namespace std;
typedef vector <double> Row;
typedef vector <Row> Matrix;
Matrix AA(int n) {
return Matrix (n, Row (n, 1));
}
int main()
{
Matrix B = AA (3);
cout << B[0][0] << endl;
}
>>750 ちょっと訂正.
-Matrix AA(int n) {
+Matrix AA(size_t n) {
vector<vector<int>> v; 多次元配列は↑みたいにSTLのvectorを入れ子にして使った方が楽だよ。 同様に入れ子して行けば何次元でもいける。
vector< vector<int> > v; 逝ってくる…
みなさんどうもありがとうございます。 ところでSTLを使うことのデメリットはありますでしょうか? 使わないより計算速度がやや遅くなるとか‥‥?
>>757 「計算速度が遅くなるのに気づきにくい」が正確かな。
たとえば
>>750 はvectorを値で返しているのでコピーが発生する。
>>750 なら4要素だから大したことはないが、巨大なvectorをコピーすると、
コードは単なるreturn分なのにも関わらず実行時コストが大きくなる。
速度が本当に気になる場合は実測した方がいいです. うちでは圧倒的に750が速いです. 758さんの指摘はもっともなんですが,コピーは戻り値最適化で消えることがありますし, それ以外のファクタが律速段階になっている可能性が多いにありえます. 以下測定コード.(見にくくて申し訳ありません.) BUNDLE_SIZE10000に注意して見て下さい.
#include<iostream> #include <vector> #include <boost/timer.hpp> using namespace std; double *AA743(int n) { double *A = new double[n*n]; for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) A[i * n + j] = 1; return A;} double** AA744( int n ) { double** A = new double*[n]; for (int i = 0; i < n; i++) A[i] = new double[n]; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) A[i][j]=1; return A;} typedef vector <double> Row; typedef vector <Row> Matrix; Matrix AA750(size_t n) {return Matrix (n, Row (n, 1));} const size_t MATRIX_SIZE (1000); const size_t BUNDLE_SIZE (100); const size_t BUNDLE_SIZE10000 (BUNDLE_SIZE * 10000);
int main(){ cout << flush; sleep (1); boost::timer t743; for (size_t k (0); k < BUNDLE_SIZE; ++ k) { double *B = AA743(MATRIX_SIZE); delete B;} cout << t743.elapsed () << endl; cout << flush; sleep (1); boost::timer t744; for (size_t k (0); k < BUNDLE_SIZE; ++ k) { double** B = AA744(MATRIX_SIZE); for (size_t i = 0; i < MATRIX_SIZE; i++) delete [] B[i]; delete [] B;} cout << t744.elapsed () << endl; cout << flush; sleep (1); boost::timer t750; for (size_t k (0); k < BUNDLE_SIZE10000; ++ k) Matrix B = AA750 (3); cout << t750.elapsed () << endl; return 0;}
割り込みの術
>>762 なんぬぅ!
環境
model name: Pentium III (Coppermine)
cpu MHz: 853.221
cache size: 256 KB
MemTotal: 515256 kB
g++ 3.3.4 on Linux 2.4.26
コンパイルフラグ -O3 -march=pentium3 -msse -mfpmath=sse -fforce-addr -fomit-frame-pointer
結果
5.71
7.5
3.47 <-10000倍回してるのに
それでは
>>742 はクラス内部での処理を3番目の方法で実装して、
getメソッドをポインタのポインタで返せばいいんだね
ヤバい!!!! Matrix B = AA750 (3); 逝って来ます
>>765 750の測定回数を743,744と揃えるために
-for (size_t k (0); k < BUNDLE_SIZE10000; ++ k)
- Matrix B = AA750 (3);
+for (size_t k (0); k < BUNDLE_SIZE; ++ k)
+ Matrix B = AA750 (MATRIX_SIZE);
のように修正し測定し直しました.
結果
5.67
7.4
5.23
>>767 766の結果は
1000x1000の行列を100回生成したときの実行に要した時間(秒)で,
上から743,744,750の場合なのですが,
うちの環境だと御覧の通り744は他の2つに比べ若干遅いみたいです.
(他の環境だとどんな感じなんでしょ? >>all)
ただ,システムをトータルで見たときに律速段階になってないようであれば,
気にするのはあんまり意味のないことだと思いますよ.
そりゃ当然かもね だってnewの回数もdeleteの回数も一番多いんだから。 そうしないとdouble**が作れないわけでもあるが…
771 :
デフォルトの名無しさん :04/09/02 19:52
map<string, int> m; mに("0",100)から("9",100)までのペアを挿入したいんですが、 for分でまわして、'0'+i とかを使おうとしても、stringにキャストできないから困っています。 どうしたら良いですか?
char buff[]="0"; buff[0]+i; とか
773 :
デフォルトの名無しさん :04/09/02 20:04
0から9の10個くらいコピペでいいと思うんだけど
>>773 実際に使うときには動的だったり、1-99コくらい会ったりするので・・・
123.ToString()みたいな関数は用意されていないんですか?
775 :
デフォルトの名無しさん :04/09/02 20:14
>>774 boost::lexical_cast
重い処理(forループをぶん回す)を行う関数を実行中に、進捗状況を表示したり、 ユーザーからの要求で処理を中断したりしたいのですがどうしたらいいでしょうか? windowsのコールバック関数とかが検索で引っかかるのですが、環境非依存にしたいのです。
>環境非依存 無理
無理ですか。この場合、処理を行う関数だけ書き換えなくて済めばそれでいいんですが。
書き換えろよ
>777 独自のコールバック関数を定義して、 その関数ポインタを受け取るようにすれ。 コールバッククラスでもいいけど。
たとえば、途中で中断したい関数hogeの引数に関数ポインタを追加して、 中断チェックをする関数を渡してあげればよいちうことでしょうか int hoge( int (*mycallback)() ) { int id; for (){ //処理 …… id = (*mycallback)(); if (id==1) return 1; //ループを途中で抜ける } return 0; //正常終了 } int chk_abort() { if(abortボタンが押されたら) return 1; else return 0; } で、呼び出すときは //処理 hoge(chk_abort); //処理 みたいな?
あ、777=779=782です
>782 ものすごくてきとーな説明だったのによく解ったな。そんな感じ。
781でキーワード追加できたので、検索結果を絞り込めたので。 これでint chk_abort();を処理系ごとに用意すれば、int hoge( int (*mycallback)() ); に関しては手をつける必要がなくせますね。早速試してみます。ありがとうございました。
#include<stdio.h> int main(){ double pi=0; int l,h; char tmp[10]; printf("第何項まで? \n"); fgets(tmp,sizeof(tmp),stdin); sscanf(tmp,"%d",&l); for(h=1; h <= l ; h += 2){ if( h % 4 == 1){ pi=1.0/h + pi; } if( h % 4 == 3){ pi= - 1.0/h + pi; } printf("%d乗の項まで pi = %1.80lf\n",h,4*pi); } } 興味本意でこのようなプログラムを作ってみました。 piを求めると言うより,arctan1のテイラーの収束の遅さを知るためのものです。 これをコンパイルして実行すると,48桁までしか正しい数字が出て来なく, 以下は0が並んでしまいます。 手元の資料にdoubleの上限値が1.7E+308,精度が15桁とあるのですが, なぜ,48桁程度までしか正しく計算できないのでしょうか?
書き忘れました。FreeBSD4.8Rでcc 2.95.4を使ってコンパイルしました。
クラスの勉強をしていて代入演算子の定義というものをやったのですが、 Myclass &Myclass::operator=(Myclass& original) { cout << "My operator" << endl; if(this==&original) { return *this; } name = original.name; return *this; } という感じで、if文で自分自身にオブジェクトの代入を行わないようにするとあるのですが if文でtrueでもfalseでも*thisを返しているのだからobj1 = obj1 や obj1 = obj2というようなコードを書いても どちらも呼び出したオブジェクトobj1が返ってくることにならないですか?
書き忘れました。 呼び出したオブジェクト自身が返ってくるということは自分自身にオブジェクトの代入を行わないようにする意味がないのではと思ったのです。 if文のところを消してobj1 = obj1としてもとくにエラーが出たりするわけでもなかったのでなぜこのようにするかがわかりません。 どうかご指導お願いいたします。
>786 よく判らんけど、1.0/hがpiに比べて小さすぎる値になってしまい、 (1.0/h + pi) == pi になってしまってるんじゃないの? >788 obj1 = obj2 は obj1.operator=(obj2) という関数に置き換わり、 その関数の返値がobj1(の参照)になるということ。って違うのか。 メンバにポインタを持っていて、newとdeleteが絡んだときに問題が発生する。
>>786 いやだから、精度が15桁しかないんだからそれ以上の桁に意味なんてないんだってば。
>>790 その場合の返り値はどこへいくのでしょうか。。
上のobj1.operator=(obj2)という文に置き換わることはわかるのですが、これはobj1.関数名(引数)という感じの関数ですよね。
と、するとその戻り値を格納する場所がないのでいったいどこへ行ってしまうんだろうと。。。
返り値を入れる変数など = 関数名(引数)という形のように 返り値を入れる変数など = obj1.operator=(obj2)という感じでないといけない気がして。。
>>788 自分自身への代入のときに、nameメンバをコピーしないことに意味があるんだろ。
nameメンバがポインタで、コンストラクタでnewしていれば当然の要請だね。
で、代入結果は obj1 = obj2では単純に捨てられる。
戻り値に*thisが必要な理由は、obj3 = obj1 = obj2のような場合に備えて。
>>786 >790、>791の指摘している通り、実際100000000までと1000000000までとでは値が変わらなくなってくる。
試してみたが、この時点で、累積誤差の所為で12桁程度の精度しかなくなってしまっている。
#真面目に誤差を計算しなくてもこんなもの。昔はこんな計算一々試せなかったなぁ。
>>793 ということはこのようなポインタを使用しない場合は特にif文を使用する必要はなく、
仮にobj3 = obj1 = obj2というようなイコールを続けて使うことをしない場合は*thisを返す必要はないのでしょうか?
>>790-792 御解答ありがとうございます。
doubleの精度が15桁とはいえ、48桁程度までは数字が出てきているため、
意味があるのだろうかと思っていたのですが、信用できない数字なのですね。
797 :
デフォルトの名無しさん :04/09/03 07:18
>>793 もひとつ質問で、obj1 = obj1のような同じオブジェクトを代入した場合はどのようなことが起こるのでしょうか?
予想ではif(this==&original){return *this;}でreturn *thisをするが同じように格納する場所がないから捨てられる・・・と思うのですが。。
>>797 マンドクセからEffectiveC++でも買ってこい。
799 :
デフォルトの名無しさん :04/09/03 08:28
結構高いのにたいした事ない 絶対熊田曜子の写真集のほうがヌケルぞ
801 :
デフォルトの名無しさん :04/09/03 09:27
たいしたことないのはMoreがつく奴
802 :
デフォルトの名無しさん :04/09/03 09:39
boostのuBLASで行列の乗算A*Bを行うプログラムを VC++でコンパイル実行すると、結果はちゃんとでるんですが、 エディタ画面に戻って「prod」と入力するとエディタが ハングアップ状態になってしまいます。 こんな現象にであった人いませんか? 環境 Windows XP Home Edition, VC++ NET 2003 Standard, boost_1_31_0
intが32bitの環境で int*int=int64で結果を受け取りたいのですが、 何か良い方法無いでしょうか?
804 :
デフォルトの名無しさん :04/09/03 09:42
>>803 intじゃ無理
キャストするなどしてint64にしないと無理。
.netのVCでダイアログを作成するとなぜかCDHtmlDialogの派生で勝手に作られてしまいます。 以前はCDialogの派生だったと思いますが、これからはこっちの方が正しいのでしょうか? あと、作るたびにCDialogの派生に変更するのが面倒なのですが、デフォルトで CDialogの派生で作るようにすることはできないでしょうか? .netが以前のVisualStudioに比べてあまりに変わりすぎてるのでどうもわかりません。 教えてください。
>>806 自己解決です。作るときにたまたまリストのトップであるCDHtmlDialogが選ばれてただけでした。
>>795 > ということはこのようなポインタを使用しない場合は特にif文を使用する必要はなく、
メンバにポインタが無くても,他にユーザ定義のクラス(Aとしましょう.)がメンバにあって,
Aが同じ問題を抱えていた場合に問題になります.
Aを変更できるならAを修正するだけですが,
Aが変更できない場合はAを保持してるクラスで対処する必要があります.
> 仮にobj3 = obj1 = obj2というようなイコールを続けて使うことをしない場合は*thisを返す必要はないのでしょうか?
OKです.その場合宣言では返値の型にvoidを指定しましょう.
ただ組み込み型と互換がなくなるのでお薦めしません.
それと,代入演算子の引数(コピーコンストラクタもですが)はconstを付けましょう.788の例だと
Myclass &Myclass::operator=(const Myclass& original) {...}
こんな感じ.
質問があります。 class Vector { double* data; int n; public: Vector(int n0) { data = new double[n0]; for (int i=0;i<n0;i++){ data[i]=0; } n = n0; } void put(int i, double d) { data[i] = d; } }; class anime{ public: static Vector tt(3); //static double m; }; main(){ anime::tt.put(0,4); //m=10; } 上記のように、class animeの中でVector classのインスタンスttを、staticにして、それを 別のところで操作しようとしたら、「構文エラー:定数」というエラーがでてしまいます。 double だとエラーがでないのに、上記Vectorでエラーがでる理由とエラーの意味がわかりません。 javaではこういうことはできてて良くやっていたのですが、c++だとできないのでしょうか?
>>809 class anime {
public:
static Vector tt;
anime() : tt(3) {}
};
それよりVectorはoperatorを使えよ。
>>810 それだとC2438
「静的なクラスデータを初期化するのに、コンストラクタが使われています。」
になったぞ。
class anime{
public:
static Vector *tt;
};
Vector *anime:ptt = new Vector(3);
int main()
{
anime::tt->put(0,4);
return 0;
}
俺にはこれしか思いつかない…
誤記訂正 Vector *anime:tt = new Vector(3);
>>809 -class anime{
-public:
-static Vector tt(3); //static double m;
-};
+class anime{
+public:
+ static Vector tt;
+};
+Vector anime::tt(3); //static double m;
それで良かったのか…。 ありがとう、勉強になりました。
815 :
デフォルトの名無しさん :04/09/03 23:26
816 :
デフォルトの名無しさん :04/09/04 10:08
Exeファイルを作成できる、コンパイラってありますか?
デフォルトでLinux用のExeファイルを作成するコンパイラってありますか?
819 :
デフォルトの名無しさん :04/09/04 10:44
vctkで do { int a = ...; } while(a); が通るんだけど、これっておかしくない?
べつに。 おかしくない書き方をこちらがやればいいだけだ。
そりゃーおかしいなw
int a = 0; do { int a = 1; } while (a);
824 :
デフォルトの名無しさん :04/09/04 17:36
テキストデータをリソースに追加してそこから文字を読み込みたいのですがやりかたがわからないです
825 :
デフォルトの名無しさん :04/09/04 17:38
C/C++にはリソースなんて概念はありません
>>824 おとなしく.txtよみこんでろlwkじぇっあwks
LoadString
>>825 FILE*とかメモリとか、リソースじゃないんですか?
FILE*とかメモリにテキストデータを追加するのか?
ぬるぽの出番ですか?
831 :
デフォルトの名無しさん :04/09/04 18:34
いえ
___ ガッ
/___|ミ ガッ
.|| ヾ ミ 、 ガッ
∩_∧/ヾヽ
| ,| ゚∀゚). .| |;, ガッ
/ ⌒二⊃=| |∵.
.O ノ %`ー‐'⊂⌒ヽ ガッ
) ) ) )~ ̄ ̄()__ ) ←
>>830 ヽ,lヽ) (;;;;;;;;;;;;;;;;;)(_(
class A{ :public static double* a; }; double* A::a=new double[3]; a[0]=1; 上のコードのように、静的なメンバ定数であるaという配列を初期化する際に そのaの成分a[0]をある値に初期化したいのですが、a[0]=1の部分でエラーになります どうしても上のクラスの中でa[0]の成分を設定したいのですが、無理でしょうか?
>>833 class A{
public:
static double* a;
};
double* a_init (){
double* result=new double[3];
result[0]=1;
return result;
}
double* A::a=a_init ();
835 :
デフォルトの名無しさん :04/09/04 23:59
腐れ先輩のコードを保守しなければならないのが会社だが、 class SputterProcess { ... public: virtual SputterProcess operator=(const SputterProcess&); }; ってのがある。 virtualなoperator=()ってなに?
836 :
デフォルトの名無しさん :04/09/05 00:00
まちがえた × virtual SputterProcess operator=(const SputterProcess&); ○ virtual SputterProcess& operator=(const SputterProcess&);
>>836 そういう方には
「この腐ったイカめ。私の床に落ちた精液でも舐めてなさいよ」
と、いってやればいい。
838 :
デフォルトの名無しさん :04/09/05 00:40
ヤラナイカって言ってやれば??
>>835 ひょっとして派生側で挙動を変えてるとか
840 :
デフォルトの名無しさん :04/09/05 00:48
The AMANOJA9さんサイコーです。
843 :
デフォルトの名無しさん :04/09/05 01:49
virtuaなメンバ関数はポインタを通して呼び出されて はじめて意味があるんだよ
>>843 >virtuaなメンバ関数はポインタを通して呼び出されて
>はじめて意味があるんだよ
?????????