【初心者歓迎】C/C++室 Ver.42【環境依存OK】
1 :
デフォルトの名無しさん :
2007/09/03(月) 01:00:06
みんなのCの勉強法は?っていうFAQの続きで新スレスタート
はじめは、書きたいように書けばいいんだよ
それより、まず1行、書き始めようや
昨年書いた自分のコードを、今の自分ならイチから書き直したくなる
そんな気持ちにすらなる アマチュアなら、それでいいのではないかと
処理系を聞いてるくらいだから、まずコンパイラセットアップからはじめようや
VCExpressでもいいよ 他言語経験者なら、まずhello world 通すことからはじめようや
プロ(ルーキー)なら、先輩に聞け 聞ける先輩がいないなら、そんな先輩を探せ
>>1 乙です
1年前のコードを見て自分が確実に劣化しているのを感じたんだが、 同じように感じる人って少ないのかな?
sfのコードは美しいばかりではない
玉石混交なのはもちろん、動くことを優先に、意図的にやっつけコード書いてることもある
コメントも読んで、書いた人の心理まで読んで欲しい
>>3 あるある、今の自分の鈍り具合を見て萎える
昨年のほうがましだったってね 正直なにくそだ
void*型にメンバポインタはやっぱりどうしても入らないの? 代わりにどんなメンバポインタでも入る型は存在しないの?
7 :
デフォルトの名無しさん :2007/09/03(月) 20:26:12
前スレの965です 971さんの言う通りqのシグナルを送ってみたいと考えていました いろいろありがとうございます system使わないで実装がんばります(´・ω・`)ゞ
>>6 そもそも変数のサイズが違うことがあるからねえ。
メンバポインタへのポインタなら入るyp
BCB6のメンバ関数ポインタは12バイト。参考までに。
ありがとう!
>>9 ポぃンタってアドレスの入る箱でしょ.アドレス格納箱って32bitOSだと4バイトじゃないの?
それが、12バイトなんて信じられないぞなもし....なんで肥ったの????
アドレスとは定義されてない
C++3rd 15.5「メンバポインタ」の項を読むといい。 「メンバポインタは、変数ポインタや関数ポインタとは異なり、メモリの位置を指すポインタではない。 メンバポインタは、ポインタというよりも構造体オフセット、配列の添え字に近い。」
メンバ関数へのポインタは、 非仮想関数の場合アドレスを、 仮想関数の場合vtblのオフセットを保持するようになっている。 もちろんどっちを保持しているかのフラグも要るし、 多重継承などで複数のvtblがある場合も考えなければいけないし、 そうしてぶくぶくふくれていく。
14はもちろん例えばの話ね。
>>13 のは、主にメンバ変数へのポインタの話。
>>9 のは、独自拡張のいわゆる__closureの影響。
WinAPIの話なんですが、C/C++の型についてなので、ここで質問させてもらいます。 LPARAMの値lpを SetWindowLongPtr(wnd, DWLP_USER, lp); として設定すると、「LPARAMからLONGへの変換。データが失われる可能性がある」と出てきます。 LPARAMもLONGも、元をたどれば同じlongなので、データが変わることはないと思ったんですが… また、hoge *h; ていうクラスのポインタがあって、 h = reinterpret_cast<hoge *>(GetWindowLongPtr(wnd, DWLP_USER)); とすると、「LONGからより大きいサイズの hoge * へ変換します」と出てきます。 ↑2つとも、自分の環境だと自分の期待通り動いてるんですが、 64ビット環境とか、他の環境だと動かない可能性があると言うことでしょうか。 # そもそも、SetWindowLongPtrの第3引数や、GetWindowLongPtrの戻り値の型はLONG_PTRだと、 MSDNライブラリに書いてあるんですが、なぜLONGなのだろう…
>>17 >64ビット環境とか、他の環境だと動かない可能性があると言うことでしょうか。
そのとおり。
ただし、32ビットOSでは現在でもSetWindowLongPtrはSetWindowLongの別名として
マクロ定義されているだけなので、MSDNでは第3パラメタがLONG_PTRになっているが、
ヘッダの宣言ではSetWindowLongと同じLONGのままの扱い。
そのために警告として表示されると思われる。
>なぜLONGなのだろう…
WindowsAPIは当初から64ビット対応されてたわけではない。
以前はポインタやハンドルをLONGやDWORDで扱っている箇所があった。
64ビット対応したとき、単純にいままでLONGだった箇所はLONG_PTRに、
DWORDだった箇所はDWORD_PTRに変更したと思われ。
あ、そのとおりってことはないな。 19に書いたとおり、32ビットOSでの警告は現在の実装(ヘッダ)の問題と 思われるので、その警告は無視してよい、かな。
boost::function<bool (int, int)>; このテンプレート部分はどうやって取得すればいいんでしょうか。 ああああああああああああああああああああああああ
テンプレート 引数 ひきすう いんすう hikisuu innsuu hikky
>>21 template<class T>
void func(boost::function<T> &f) { ... }
じゃダメなん?
type1 (type2, type3, type4 .......) からどうやって、 type1 type2 type3 type4 をそれぞれ得るか?
「sizeof演算子は、size_t型の整数値を返す」と習いましたが、size_t型はC/C++の予約語ではなく、 どこかのヘッダファイル(VC2005だとcrtdefs.hにありました)にtypedefされている型だと思うんですが…。 でも「何も」includeしなくてもsizeof演算子は使える…。 というかsize_tも使える…。なんでsize_tが定義されてないのに使えるのでしょうか。コンパイラマジック? こんなこと気にしてたら禿げますかね
コンパイラマジックです。
>>25 sizeofは、コンパイラがsize_tのtypedef元として
使うであろう整数型を結果とするということ。
コンパイラとライブラリは、全くの別物が
無関係に作るということが(おそらく)ないので、
これでうまくいくはず。
定義されていなければ使えない 使える→どこかで定義されている 探せ
29 :
デフォルトの名無しさん :2007/09/05(水) 00:25:42
すみません C言語でSocketを用いて通信する場合は サーバー・クライアント両方とも C言語で設計されていなくとも通信できるのですか?
>>29 まったく問題ない
極端にいえば、アセンブラでソケットライブラリ叩いても結構
一見ばかばかしいとも思えるけど、FAQらしいのでマジレス
33 :
デフォルトの名無しさん :2007/09/05(水) 01:03:39
Cで16進数の FFC8D6 という値があったとして それぞれ FF と C8 と D6 を取り出したいんですが どうすればいいんですか? 何となくシフトすれば良いって気もしないでもないんですが・・・
FFC8D6 & 0xFF FFC8D6 >> 8 & 0xFF FFC8D6 >> 16 かな
>>33 シフトと論理積
union使う手もあるな。
なんとなくだけどRGB値の分割する目的? だったらGetRValue(),GetGValue(),GetBValue()とか
>>33 右シフトするときは、ちゃんと unsigned にしてやらないと、
signed では、MSB が 1 だったときの振る舞いが処理系依存なので
気をつけないとダメよん。
>>35 union を使うってのは、ビットフィールドと、unsigned int あたりを
union にするっつーことかしら。サイズと各ビットの意味が固定な
ハードウェアレジスタの表現なんかだと、各ビットに名前つけられて
良いですな。
エンディアンが確定しているなら unsigned char *p = &val; で、p[0]~p[3]で取り出すとか。怒られるかな。
Cならいけそう C++だと怒られた
unsigned char *p = (unsigned char *)&val;
>>24 多分こう
template<class R. class A1>
void func(boost::function<R (A1)> &f) { ... }
template<class R. class A1, . class A2>
void func(boost::function<R (A1.A2)> &f) { ... }
>>37 union my_long {
unsigned long value;
unsigned char bytes[4];
};
union my_long tmp;
tmp.value = 0xFFC8D6;
printf("%02x %02x %02x %02x\n",
tmp.bytes[0],tmp.bytes[1],tmp.bytes[2],tmp.bytes[3]);
こんな感じか?
まぁビットフィールドは要らんだろ。
unionしばらく使ってないから、なんか間違えとるかも知らん
43 :
35 :2007/09/05(水) 20:57:23
>>37 >>42 みたいなのを考えてた。
ビットフィールドは、存在自体忘れてたよ。
ちなみにC++(覚えたて)なら無名の共用体を使えるから、"tmp."を省けるんだね。
結果がバイト順に依存するのは良いのか?
>>44 C言語でやってる限りはエンディアンと型のバイト数を
意識せにゃならんのはしょうがないんじゃね?
C++はよー分からんが。
まぁ、とりあえずエンディアン気にしないならこうか?
unsigned long val = 0xFFC8D6;
unsigned long a,b,c,d;
a = val / 0x1000000;
val = val % 0x1000000;
b = val / 0x10000;
val = val % 0x10000;
c = val / 0x100;
val = val % 0x100;
d = val;
printf("%02x %02x %02x %02x\n", a, b, c, d);
本質的には、やってることはビット演算と変わらんな。
バイト数は、まぁsizeofか何か使ってループ回すのかね。
>>45 ビット演算もバイト順独立だよ
整数を整数として扱っている限りバイト順は気にしなくて良い
>>46 あれ?そうだっけ?
こりゃ失礼しました。
>>40 の方法ならパッと見スッキリ書ける。
union使うなら場合によっては「うまいこと書けたな」と満足を得ることが出来る。
>>34 >>45 は愚直に見えるが、多くの環境でまず間違いなく動く。
こんな感じか?
人物判断判断 ○FFC8D6 >> 8 & 0xFF 派 A型、正論、頑固、まじめ。 ナンピトたりとも彼の信念を曲げることは出来ない。 頭が固くて時代についていけないタイプも含まれる。 ハマレばあらゆる環境に容易に移植できるすばらしい コードを書く。 ○union 派 AB型、革新的、短絡。 新しいもの好きで、すぐに飛びつく(union自体は新しくも無いが)。 好奇心旺盛のあまり、大怪我をすることもシバシバ。 時代を変革する革新的なコードを書く可能性を秘める。 ○unsigned char *p = (unsigned char *)&val 派 O型、現実的、楽天家、適当。 とにかく動けばOK。ソースはスパゲッティーになりがち。 このタイプの優秀な奴は、あらゆる環境に即座に対応し、 理論よりも現実に沿ったコードを書く。 尚、B型は分類不能。
AB型だけど一番上だよ
A型だがAB型と仕事すると必ず揉めるからやだ
52 :
35 :2007/09/05(水) 22:53:13
>>49 A型とAB型の両親から生まれたおれはA型。
当たってるね。
union (+ビットフィールド)使うのって革新でもなんでもなくて かなーり古い方法でっせ。適用される場面がデバドラ系で、 一般的なコードではほとんど出てこないんで、縁のない人は 一生見ないで終わるかも知れんけどw
>>49 A型で一番上。真ん中はunion作るのが面倒くさい(でも、実際は面倒じゃないよな)
この前、sprintfして文字列操作後にscanfに食わせてるソース見た。 sprintf( buf, "%08X", val); memset( buf1, 0, BUF_SIZE); memcpy( buf1, buf, 2 ); a = strtol(buf1, 0, 16); memset( buf1, 0, BUF_SIZE); memcpy( buf1, buf+2, 2 ); b = strtol(buf1, 0, 16); .... 以下略みたいな
Cでshared_ptr並のスマートポインタってできないの?
俺なら、こんな感じだな。そんな俺はAB #include <cstdio> using namespace std; union my_long { my_long( long val ): value(val){} void show(); unsigned long value; unsigned char bytes[4]; }; void my_long::show() { printf("%08X\n", value ); printf("%02X %02X %02X %02X\n", bytes[0], bytes[1], bytes[2], bytes[3]); } int main(){ my_long ore = 0xFFEEDDCC; ore.show(); return 0; }
58 :
デフォルトの名無しさん :2007/09/05(水) 23:52:14
C言語なのにうっかり参照渡し書いたら なんかコンパイル通っちゃったんだけど C++じゃなくても使えるようになった? コンパイラが機転利かせてくれただけ?
なにをもってC言語なのかは知らないけど、たとえばソースの拡張子が.cでも C++としてコンパイルすることはできるわけだが。
.hにC++コード書いたらちゃんとコンパイルできました><
62 :
デフォルトの名無しさん :2007/09/06(木) 23:06:31
VS2005SEで作った空のC言語のプロジェクトは デフォルトで「C++としてコンパイルする」とかいう謎のオプションが付いてるよーだ?
日本語でおk
基本的な質問なんですが、 char* str = "a"; char ch = str[0]; printf("%s", &ch); とすると"a"の後ろにゴミのようなものがついて出力されてしまいます。 これは何故なんでしょうか? そして、&chを"a"だけにするにはどうすればいいでしょうか? printf("%c", ch);なら大丈夫なんですが、 strcmp(char* s1, char* s2);で使うので、 ポインタかアドレスにしたいです。
char* str = "a"; printf("%s", str);
いやそれは分かるんですが、実際には、 char* str = "abc"; char ch = str[0]; strcmp(&ch, "a"); という感じに1文字目が"a"か判定するのに使いたいので、 strそのままじゃなく、strを1文字に分解したものが欲しいんです。
>>64 C言語で文字列ってのはナル終端文字列で、
char配列で文字の並びを表して最後に'\0'を付加したもの。
>char ch = str[0];
これだと'a'のうしろに'\0'をがないでしょ。
char ch[2];
ch[0] = str[0];
ch[1] = '\0';
printf("%s", ch);
なんでch == 'a'という判定式を使わないのかね
>>66 それなら文字列を比較してるんじゃなくて文字を比較してるんだからstrcmpは不要
if(str[0]=='a')
だめだ、こいつ(ry AA略
72 :
66 :2007/09/07(金) 00:14:41
色々と分かりました。ありがとうございます。
文字の出力なら "%c" だろ。
うん
75 :
デフォルトの名無しさん :2007/09/07(金) 16:27:09
おまいら、型を一々宣言するのめんどくさくないですか? 一々これINT あれは、DWORDってくそめんどくさいぞ
死ねばいいと思うよ
第四世代言語とかあったなー(遠い目)
型指定できないほうが終わってんじゃん
時代は型推論です
低水準な手続き操作がしたいのにコンパイル時の型推論の事も考慮しながらプログラム書くなんてやってられんよ。 型推論はもっと抽象的なところでやっててくれ。
>>81 CやC++でコードを書くときに、どのみち型推論よりもずっと複雑なことを
色々考慮しながらコード書いてると思うが
ポインタは単なるアドレスとだけ理解をしていると、C++の多重継承時の
ポインタのキャスト操作などでハマるし
83 :
82 :2007/09/07(金) 19:57:10
すまん意味不明な例えになった abstractionが不要だと言うのならクラスやテンプレートは要らないし コンパイラが裏で仕事をするのがイヤだというのならC++なんぞは悪のカタマリだ そんならアセンブラだけ使っていればいい
ずいぶんと極端な型推論信者だね
っauto
そんな小細工は型推論とは言わぬ
>>81 関数テンプレートにおける実引数からのテンプレート実引数の導出は、
まさに抽象的なところだと俺は思うよ。
ビット単位の操作とかだろ
ファイルをCreateFileで開いてある状態で、その内容のみを削除するには(ファイル自体は残す)どうしたらよいでしょうか。
>>89 SetFilePointer(hFile, 0L, NULL, FILE_BEGIN);
SetEndOfFile(hFile);
93 :
デフォルトの名無しさん :2007/09/08(土) 09:17:45
C++詳説にはデストラクタは継承されず、仮想関数にはなれると書いてありました。 Accelerated C++では仮想デストラクタは継承されると書いてありました。 これは仮想でないデストラクタは継承されないが、仮想にすると継承される という解釈で良いのですか? ストラウスストラップのプログラミング言語C++第3版には特に言及された 箇所が見当たりませんでした。 実際はどうなのでしょうか?
94 :
デフォルトの名無しさん :2007/09/08(土) 09:44:51
#include <iostream> using namespace std; class B { public: ~B(){ cout << "B::~B()" << endl; } }; class D : public B { public: ~D(){ B::~B(); } }; int main() { D obj; return 0; } このコードですが、bcc32ではコンパイルが成功し実行できました。 結果は B::~B() B::~B() 解釈すると、objが破棄されるときに~D()がコールされ、その定義の中身B::~B()が 実行された後で、Dの基底部分のBが解体されるので再度B::~B()が呼ばれた。 しかしg++では ~D(){ B::~B(); } の部分で以下のエラーが表示されコンパイルできませんでした。 no matching function for call to D::~B() bcc32は怪しい部分が多いので信用していないのですが、g++でコンパイル できない理由はやはり仮想でないデストラクタは継承されないからなのでしょうか?
なにわけわかんないことやってんだ。 これを試せ。 class B { public: /* virtual */ ~B(){ cout << "B::~B()" << endl; } }; class D : public B { public: ~D(){ cout << "D::~D()" << endl; } }; int main() { B *obj = new D; delete B; }
それと、bccを信用しないのは勝手だが おまえの頭の中よりは、ずっと規格(当時)を理解して、それに沿った挙動をしてくれるよ。
97 :
デフォルトの名無しさん :2007/09/08(土) 10:11:23
>>95 レスありがとうございます。
そのコードの動作は分かってます。
virtualをコメントアウトした場合は、
静的バインド機構によって、delete obj; では B::~B()がコールされる
virtualを付けた場合は、
動的バインド機構によって、D::~D()がコールされ、続いてB::~B()がコールされる
知りたいのは、デストラクタを仮想にしなかった場合に派生クラスに継承
されているのかどうかということです。
ですから、あえて派生クラスのデストラクタから明示的に仮想でない
基底クラスのデストラクタをコールしてみたのです。オブジェクトをヒープ
にとるかどうかは問題にしていません。
>>96 そうは思いませんけど。
constオブジェクトから非constメンバー関数が呼び出せてしまいますよ。
警告は出ますが。
”−>”と”.”ってどのような場合に使い分けたら良いのでしょうか?
>>98 gccは配列の要素数が変数で指定できますよ?
>>98 警告が出るなら、わかっていてそれに沿った挙動をしてるのでは。
(そのあとの「配慮」がお節介だな、とは感じるけれども)
というか、詰まるところ「規格と実装の違い」についての質問をしている人間が、
自分のほうが規格がわかってる自信を持つのっておかしいよ。
virtualなしの時、 B *obj1 = new D; delete obj1; B obj2; 上の二つデストラクタ呼び出しが違うよ。
>>101 「規格と実装の違い」についての質問をしているのではありません。
標準C++準拠と謳っている書籍に書いてある内容、つま規格について
知りたいのです。それを検証するために、参考までに二つのコンパイラを
使ってみたということです。
規格上、仮想でないデストラクタが継承されるのかどうかを知りたいのです。
もし継承されるなら ~D(){ B::~B(); } のとおり派生クラスで明示的に仮想でない
基底クラスのデストラクタが呼べるはずと考えたわけです。
104 :
102 :2007/09/08(土) 10:37:13
訂正 B obj2;× D obj2;○
>>100 お前は何を言いたいのだ。配列の要素数に変数を指定できるのはC99の正当な仕様だ。
gccを使って仕様を云々するなら、-std=c++98をつけるくらいのことはしてから言え。
>>102 そうなんですか?
基底クラスのデストラクタが仮想でない場合は、どちらもBのデストラクタだけが
呼ばれると思いますが。
delete obj1 はDクラスオブジェクトのB部分のみを解体する。
B obj2はクラスBオブジェクト自身が解体される。
>>104 訂正後のコードならもちろん違います。
virtualなしの時、
B *obj1 = new D;
delete obj1;
D obj2;
D obj2;については当然クラスDのデストラクタがコールされ、その後
クラスDオブジェクトの基底部分が解体されるのでクラスBのデストラクタ
がコールされる。
ということだと思います。
Bのデストラクタもコールされるということは継承されているということですかね?
何かわからなくなってきました。
>>103 >>101 で言ってるのは、「規格について知りたい」状態の人間が
なんで規格の知識でコンパイラに負けてないなんて自負ができるのかってこと。
>>107 D obj2;の時は静的に結合されたコードが生成されるため、
virtualのあるなしに関わらずB::~B()がコールされる。
virtualを付けるのは、ポインタにしてしまうと元のオブジェクトが
基底クラスをさすのか派生クラスをさすのかを区別できる情報を
付けるため。
継承するしない。で言えばしてるんでしょ。 問題は、ポインタのとき、Dのデストラクタ呼び出しをするにはvirtualが必要ってことでは? そうしないと、Dで確保したリソースが、開放できなかったりする。
まあ継承してる事になるんでしょうね。意識した事はないけど。
>>93 デストラクタを継承という概念で説明するのは正しくない気がするね。
規格では、コンスラクタの呼ばれる順番とデストラクタの呼ばれる順番は
逆になることを定めている。つまり、クラス B から派生した D を構築する
時は B → D の順でコンストラクタが呼ばれ、D を解体する時は D → B の
順でデストラクタが呼ばれる。
この挙動はデストラクタが仮想であるかどうかと無関係。デストラクタ
は普通のメソッドと違い、特別扱いされるということ。
一方、基底クラスのポインタを介して派生クラスのオブジェクトを削除する
場合、基底クラスに仮想デストラクタがないとその動作は不定であり、派生
クラスのデストラクタが呼ばれない可能性がある。これも規格で定められて
いる。
つまり、仮想デストラクタというのは、多態を利用するなら従わざるを得ない
ルールということ。派生クラスを多態として使わないのであれば、仮想
デストラクタを宣言しなくても良い。
12.2.2、12.4.2、15.4.3 あたりを参照。Effective C++ と RAII もね。
俺は規格を知らないけど、コンパイラを規格の知識勝負して負ける気はしないよ!
思っていたのとコンパイラの挙動が違っている時は、99.9999%自分の思い込み違いである
>>115 そうは思いませんけど。
constオブジェクトから非constメンバー関数が呼び出せてしまいますよ。
警告は出ますが。
>>116 そういうあからさまなバグは自ずからわかるだろ
>>116 そりゃ(少なくとも今となっては)規格に
追いついていないコンパイラを使うのは反則だ。
もちろん例えばg++なんかでも高度にテンプレートを
使ったプログラムなら、その確立は99.9999%からがくっと下がる。
boost作ってる奴ってどんなコンパイラ使ってるんだろ Comeau C++とかか?
>>103 ひょっとして問題なのは、「アクセス可能なこと」と「継承」の用語の問題?
JISX3014の10章では、
継承されたメンバはその名前が隠蔽されているか、あいまいな場合を除き、
派生クラスの他のメンバと同様に、式で参照することができる。
と書かれているけど、
>>94 の例とか見ても、スコープを指定しなければいけない
時点で、継承といえないということでは?
例えば、
class C1 {
public: void foo();
}
class C2 : public C1 {
public: void foo();
}
class C3 : public C2 {
public: void foo();
}
と定義した場合、C3 は C1::foo() にアクセスできるけど、C3 が C1::foo()を継承してるとは
普通に言わないよね。
ついでに言えば、コンパイラがオブジェクトを破棄するときの手順に基底クラスの
破棄が含まれていることと、基底クラスのデストラクタを継承することの間に
何からの関連を見出そうととしているあたりも混乱してる気がする。これも言葉の問題か。
>>117-118 つまりコンパイラが規格を知っていることは
あまり期待できないということですね。
>>96 さんの言ってることはやはりデマだったのですね。
>>121 あんまりスレの流れ見てないが。
言語の規格は何度か改定されているのが1つ。
大体のコンパイラは「独自の拡張機能」を持っているのが1つ。
コンパイラが「どの規格」に「どのように」準拠してるのか、知るのが必要じゃない?
結局何が言いたいのかというと、C99、もうちょい流行れ。
Turbo C++の行く末が気になる Boost対応ってテスト全部通す気なのだろうか いやそうなってもらわないと困るのだが無理だと思う
普段使いのコンパイラが対応してくれないと覚える気になれない。 VCがC99対応するのはいつなんだろう。
とりあえずC99の可変長引数マクロはすべてのコンパイラで採用するべき
>>112 >>113 理解できました。確認不足で失礼しました。
AcceleratedC++で仮想デストラクタが継承されると言っているのは
他の仮想関数と同様に派生クラスのデストラクタも仮想性を持つ
ということで納得できました。
>あと、
>>94 がg++でコンパイルエラーになるのは~がビット否定演算子と解釈されるため。
そういうことなのですね。勉強になりました。
ありがとうございました。
>>120 読んでいた書籍で『仮想デストラクタは継承される』という記載
があったので混乱していました。
デストラクタは継承されないけれども基底クラスのデストラクタを
仮想にしておかないと、基底のポインタや参照が指している実際の
のオブジェクトが派生クラスのオブジェクトであった場合、
派生クラスのデストラクタが呼び出されなくなってしまうということ
で理解しました。
>>120 例えば、
class C1 {
public: void foo();
}
class C2 : public C1 {
public: void foo();
}
class C3 : public C2 {
public: void foo();
}
と定義した場合、C3 は C1::foo() にアクセスできるけど、C3 が C1::foo()を継承してるとは
普通に言わないよね。
インターフェースを継承している、つまりC3はC1::foo()を継承していると思っている
のですが問題ですかね?(この場合は、もちろん名前は隠蔽されてしまいますが)
128 :
127 :2007/09/08(土) 15:38:55
>>120 >スコープを指定しなければいけない
>時点で、継承といえないということでは?
確かに。もっともです。
クラスの継承って事はその中身までも継承するってことで、 すべてのメンバは継承してるって解釈じゃダメですか? 基底クラスの private メンバも継承している。でも自分でもどうにもできないのは、 言うなれば、自分の骨とか内臓を直接見ることができないのと同じ様な事かと思った。
130 :
127 :2007/09/08(土) 15:47:07
>>113 デストラクタが継承されないのにthis->~B()で呼び出せる
ということが結びつきません。。名前が隠蔽されてるわけでもないし、
あいまいでもないので、
>>120 さんが書かれているとおり
継承されたメンバに含まれる気がします。
131 :
127 :2007/09/08(土) 15:50:31
>>129 確かにprivateなメンバも継承されていて、それは派生クラスから
直接アクセスはできないだけで、派生オブジェクトの基底部分とし
ては存在していますからね。
132 :
デフォルトの名無しさん :2007/09/08(土) 19:15:08
以下のようなpiyoクラスがあるとします [piyo.h] #include "Enemy.h" class piyo{ ... public: ... Hit( CEnemy *pEnemy ); // 当たり判定に敵クラスが欲しい }; このpiyoクラスを拡張してEnemyクラスにも持たせたくなったんですが無理ですよね? 何かいい方法ありませんか?
意味がわかんねんだけど なんで無理だと思うのさ
134 :
デフォルトの名無しさん :2007/09/08(土) 19:26:03
piyoクラスがEnemyクラスを使ってるので(?)コンパイルエラーになります
>>134 使い方による。
以下のようにお互いが相手の実体をメンバに持つことは不可能だが、
class piyo {
Enemy e;
};
class Enemy {
piyo p;
};
以下のように片方(または両方)がポインタのみの保持であれば問題ない。
class Eme,u;
class piyo {
Enemy* e;
};
class Enemy {
piyo p;
};
定義(includeも)の順番が逆とか単純な理由だったり。
includeの順番を変えて
>>135 さんみたいにしたらコンパイル通りました
ありがとうございます
>>112 > 一方、基底クラスのポインタを介して派生クラスのオブジェクトを削除する
> 場合、基底クラスに仮想デストラクタがないとその動作は不定であり、派生
> クラスのデストラクタが呼ばれない可能性がある。これも規格で定められて
> いる。
未定義動作だよ。 5.3.5p3 ね。
バイナリかテキストを判別する方法?又はそういう関数みたいなものはありますか?
テキストは文字コードのみで構成されたバイナリ
ISO-8859-1だと思えばどんなバイナリもテキストファイル
CStringWなどの比較関数を使うのと、wchar_t型の配列を作って自前で比較するのでは 単純にどちらの効率がいいのでしょうか?
この手合いは、所詮「統計的にどっちか判定する」だけであって、100%判別じゃない これがわかれば(すんなり割り切れれば)、ニーズに合った実装が自力でできるかと
>>143 実際にCStringW等の実装を覗いてみるといいと思う。逆汗とかで。
…煽りじゃなくて。実際にライブラリを覗くことが、こういった疑問への一般解を実感させるかと。
俺?必要に応じて、毎度見てるよ
C/C++をスラスラ書けるのに、情報関係の資格を持ってなかったらクソですか?
情報関係の資格を持ってるのに、C/C++をスラスラ書けない方がクソです。
スラスラ書けるというやつにろくな奴はいない実感しております 特に低学歴に多い プログラムは書けるがそれを活かす分野の知識がまるで無い 大学1年並の一般教育の知識すらない専門卒は最悪だった
そうそう特に
>>150 なんてのはズバ抜けてひどかった
ふむふむ。 プログラムを活かす分野の専門知識に欠けていた訳だな 中卒の俺は。 参考になったありがとう!
>>145 CStringT<>はヘッダに実装されているぞ。
逆汗するまでもない。
friendの使い方ってこんなかんじでいいのでしょうか? class 貞操帯 { friend ご主人様; void Unlock(); public: void Lock(); void 浣腸(液体& 浣腸液); };
ダメです。
"d:\temp\file.txt" ↑のようの文字列からダブルクォーテーションを一撃で消し去ってくれるような 素敵な関数は存在しますか?
文字列+1の位置から文字列の長さ-2をコピーすれば言いだけの話。
Cには無いかな C++だとstringクラスのreplaceとかで。
char *str; int length; ....... str++; length -= 2; ぷ
自分で作ってみます。ども
char str[] = "\"d:\\temp\\file.txt\""; char* pos = str; if (*pos != '\"') return; do { if (*(pos+1) == '\"') { *pos = '\0'; break; } *pos = *(pos+1); pos++; } while(*pos != '\0');
shlwapiとかに便利そうな関数がありそうだったのでみてみるとよさげ 自分も前から気になってるんだが、ちゃんとみれてない まあ、shlwapiすら重くて糞だという応用ならしょうがないが
…あ。早漏した \x22を消したいのか それなら自分で書いた方がはやいかも
sprintf(buf, "%.*s", strlen(str) - 2, str + 1)
>>156 #include <iostream>
#include <string>
#include <algorithm>
int main() {
std::string path("¥"d:¥¥temp¥¥file.txt¥"");
std::string result;
std::cerr << path << std::endl;
std::remove_copy(path.begin(), path.end(), std::back_inserter(result), '"');
std::cerr << result << std::endl;
}
std::string hoge("¥"d:¥¥temp¥¥file.txt¥"");; boost::trim_if(hoge, boost::is_any_of("\"")); // hoge -> d:\temp\file.txt
char str[] = "\"d:\\temp\\file.txt\""; PathUnquoteSpacesA(str);
169 :
デフォルトの名無しさん :2007/09/09(日) 20:10:28
vs2005を使ってます。 vector<hoge*> m_vecHoge; とかでもってるメンバを vector<hoge*>::iterator itr = m_vecHoge.begin(); while( itr != m_vecHoge.end() ) { itr->hogefunc(); ++itr; } のように使おうとしたら オーバーロードされた 'operator ->' の戻り値の型 'hoge **' が無効です。 と怒られました。 よく分からないので *itr->hogefunc(); とか itr++; とか変えてみてもダメでした。 iteratorを使わずに[]でアクセスすればコンパイルできるんですが、なぜでしょうか? 他の場所では同じ方法でiteratorを使えてるんですが(要素は別のクラスですが)、 ここだけなぜかつかえないです。 何が原因でしょうか?
>>169 (*itr)->hogefunc();
これじゃだめ?
>>170 いけました!
他の場所も良くみたら->を使うときはカッコで囲ってました。
ありがとうございました。
172 :
169 :2007/09/09(日) 20:52:42
list<Hoge*>::iterator itr = m_listHoge.begin(); for(; itr != m_listHoge.end(); itr++) { if((*itr)->GetLife() < 0.0f) { delete *itr; *itr = NULL; m_listHoge.erase(itr); } } 連続ですいません。今度はlistなんですが、 上のような感じで、listの要素が持ってるLifeがゼロになったら、listからその要素を消したいです。 が、実行画面上で消えた瞬間、 list iterator not incrementable とかいうstlのエラーがでて強制終了します。 なんでですか? ちなみに、このlistを使ってるのはここ一箇所なので、エラーは間違いなくここで起きていると思います。 また、listに入ってる要素は一個です。
>>172 イテレータで回している間に、要素数の変化する操作は未定義じゃないかな?
>>172 イテレータはコンテナごとに定められたルールに従って無効になることがある。
無効になったイテレータは ++ でのインクリメントも要素へのアクセスもできない。
list では erase() したイテレータは無効になる。 erase() の前に次のイテレータを
取っておくか、 erase() の戻り値を使うといい。
アドバイスいただけたらうれしいす。 「やさしいC」と「新C言語入門ビギナー編」まではものにできたド初心者です。 基本情報の擬似言語対策でアルゴリズムの勉強しようと思ってるんですが、 お薦めの参考書はないでしょうか? とりあえずヤフオクで「Cアルゴリズム全科」って分厚い本買ったんですが・・・・ もっとわかりやすいの・・・プリーズ・・・
>>156 d:\"temp"\file.txtみたいなものはいいのか?
Windows XPなんかでは使えるんだこれが。98とかだとしらないけど。
>>178 ごめん、試してみたらコマンドプロンプトだけっぽい。
>>176 の言うとおり過去問題集するか、Cで色々作ったりするのがいい
正直基本情報の擬似言語はちゃんとCでプログラム書けるなら勉強しなくても
分かるぐらい簡単
>>180 >>181 レスサンクス。
ですよね。ソース打てない人が理解する為に擬似言語があるんですよね・・・
とりあえず過去問をCで打ち変えるとこからやってみようと思います。
でわ
CのAPIによっては、(特に文字列の)ポインタを関数などに渡すときにconstがない場合があると思います。 std::string s = "hoge"; c_api_func(s.c_str()); // error: c_api_func(char *); これらのAPIは文字列のコピーを作成して使うので、ポインタの指す文字列が変わらないことはないだろう、 と分かっていても、const_castするのは勇気がいると思います。 ここで、プロの人はどうしますか? std::string s = "hoge"; std::vector<char> v(s.begin(), s.end()); c_api_func(&v[0]); はどうでしょうか。
>>183 s.c_strはヌル終端文字列で、vector vはヌルを最後に持ってない気がする
けど、この違いは大丈夫?
c_api_func()がどういう処理をするかによるけど
c_api_func( const_cast<char*>( std::string(s).c_str() ) );
186 :
185 :2007/09/10(月) 19:53:48
誰か突っこめよ><
APIがこの先変わらず内容を書き換えないのであればconsr_cast
>>186 おれさあ何とかcastとか色々あるけど、よくわかんねえ
てか使う機会に出会ったことねえ
申し訳なさげにstatic_castは使ったことある
>>186 正直不安に思ってたりして、笑えねえよ
_bstr_tあたりにちょっと持たせるとか、
allocaするとかしないといけないかなあとか思ってみたり
使い捨てのものだから、まあ大体は結局ほったらかしてるけど…。
#define deleate delete
#define buuru bool #define turu true #define faruse false #define wtyaa wchar_t #define kurasu class #define storuct struct #define yunion union #define dexisu this #define pabrick public #define purotekuteddo protected #define puribate private #define ekusuprist explicit #define hurend friend #define baatyuaru virtual #define opereetaa operator #define konsuto const #define inrine inline #define sutatikku static #define ekusuteen extern #define nyuu new #define deriito delete #define torai try #define kyatti catch #define suroo throw
ガイキチがあらわれた
>#define puribate private なんじゃこりゃw
#define ittouhei private
さすがお前だ
>#define nyuu new これ萌えていい?w
>#define storuct struct 微妙だなw
「ぃ」は li な俺に #define dexisu this はいただけない
dhisuだろあほ
thisがズィスな俺にも#define dexisu thisはいただけない
dexisuってなんか格好良いかもw
#define WIndow Window #define ture true これは外せん
#define amin main #define unsgined unsigned #define retrun return
ネタマクロスレになりますたw
俺が欲しいのはこれぐらいだ。 #define retrun return #define signed singed #define unsigned unsinged こいつは要らんな。 #define トントカイモ system #define スイカナスミ return
コピーコンストラクタとoperator=って、 やっぱり同じ内容でも別々に書かないといけないものなんですか? まったく同じ引数(自クラスのconst参照)を取って、代入する内容も同じなのに、 同じメンバ代入や複製のコードをそれぞれに書くのがどうも解せないんですけど。 なにか一つにまとめる方法とかがあれば教えていただきたいです。
同じじゃないよ。 class MyString { private: char *ptr; public: MyString(const MyString& s) { ptr = new char[strlen(s.ptr) + 1]; strcpy(ptr, s.ptr); } MyString &opetator=(const MyString& s) { delete[] ptr; ptr = new char[strlen(s.ptr) + 1]; strcpy(ptr, s.ptr); } };
もしほんとに同じの場合は、単にコピーコンストラクタから代入演算子を呼び出せばいい。 MyString(const MyString& s) { *this = s; } この例だとゴミポインタを delete[] してふっとぶけど。
MyString &opetator=(const MyString& s) { if (ptr) delete[] ptr; ptr = new char[strlen(s.ptr) + 1]; strcpy(ptr, s.ptr); } }; これで解決
前にoperator =の実装にコピーコンストラクタを使うのはだめか って聞いたんだが、やめとけって答えられた覚えがある。 #include <new> class Hoge { public: Hoge(); Hoge(const Hoge&); Hoge& operator =(const Hoge& y); { if (this != &y) { this->~Hoge(); ::new(this) Hoge(y); } return *this; } };
>>213 >if (ptr) delete[] ptr;
ptr がゴミ値のときにふっとぶのは一緒
だいたい NULL 判定しなくても delete[] NULL; は許容されている
>>211-215 ご意見ありがとうございます。
コピーコンストラクタの中で
*this = s;
ってやる方法、自分も同じこと考えました。
この方法でコピーコンストラクタとoperator=を一緒にしてしまっても、
基本的には問題無いですよね?
>>216 >基本的には問題無いですよね?
だから、一般的には問題あるってんの。
問題ない場合は、 *this = another; していいけど、
そんなものはケースバイケース。
>>216 メンバーがクラス型の時も大丈夫か?
メンバーが先に生成されるからコンストラクタもメンバーから呼ばれると思う。
メンバーのコンストラクタに引数渡したい場合とかに無理がないかな?
なにを質問してるんだお前
>>185 せめてこう
{
std::string tmp(s);
c_api_func( const_cast<char*>( tmp.c_str() ) );
}
c_api_funcがconstは付いていないけど、 実際には書き換えないことがわかっているという場合だろ。 そこまでする必要は無いと思う。
c_api_func( const_cast<char*>( std::string(s).c_str() ) ); とりあえず、↑はまずいと言いたかった。
まずい理由を詳しく
>>221 テンポラリ用意しても、c_str()で返されるconstな領域に書き込まれたらダメだよ。
そこまでするんだったら
std::vector<char> tmp(s.begin(), s.end());
tmp.push_back('\0');
c_api_func( &tmp[0] );
とした方がいい。
#define BEGIN_TO_END(rng) boost::begin(rng),boost::end(rng) std::vector<char> tmp( BEGIN_TO_END(s) );
変数の宣言に関して質問です。 int main(){ int a[5], b[5], c[5], i; int *p; p = c; for(i = 0;i < 15;i++){ //初期化 *p = 0; cout << *p << endl; p++; } for(i = 0;i < 5;i++){ //確認 cout << a[i] << "," << b[i] << "," << c[i] << endl; } return 0; }
それはやるな。
229 :
えいいち ◆GRGSIBERIA :2007/09/11(火) 17:14:56
上のソースだと、c,b,aの順に、つまり宣言の後ろから順に変数がメモリに割り当てられていますが、 コンパイラによってはa,b,cの順、つまり宣言の前から順に変数がメモリに割り当てられますか? あと、別の場所で宣言した変数がa,b,cのいずれかの間に割り当てられることもありますか?
鼻から悪魔
a, b, c がメモリ上のどの位置に確保されるかは不定。 連続である保証はない。
コンパイラによっても違うし、同じコンパイラでもオプションによって違ったりする。 コンパイラの内部仕様なので、並び順に依存したコードの動作は保証されない。 例えば、VCの場合、/O1オプションを付けると、領域を最小化するため、 変数の要素サイズの順に並べ替えが行われたりするが、/O1を付けない場合には また別の順番になる。いずれも、宣言順がそのまま反映されることはない。
>>223 の書き込みを見て、ふと昔の自分のコードが不安になりました。
一時オブジェクトの解放のタイミングについて教えてください。
CString s1 = "C:\\hoge\\";
HANDLE hFile = CreateFile(s1 + "fuga.txt", …);
これって、
>>223 でダメ出しされてるのと同じようなコードだと思うけど(実引数でCString
の一時オブジェクトを作成し、一時オブジェクト内で管理する領域のアドレス
を関数に渡す)、やはり仕様的に問題があるのでしょうか?
JISX3014 12.2
一時オブジェクトの解体は、それを生成した地点を(字句的に)含む完結式の評価の
最終段階で行う。
1.9
他の式の部分式となっていない式を完結式と呼ぶ。
実引数の評価は、その関数本体の式又は文の実行に先行する。
調べて、上の記述までは見つけたけど、以下の3点の疑問が残り、よく理解できていません。
- 完結式の定義について。実引数の場合はカンマで区切られた一つ一つの事を指すのか?
それとも、カンマで区切られた一つ一つは部分式で、完結式は関数呼び出し全体を指すのか?
- 実引数の評価直後(関数を呼び出す前)に一時オブジェクトは解体される可能性があるのか?
それとも、完結式が関数呼出し全体なら、破棄は関数呼び出し完了まで待ってもらえるのか?
- VC2005では実引数内で上記のような一時オブジェクトを使う演算を行った場合、
デストラクタは関数の呼び出し後に動作しますが、これはたまたまなのか? 想定される動作なのか?
この疑問について、教えていただけないでしょうか。
>>234 s1 + "fuga.txt"の一時オブジェクトは
HANDLE hFile = CreateFile(s1 + "fuga.txt", …); のあとに消滅する
hFileがその一時オブジェクトに依存しているとクラッシュする
がそんなことは実際起こらない。CreateFileは一時オブジェクトを
コピーして使うから。そしてそれはドキュメントされてない
だからOS依存のAPIは出来る限り使うべきではない。
たとえばPathFindFileNameはコピーしないので本当にクラッシュする
>>234 完結式はその場合、初期化子全体なので、そこではその関数呼出式全体。
なので残りの2つの問いも、それぞれ問題ないということになる。
>>235 本当は、constなポインタの引数なのに
指す先を書き換えるほうがいけないんだよな。
そうだよな
238 :
234 :2007/09/11(火) 21:24:40
>>235 ありがとうございます。
さすがに後続行までの保証は考えていません。
1行分が完結するまでの間有効ならば十分です。
>>236 ありがとうございます。
完結式の示す範囲が関数全体と聞いて安心しました。
とすると、
>>223 も動作的には
>>221 とほぼ等価で問題ないって事ですよね。
指摘がスタイルとかの問題ならば別ですが。
239 :
デフォルトの名無しさん :2007/09/12(水) 12:43:50
void HogeManager::Update(float elapsed) { if( m_listHoge.empty()) return; list<Hoge*>::iterator itr = m_listHoge.begin(); while(itr != m_listHoge.end()) { (*itr)->Update(elapsed); if((*itr)->IsExpired() == true) { delete *itr; *itr = NULL; itr = m_listHoge.erase(itr);//消すときは次のiteratorを取って置く } if(m_listHoge.empty())break; ++itr; } } なんかstlのlist使ったら list iterator not inclementableとかいうエラーがでます。 以前同じような質問をしたときに listのiteratorはeraseした後無効になるから、戻り値をとっておけといわれて これで直ったような気がしてたんですが、やっぱエラーがでました。 listを消したりインクリメントしたりする操作はこの関数内でしか行ってません。 iteratorの使い方とか間違ってるでしょうか?
>>239 > if(m_listHoge.empty())break;
を
if (itr == m_listHoge.end()) break;
じゃない?
eraseの戻り値がend()でも、リストが空とは限らないでしょ。
241 :
240 :2007/09/12(水) 13:08:01
>>239 むしろこうするべきか。
if ((*itr)->IsExpired()) {
...
itr = m_listHoge.erase(itr);
} else {
++itr;
}
そうしないと、eraseしたときにiteratorが進みすぎてしまう。
>>241 elaseして戻り値貰った時点で
そのitrはすでに次に進んでるわけですね。
それがendだったときに
さらに++itrしてたからエラーが出ていた、と。
なるほどありがとうございました。
ついでに言うと、trueと比較するのは(仮令まともなbool型があるC++とはいえ)止めた方がいい。 と、>241は指摘していると思う。
244 :
デフォルトの名無しさん :2007/09/12(水) 17:43:00
>>244 1はtrueだがtrueは1だけではないから
void HogeManager::Update(float elapsed) { if (m_listHoge.empty()) return; typedef list<Hoge*>::iterator Iter; for (Iter i = m_listHoge.begin(), end = m_listHoge.end(); i != end; ) { (*i)->Update(elapsed); if ((*i)->IsExpired()) { delete *i; i = m_listHoge.erase(i); } else { ++i; } } }
>>245 どういうことですか?よくわかりませぬ・・・
コンパイラによって違うとか?
>>246 delete *i;
*i = NULL; ←これって必要ないんですか?
よくSAFE_RELEASEマクロとかでこんな風になってるのがあったような気がして。
>>247 (*i)はdelete後にeraseによって消えるのでわざわざそんなことする必要は無い
#include <stdio.h> int main() { for(int i=-2; i<3; i++) printf("%2d %s\n", i, (i==true ? "true" : i==false ? "false" : "???")); putchar('\n'); for(int i=-2; i<3; i++) printf("%2d %s\n", i, (i ? "true" : !i ? "false" : "???")); return 0; } //実行結果 -2 ??? -1 ??? 0 false 1 true 2 ??? -2 true -1 true 0 false 1 true 2 true
>>247 trueとの比較について
・boolを返すプロトタイプを持つ関数が、true(実体は1)の代わりに2を返すかもしれない
・一般的なCPUでは0との比較のほうがコストが低いかもしれない
・C/C++ではif文の意味は、()の中が「0でなかったら」なので== trueと書くべき理由が無く、読み取りにくくなるだけ
deleteしたポインタへの代入について
・そのポインタを再利用するなら意味はあるが、直後に更新するのだから意味が無い
・マクロで更新しておくのはまぁ勝手だが、あまり意味がないことには変わりが無い
>>250 > true(実体は1)の代わりに2を返すかもしれない
たとえそれでもtrueとの比較は真でなければおかしい。
プロトタイプ宣言はboolのくせに、
戻り値intという定義だというのでもない限り。
> 一般的なCPUでは0との比較のほうがコストが低いかもしれない
そんなこと、最適化でどうにでもなる。
> == trueと書くべき理由が無く、読み取りにくくなるだけ
これは同意。== trueと書くやつの気が知れない。
少し違う例だけど。
http://www.kouno.jp/home/c_faq/c9.html#2 > もし君が「if((a == b) == TRUE)」が「if(a == b)」の改良版であると信じるのなら、
> なぜそこで止めるのか。なぜ「if (((a == b) == TRUE) == TRUE)」を使わないのか
>>251 >プロトタイプ宣言はboolのくせに、戻り値intという定義
市販ライブラリではホントにこんなのがあるんだ。流石に2は戻ってこないが。
253 :
デフォルトの名無しさん :2007/09/12(水) 18:48:47
int型の比較ならif(i==10)とか書くわけで、 そういうのとの統一感が取れてるって意味で視認性はむしろいいと思うんだけど。
if(i == true)となってれば後で見たときにiがbool型って分かりやすい。 if(i)では中身が何型を想定してるのか分かりにくい。
C系の言語は否定演算子が!一文字で、紛れやすいのが難点だと思う。 #define NOT(exp) (!(exp)) if (predicate()) if (NOT(predicate()))
見難い云々は書き方次第だろ
>>254 名前の付け方しだいによるでしょう。
if (something->isExpired() == true) は、いかにも冗長。
bool値を返すことが名前だけから判断できないような関数なら
if (p->doSomething() == true) もありかも。
自分で命名する関数が論理値を返すなら、そんな命名はしないけど、
システムコールやライブラリの名前が、一見して論理値を返すように見えなければ
true や false と比較するコードを書いてもいいんじゃないかな。
258 :
257 :2007/09/12(水) 18:59:53
なんか日本語がへたくそだ。>オレ
つハンガリアン記法
ごくたまに !!a というのを見ることがあるのですが これは「aがTRUE(の実体)とFALSE(の実体)のどちらとも等しくない」ことを防止するためにやってるのでしょうか?
>>260 aが0なら0(false)
aが0以外なら1(true)
if (a == 10) {} if (obj->isAlive() == true) {} 前者の解釈は「もしaが10なら」 後者の場合は「もし『objが生存しているなら』が真実なら」 となって後者の方は少し長冗。
264 :
252 :2007/09/12(水) 19:33:40
>>261 うん、それは承知しているけどBOOL型って突っ込みが来そうだからやめておいたんだ。
整数型、bool型の使い分けに関して(自分の指針) (aは整数型、is_newlineはbool型) 1,原則として条件式にはbool型を使う。 if(a) はたまに見かけるが、「もしaなら」というのは論理的には意味不明。 2,整数型の比較には ! を使わず、他の比較演算子を使う。 if(!a) よりも if(a==0) の方が圧倒的に分かりやすいし、1と同様に「もしaでないなら」というのは理論的には解釈不能。 3,bool型の最比較はしない。 if(is_newline==true) は少し無駄がある。if(is_newline)で十分。 4,bool型の反転には比較演算子ではなく、! を使う。 if(is_newline==false) よりも if(!is_newline)。後者の方が「改行ではない」ことが分かりやすい(と思う)。 bool型は単独でも論理学的な論理の意味をなすが、 整数型は単なる整数であり、そういった性質を持たないという点が両者の最大の違い。 この指針が絶対だとは思わないので、まあ一つの参考として見たって下さい。
よし、それもらった
俺は == で真偽判定は全部しないようにしている。
268 :
デフォルトの名無しさん :2007/09/12(水) 20:15:38
> 1,原則として条件式にはbool型を使う。 > if(a) はたまに見かけるが、「もしaなら」というのは論理的には意味不明。 値がゼロかどうかで判断したいんでしょう。
>>267 菊池 真の判定ではなく偽の判定をするなら==を使うだろ
?
!
272 :
デフォルトの名無しさん :2007/09/12(水) 21:20:23
クラスのメンバ関数の宣言、定義するファイルについて メンバ関数宣言、定義って普通別々のファイルにするのですか? たとえば、.hファイルには関数宣言だけして、定義は.cppファイルにする。 それとも、.hファイルにメンバ関数宣言、定義(クラス外に)をする
(例としてWin32APIの)構造体を初期化するとき、今までこんな感じにしていた。 OPENFILENAME ofn; ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = wnd; ...; // 構造体メンバのポインタでNULLでかまわないところは設定しない GetOpenFileName(&ofn); よく考えたら、このプログラムは「ヌルポインタのビット表現は0」であることを前提にしてるので、やばいのではないかと思った。 やはり ofn.lpstrFilter = 0; // ヌルポインタにしていく ofn.lpstrCustomFilter = 0; というように、全て設定しないといけないよね? ところで、初期化するときに、 OPENFILENAME ofn = {0}; とした場合はどうなるのだろう。ZeroMemory/memset(..., 0, ...)と同じなのか、全てのメンバに対して = 0 を設定しているように動くのか。
>>272 メンバに代入とかprivateメンバの値を返すだけとかは当然.hに書く。
クラスで使う他のヘッダをクラスのヘッダで#includeしてクラスの.cppではクラスの.hだけを#includeする。
基本的に.cppを書くようなクラスなら、そこに関数定義を書く
>>273 Win32ベッタリなコードでヌルポインタのビット表現など気にしても
仕方が無い気がするが……
= { 0 };
でもいいし、どっちでも好きに汁
276 :
デフォルトの名無しさん :2007/09/12(水) 22:49:45
例えば「順位(int)」と「名前(string)」のセットがstlの何らかのコンテナにばらばらに入れてあるとして、 それを「順位」順で並べ替えたいんですが、できる方法ってありますか?
あります。
278 :
デフォルトの名無しさん :2007/09/12(水) 22:53:28
2点質問があります。 1.関数で配列全体を呼び出しもとに帰すにはどう記述すればよいのでしょうか? 例)a[0],a[1],a[2],a[3]といった、算出した値を配列要素としてではなく、配列全体をreturn文で返す 方法がわからずにおります。 2. 1+X+X^15で生成する疑似ランダムデータの作製法がわからずにおります。 どうかご教示願います。
279 :
デフォルトの名無しさん :2007/09/12(水) 22:55:17
>>278 C/C++ではそもそも配列全体を値渡しすることができないので、参照渡しかポインタの値渡しになる。
従って、戻す方法を考える必要がない。と言うか、戻す方法はない。
281 :
デフォルトの名無しさん :2007/09/12(水) 23:04:26
>>280 先月から始めたプログラミング初心者なので、もうしわけありませんが、具体的な記述例を教えて頂けないでしょうか?
参照渡しとは何でしょうか?
main()
関数呼び出し
関数本体
[配列要素に値を代入して、代入した配列全てを呼び出しもとに返す]
>>278 1. についてはC++ならvectorで返すのが良いと思う
2. については
int myrand(void){
static int x;
x=1+x+pow(x,15); // or x=1+x+x^15; ???
return x;
}
>>281 void hoge(int *piyo)
こんな感じに(配列の)ポインタを渡して、書き込む
284 :
276 :2007/09/12(水) 23:06:52
どうやらmap とかmultimapに入れていけば勝手にソートしてくれるみたいですね。 失礼しました。
285 :
デフォルトの名無しさん :2007/09/12(水) 23:19:32
>>282 2.についてはハードウエアではシフトレジスタで合成可能(Verilog)なんですけど、
おしえていただいたものも、シフトレジスタ相当なものでしょうか?
初心者から見ると数式に見えるんですけど。回路は以下のとおりです。
|〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜EXOR|
| |〜〜|
→X→X→X→X→X→X→X→X→X→X→X→X→X→X→X|→
>>255 そんなものを#defineせずとも、こう書ける。
if (not predicate())
Cなら<iso646.h>をインクルード、
C++なら何もインクルードすることなく(notはキーワードだから)可能。
287 :
デフォルトの名無しさん :2007/09/12(水) 23:23:21
>>283 この記述は関数呼出し元に書くのでしょうか?それとも関数本体に書くのでしょうか?
すみませんが、具体的に書いて頂けないでしょうか?1ヶ月もしない初心者なもので、
わからずにおります。
288 :
デフォルトの名無しさん :2007/09/12(水) 23:26:13
|〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜EXOR| | |〜〜| →X→X→X→X→X→X→X→X→X→X→X→X→X→X→X|→
289 :
デフォルトの名無しさん :2007/09/12(水) 23:28:24
>>288 うまく書けなくてすみません。一番右側のXの出力と右から2番目のXのEXORをとり、 それを一番左側のXの入力とするものです。
>>285 もし、SystemC なら malloc の類は使えないと思ってください
ついでにいうなら文法が似ているだけで別の言語です
ハードウェア板に行ったほうが良いと思います
>>278 配列を構造体に閉じ込めれば、その構造体ごと返すことは可能。(制限はある)
ただし、そのために構造体を作りたくないという場合、他の人の言うようにポインタでやりとりする。
>>286 bool a = true;
if(not a) ;
って使ってみたらコンパイルエラーだったんですが…。(bcc)
未定義のシンボル not(関数 main() )
>>289 こんなもんかな?
int myrand(void)
{
int x[15];
// シフトレジスタ
for(int i=15-1;i>0;i--) x[i]=x[i-1];
x[0]=x[13]^x[14];
return x[0];
}
295 :
デフォルトの名無しさん :2007/09/12(水) 23:47:39
>>283 こんな感じでしょうか
#include <stdio.h>
void hoge(int *piyo)
int main()
{
int *piyo2;
a=hoge(piyo2);
}
int hoge(int *piyo)
{
piyo=c+d;
return piyo;
}
296 :
290 :2007/09/12(水) 23:51:11
点で話にならない。先月からはじめたと言うことは、少なくとも10日は経つのだろう。 それで未だそんなことを書いているようではどうしようもないな。
298 :
デフォルトの名無しさん :2007/09/12(水) 23:52:09
299 :
デフォルトの名無しさん :2007/09/13(木) 00:05:49
>>297 先月からといっても5日間しか触れていませんが、与えられたことをこなさなければならず、困っております。
どうか正解を教えて頂きたいとねがいます。
300 :
294 :2007/09/13(木) 00:08:35
>>298 なんか
>>294 は違う気がしてきた
仮に x= 0001101110110001 <- 2進数表現
が与えられた時、これだけで次の x の値は決定される?
もし決定されるとしたら x の値はどうなる?
struct Random { int reg[16]; Random() { // オールzeroだとまずいので適当に初期化 // reg[i] は 0 or 1 です for (int i=0; i<16; ++i) { reg[i] = i % 2; } } int rand() { // EXOR int bit = reg[0] ^ reg[1]; // reg[14:0] <= reg[15:1] for (int i=0; i<=14; ++i) { reg[i] = reg[i+1]; } // reg[15] <= reg[0] ^ reg[1] reg[15] = bit; return bit; } };
302 :
デフォルトの名無しさん :2007/09/13(木) 00:16:08
>>300 決まります。
1000110111011000=X
とすると、次のXは0になります。XとX[1]のEXORをとって一番左側のX[15]に代入して全体を1ビット
左にシフトして、次の出力を得ます。
303 :
294 :2007/09/13(木) 00:25:51
>>302 ってことは
>>301 の通りってことか
(
>>301 ESPレベル高いよ。すごいよ。)
> 全体を1ビット左にシフトして
全体を1ビット 右 にシフトして の間違い?
304 :
デフォルトの名無しさん :2007/09/13(木) 00:29:32
>>297 この程度しか思い浮かびません。手元に教科書も無く、感で書きました。申し訳ございませんが、
間違いを指摘して頂きたいと願います。お手数お掛けしますが、どうかよろしくお願いいたします。
#include <stdio.h>
void hoge(int *piyo)
int main()
{
int *piyo2,x;
piyo2=&x;
a=hoge(piyo2);
}
int hoge(int *piyo)
{
piyo=c+d;
return piyo;
}
305 :
デフォルトの名無しさん :2007/09/13(木) 00:30:46
306 :
294 :2007/09/13(木) 00:33:38
C言語で書くとこんなもん?
int myrand(void){
static unsigned short x=0x8DD8;
int bit;
bit=(x&1)^((x
>>1 )&1); // x[0]^x[1]
x=(bit<<15)|(x
>>1 );
return bit;
}
void GetArray(int *piyo) { int piyopiyo[] = { 5, 6, 7, 8 } piyo = piyopiyo; } int main() { int piyo[] = { 0, 0, 0, 0 }; GetArray( piyo ); return 0; }
309 :
294 :2007/09/13(木) 00:58:15
環境持ってないから確認できないけど RTL では piyo[15:0] として piyo = 16'b0010101000111011 みたいに代入できたような気がするから 下みたいにすればいける*かも*しれない void hoge(int *piyo) // piyo[15:0] { *piyo=0x1234; } もうスレ違いとしか言えないや…
310 :
293 :2007/09/13(木) 00:59:50
>>286 gcc で出来た。安易なレスしてすまんかった。
311 :
デフォルトの名無しさん :2007/09/13(木) 01:05:50
>>301 ,307
ありがとうございます。307は正解だと思ってよろしいのでしょうか?
>>304 間違いが多すぎて突っ込むのも面倒なくらいだけど、
まず何より、配列に要素を入れて返したいという話なのに、どこにも配列が存在しないのはなぜ?
勘で書いたというが、何も考えていないのではないか?
>>311 IDの出ない板なのだから、せめて名前欄に何か書いたら?
それと307は不正解。
>>312 これは推測だけど
おそらくはC/C++に似ている言語についての質問だから
配列といっているのはビットアレイ(すなわち整数型)って意味で、
結局
>>309 みたいなのでいいんじゃないかな
もしくは
int add(int a, int b){return a+b;}
でもよさそうな気がする
>>311 void foo(int *p, n)
{
//ここでpが指す配列(p[0]〜p[n-1])に値を設定する
}
int main(int argc, char *argv[])
{
int a[100];
foo(a, 100);
// 配列aには関数foo()で設定した内容が入っている
}
317 :
316 :2007/09/13(木) 01:21:38
× void foo(int *p, n) ○ void foo(int *p, int n)
318 :
hiro :2007/09/13(木) 01:45:48
>>312 どうか間違いを指摘して頂きたいと願います。5日間しかCに触れていないので、
全く解らない状態です。教科書は学校に置いてあり、手元にありません。
#include <stdio.h>
void hoge(int *piyo)
int main()
{
int *piyo2,x;
int a[15];
piyo2=&x;
a=hoge(piyo2);
}
int hoge(int *piyo)
{ int i;
for(i=0;i<15;++i)
{
a[i]=a & B;
piyo=a[15];
return piyo;
}
間違いというか何がしたいのかわからない
320 :
デフォルトの名無しさん :2007/09/13(木) 02:03:17
>>318 まずだな、間違いを指摘して欲しいというまえに
何がしたいか書きなさい。
あんたのソースは間違い以前に、読めない。
ソースから何がしたいかなんてわかるわけない。
素直に、「僕ちん、こういう処理をするプログラムが書きたいの」
ていえ。
>>318 使用するプログラミング言語は何?
ごく普通のCでいいの?
回路設計に使うような表現をしているのが、とても気になるんだが…
322 :
hiro :2007/09/13(木) 02:25:29
>>320 ターゲットは回路設計で、仕様言語はCです。
したいことは
「1+x+x^15のシフトレジスタで構成される疑似ランダムデータを出力する関数を設計したい。main()から関数に
シフトレジスタ初期値とシフトする回数を引数で渡す。関数側ではシフトレジスタに
初期値を設定し、上記生成多項式をシフトする回数分だけ回して出力値をメインに渡す。
出力値は1ビットでよろしい(配列要素全てではありませんでした。すみません)」
以上が行いたい処理です。
323 :
デフォルトの名無しさん :2007/09/13(木) 02:44:43
画面に出力される文字をセンタリング表示させるには、 どうすれば良いでしょうか。 C++を使用しています。 まったくの初心者なので、わかりやすく教えて頂けるとありがたいです。 おねがいします。
コンソールなのか?ウィンドウなのか書いてもらわないと
#include <iostream> using namespace std; int main(int,char**) { cout << "<html><head><title>センタリング例</title></head><body><center>センタリング</center></body></html>" << endl; return 0; }
326 :
デフォルトの名無しさん :2007/09/13(木) 02:56:07
327 :
hiro :2007/09/13(木) 02:57:50
>>320 このような説明で解りましたでしょうか?Cの初心者で、どう設計したら良いか
解らずにおります。どうか、ご教示頂きたいと願います。
俺も知らんが。コンソールの場合conio.hを使うだろうと思い、 適当にヘッダに載ってた構造体と関数使ったらできた。 #include <iostream> #include <iomanip> #include <string> #include <conio.h> void print_text_centering(const std::string &str) { text_info ti; gettextinfo(&ti); std::cout << std::setw(ti.screenwidth / 2 + str.size() / 2) << str << '\n'; } int main(int argc, char* argv[]) { print_text_centering("ほげ"); return 0; }
330 :
デフォルトの名無しさん :2007/09/13(木) 03:08:23
>>323 です。
みなさんありがとうございます。
はい、コンソールです。
#include <stdio.h>
void main(void)
{
int cnt1 , cnt2 , n;
scanf("%d",&n);
for(cnt1=0;cnt1<n;cnt1++)
{
for(cnt2=1;cnt2<=n;cnt2++)
{
printf("*");
}
printf("\n");
}
}
例えは上のようなプログラム(正方形が表示されます)
の出力をセンタリングさせるにはどうすれば良いでしょうか?
全くの初心者ですみません…。
331 :
デフォルトの名無しさん :2007/09/13(木) 03:13:45
>>322 #include <stdio.h>
int func(int,size_t);
int main()
{
const int INIT = 1;
const size_t NUM = 10;
printf( "%d", func(INIT, NUM) & 0x01 );
}
int func(int init, size_t n)
{
int ret = init;
size_t i;
for (i = 0; i < n; ++i)
ret = ret^15 + ret + 1;
return ret;
}
よくわからんがこう?
A0 = INIT = 1でAn+1 = An^15 + An + 1のA15の値を返す関数func
mainではその戻り値の下1bitを標準出力に表示
333 :
hiro :2007/09/13(木) 03:46:12
>>332 流れとしてはそうです。せっかく作成して頂いた物ですが、関数本体の疑似ランダム生成回路が
>>301 さんのほうが近いように感じられます。ビットシフトがされていないからです。
せっかく教えて頂いたのに、無理を言って申し訳ありません。関数のfor文の中身はどれでしょうか?
見受けられませんが。
struct{ int x, y; }n, m; の様に無名構造体を多用するんですが、この場合は n 及び m のメモリ空間は全て 0 で埋まってる事は仕様上保証されてるんでしょうか? コードがかさばるのでデフォルトコンストラクタを書くのは嫌です。かといって後ろの方で n.x = n.y = m.x = m.y = 0; なんて埋めるのも面倒くさいし...
静的なオブジェクト:0で初期化 自動オブジェクト:初期化されない。不定。
0初期化なら素直に書いても大した量ではないかと struct{ int x, y, z; } n = {0}, m = {0};
>>333 それならこんなので@VC2005
#include <stdio.h>
void func(int* x, size_t size, size_t num) {
size_t i, j;
int bit;
for (i = 0; i < num; ++i) {
bit = x[0] ^ x[1]; /* xor */
for (j = 0; j < size - 1; ++j) /* shift */
x[j] = x[j+1];
x[size - 1] = bit;
}
}
void dec2bits(int dec, int* dest, size_t size) {
size_t i;
for (i = 0; i < size; ++i)
dest[i] = (dec & 1<<i) != 0;
}
int main() {
int x0 = 1234;
size_t n = 10;
int x[16] = {0};
dec2bits(x0, x, 16);
func(x, 16, n);
putchar('0' + x[0]); /* 最下位bitを出力 */
}
>>334 VIPから来ますた\(^o^)/マルチ氏ね
>全て 0 で埋まってる事は仕様上保証されてるんでしょうか?
基本的には保証されない。
/* for C
static int ZEROCLEAR_COUNTER_i;
#define ZEROCLEAR(ioClassZeroFill) for(ZEROCLEAR_COUNTER_i=sizeof(ioClassZeroFill)-1;ZEROCLEAR_COUNTER_i>=0;--ZEROCLEAR_COUNTER_i){*((char*)(&ioClassZeroFill))=0;}
*/
//template<class T> ZEROCLEAR(T &ioClassZeroFill){int i;for(i=sizeof(ioClassZeroFill);i>=0;--i){*((char*)(&x))=0;}}//forC++
struct{
int x, y;
} n, m; ZEROCLEAR(n);ZEROCLEAR(m);
イマイチだな・・・
339 :
デフォルトの名無しさん :2007/09/13(木) 13:25:59
TMediaPlayerを使ってmp3を再生しているのですが、 音量の調整の仕方が分からず困っています。 音量の調整方法が分かる方いたら教えてください。 お願いします。 環境 OS:Windows xp sp2 Borland C++Builder 6.0
音関係って書いたことないけど、ユーザとして思うに、音量調整って多段階だもんなあ ボリュームコントロール(sndvol32.exe)を眺めると示唆があるか
343 :
339 :2007/09/13(木) 14:02:04
>>340 >>341 >>342 返信ありがとうございます。
教えていただいた方法で、システムの方の音量ではなく、
TMediaPlayerの方の音量だけを変更する事はできるでしょうか?
初心者なので、意味不明な事を言っていたらすみません。
質問です。 ワトソン博士を使って、アプリケーションが落ちたときの状態のスナップショットを 取得させようと考えています。しかし、条件によっては、取得されないことがあります。 いろいろ調べたら、 ○ NULLポインタへの書き込み (構造化例外) × throw による、例外 (C++の例外?) だということがわかりました。 後者の場合もワトソンにわかる限りの状態を記録させたいのですが、これは不可能 なのでしょうか?
345 :
344 :2007/09/13(木) 14:35:42
環境を書き忘れました。 XP Pro SP2 VC8 SP1
>>343 TMediaPlayer のことは知らないけど、Windows Media Player のラッパのクラスなら、
ボリュームを制御することも可能と思う
ただし、TMediaPlayer について知らないので具体的にどうすればいいかは何もいえない
TMediaPlayerのヘルプを探すしかないと思う
それでダメなら、Media Playyer自身のインタフェースを取り出して自力で制御する必要があるかも知れない
Media Playyerの仕様は以下
Windows Media Player Object Model
http://msdn2.microsoft.com/en-us/library/bb249672.aspx
347 :
デフォルトの名無しさん :2007/09/13(木) 14:44:27
ヌルポや0除算はOSで制御される例外 スローはソフト的に処理される例外 後者はその開発ソフトがキャッチして例外だしてるから 言い方は変かも知れないけど、正常処理されている異常状態。 外部からは正常に見えるのでワトソンでは厳しいですよ。 ソースがないならVCについてくるスパイで監視か イベントログもチェックが正解。いずれににしよ期待薄。
深慮なく。
>>344 一番外にcatch(...){DebugBreak();}とでもしてみればどうかと
libcのバージョンによっては、invoke_watsonみたいな名前の内部関数が
マップファイルにあったけど、こんなときに使えるかどうかはよくワカラン
>> 344 >> 347 >> 348 ありがとうございます。ちょっとよくわから無いので、 少し調べてきます。
351 :
デフォルトの名無しさん :2007/09/13(木) 22:13:25
printf("%d %d %d~~~~~~~~~",a,b,c,,,,,,,,,,,,,,,,,,,,) ↑のように引数を変化できる関数の作り方オスエテー
printf("%d %d %d", a, b, c);を printf("%d %d %d")(a)(b)(c); みたいなのにするのがカレー化っていうんですか?
積年の疑問なんですけど、 const char * get_string() { return "hoge"; } int main() { std::cout << get_string(); // 必ず "hoge" が出力されるか return 0; } は問題ありますか?スタックに置かれた配列とかを返すのは問題だと言うことは分かりますが。
>>355 文字列リテラルの生存期間はstaticと同一なので何の問題もない。
つーか、マクロを使わないための常套手段だ。
カリー化じゃろ
359 :
デフォルトの名無しさん :2007/09/14(金) 00:33:01
C言語を習得するに良い問題集はどれでしょうか? 自分は参考書を読むよりも、実際に問題を解いて理解するタイプなので、問題集型を 希望します。カーニハン&リッチーは挫折しました。
366 :
デフォルトの名無しさん :2007/09/14(金) 00:58:08
makeとかでコンパイルするときには コンソールやシェル上に実際にコンパイルするコマンドがズラ〜っと出てくると思うのですが あれってコマンドライン上からは出るように設定できないんですか?
ちょっと日本語でおk てか、何をどうしたいのかで聞いてもらった方が とりま、make/nmakeにはいっぱいコマンドラインオプションがあるけど
makeしたときに走ってるコンパイル/リンクコマンド群を、 ターミナル上に自分の手で走らせたいとか?
コマンドライン上で make とかでコンパイルしてるってことは、 ズラ〜っと出てるんじゃないの? え?
要するにmakeで自動化せずに手作業で一つずつコンパイルしたいって事かもね。
取り敢えずmake -nしてみればいいんじゃね?
「出ないように設定できないのですか」 というのであれば、nulにリダイレクトすればいいと思う。
int hoge(); hoge | piyo( _1 == 0, std::cout << "hagehage" << '\n ); でhogeの戻り値が0のときにpiyoの第二引数に指定した匿名関数を実行する みたいにoperator|とpiyoのクラスを実装したいんですがなんかいい方法ありますか? さらに int hogehoge(int i){ return i | piyo( _1 > 0, hoge(--_1) ); } のような使いかたもできるようにしたいです
>>373 Boost.Lambdaでやってみたが、ラムダファンクタにresult_ofが使えないようで、
operator |に戻り値を持たせられなかった。もちろん型を決め打ちするのは可能。
#include <iostream>
#include <boost/lambda/lambda.hpp>
template<typename Pred, typename Functor>
class impl_piyo {
public:
impl_piyo(Pred p, Functor then) : p(p), then(then) {}
impl_piyo(const impl_piyo& y) : p(y.p), then(y.then) {}
impl_piyo& operator =(const impl_piyo& y) {p = y.p; then = y.then;}
template<typename Pred, typename Functor>
friend void operator |(int x, const impl_piyo<Pred, Functor>& y);
private:
Pred p;
Functor then;
};
template<typename Pred, typename Functor>
void operator |(int x, const impl_piyo<Pred, Functor>& y) {if (y.p(x)) y.then(x);}
template<typename Pred, typename Functor>
impl_piyo<Pred, Functor> piyo(Pred p, Functor then) {
return impl_piyo<Pred, Functor>(p, then);
}
int main() {
using boost::lambda::_1; using boost::lambda::constant;
int hoge; std::cin >> hoge;
hoge | piyo(_1 == 0, std::cout << constant("hagehage") << constant('\n'));
}
>>374 なるほど
piyo()で別のオブジェクトを生成してやって、それに対して|を特殊化してやればいいんですね
ラムダファンクタの問題に関しては、result_ofをこれに対して特殊化してやればできるらしいです
とここまではできましたが、Predを満さない場合の戻り値に対して以降のoperator |を実行しないようにする方法はまだできてません
提示されたコードを元にもう少し実験してみます、どうもありがとうございました。
|をショートサーキットにするのは不可能だろ
歌声のパルス受け止めて 羽ばたく準備はOK?(HEY!HEY!HEY!HEY!) 僕ら革命も起こせるさ 電撃Chu Chu Chuビームで!
378 :
デフォルトの名無しさん :2007/09/15(土) 01:21:03
まずそのファイルが存在するかどうかを確認するべきだな
無ければ作ればいいじゃないか
あ、空のフォルダじゃなくて中身のあるファイルを作れって意味ね
>>380 documentation じゃなくて download から取ってくるんだよ。きっと。
>>380 Downloadからアーカイブを落としてみたら、中にちゃんとinclude/vecmath/Exportが入ってたよ。
中味が空っぽのファイルも作ってみました。 そうするとその部分のコンパイルエラーは取れますが、別のところでエラーが残ってしまいます。 エラーメッセージは以下のとおりです。 ...\vecmath\_tuple3.h(31) : error C2146: 構文エラー : ';' が、識別子 '_Tuple3' の前に必要です。 ...\vecmath\_tuple3.h(31) : error C2470: '_Tuple3' : 関数定義のようですが、パラメータ リストがありません。外見上の本体をスキップします。 ...\vecmath\_tuple4.h(25) : fatal error C1903: 直前のエラーを修復できません。コンパイルを中止します。 対応する、ソースコードは以下の一行です。 template <class Type> class VECMATH_EXPORT _Tuple3 { templateとか意味不明です。 何ですか?
……
>>385 寝たら? そうだな、100年くらい。
>>384 ありがとうございます。
解決しました。
>>386 そうですね。
以後気をつけます。
>>387 うるせー
糞蛆虫、一刻も早く死ね。
迅速にな。
人に迷惑かけるなよ。
やれやれだぜ。
391 :
383 :2007/09/15(土) 01:58:49
いいんだ。別に。
393 :
デフォルトの名無しさん :2007/09/15(土) 02:02:59
>>389 うるせー
糞蛆虫、一刻も早く死ね。
迅速にな。
人に迷惑かけるなよ。
394 :
デフォルトの名無しさん :2007/09/15(土) 07:50:25
>>377 蟻のレポート提出がまだ済んでいないぞ。
すまん、無料のBCCコンパイラってダウンロード出来なくなってるんだが まだ拾える場所知らないか?
>>395 そうなのか?
じゃあ付録についてる本を買え
それかLinuxにしろ
>>397 すまん、一番下の
「無償版のダウンロードサービスは終了しています。」
を読んで諦めてたわ
>>399 すまん、帰るわ
叩きたいだけの奴なんか相手にすんなよw
自演乙 アホが来ると非常に迷惑です。
403 :
デフォルトの名無しさん :2007/09/15(土) 10:20:12
ちょい質問です .hでクラスの定義して.cppでメンバ関数の定義したのをdllにしたいんだけど、どうextern宣言したら良いのかわからないんですが、解決策はないですか?又は基本的にメンバ関数はdllから呼び出せないとか?
C++って超怒級マクロなの?
406 :
デフォルトの名無しさん :2007/09/15(土) 12:26:16
STLのクラスの中身を見たいのですが見方教えてください
>質問者は必ず環境を書きましょう。
>>406 #include <string>
などとしてプリコンパイルだけしてみる。
410 :
デフォルトの名無しさん :2007/09/15(土) 18:06:20
Microsoft Visual C++ .NET 使ってるんだが、DebugとReleaseで挙動が違ってびっくりなんだ。 Releaseで出力して、なんか変な動きするから、しばらくバグかと原因をあさったけど見つからない。 その後Debugでデバッグしてみようと思ったら意図したとおりの挙動・・・。 ソースはちょっとでか過ぎるから上げられないけどこれって普通に起こることなの?
変数を初期化し忘れているとか 変数を初期化し忘れているとか 変数を初期化し忘れているとか の場合によくおきる
それはだいたい変数が初期化できていないことが原因になってる
↑被っちまったぜ
415 :
デフォルトの名無しさん :2007/09/15(土) 18:31:25
あれ、ちょっと思ったんだけどそれって変数を初期化し忘れててもDebugだと動くってことに? DebugとReleaseってどうちがうんだろ
オーバーフローとかもReleaseビルドで発症することあるな。
>>415 DebugとReleaseの違いは色々違いすぎて俺には上手く説明出来んけど、
とりあえずコンパイラ/リンカのオプションとリンクしてるライブラリが違う。
それはオーバーランじゃね?
どうやら基本ランタイムチェックって項目のスタッフ フレーム (/RTCs)を入れると普通に動くらしい。 この項目ってなんですかね?さっきから質問ばっかですまん(´・ω・`)
>>410 Releaseでもデバッグできるよ。
デフォルトでは、ステップ実行がアレになったり
エディトコンティニューができなかったりして、
Debugほど自由自在ではないが。
>>415 Debug だと初期化してない変数の値を 0xCC(半角フ)で埋める。
これはデバッグしやすくするためにそうするんだが、逆に悪さをすることもある。
NULL かどうかチェックして、NULL じゃねえやって判定されても、
有効なアドレスが入ってるとは限らんからな。
>>422 そしてNULLが0云々の議論に発展だな
425 :
デフォルトの名無しさん :2007/09/15(土) 19:51:51
問題の原因が分かりました
お察しの通り初期値の問題でした
皆ありがとう!
>>420 次回からはヘルプ見て分かるところは自己解決できるようにがんばりやす
426 :
デフォルトの名無しさん :2007/09/15(土) 20:46:56
wchar * 型からstring型に変換するにはどうしたらいいでしょうか リテラルからの変換はLをつければできそうですけども 変数で変換をしたい
wstringでなくstringへと?
>リテラルからの変換はLをつければできそうですけども って言ってる時点で、string じゃなくて wstring だと思うんだが… 本当に string めんどいぞ?ってか違い分かってる?
昔書いたソースをみたところ、char型にならこうやってた #include <clocale> // wchar_t*型をchar*型に変換 std::setlocale(LC_ALL, ""); std::sprintf(代入先(char*), "%ls", (wcharの文字列));
mbstowcsでいいよ。 wchar_t const* pws = L"hoge"; std::size_t const srcLen = std::wcslen(pws); std::vector<char> buf(srcLen * MB_LEN_MAX); std::size_t dstLen = std::wcstombs(&buf[0], pws, buf.size()); std::string s(buf.begin(), buf.begin() + srcLen);
432 :
デフォルトの名無しさん :2007/09/15(土) 21:58:52
std::vectort ってすげぇー! newでのdelete忘れも解消、動的確保もラクラク new&deleteいらねーぜ
つ boost::vector_ptr<T> ん?単なる動的配列の話か。
std::vector(というかコンテナ全て)使うときはbad_allocをcatchしないといけないよね?
C++ってCと比較すると格段に難しくね?
>>434 よくわからんがallocator<>が失敗するとかか?
ほとんど無いとは思うがnewもbado_alloc投げる
>>435 暗黙の処理とかが多いからかな
初期化と代入の違いを意識するとか面倒くさい
けど、そこが興味深くもある
Cに慣れてからC++やると参照が無意味のように思えるからじゃね?
逆じゃね。 むしろCやってポインタの危険性を理解しているからこそ 参照を適切に利用出来るのだと思う。
まぁC++のが格段に高機能だからなぁ。
Cってまだまだバージョンアップするだろうけど、クラスが使えるようにはならないの?
素直にC++使えと
C99がメジャーになったらバージョンアップするかもしれないし、しないかもしれない
ポインタについて理解できない
ポインタ=アドレスでいいやと思った
C++でint型を継承したクラスを作ることってできないのですか?
出来ないが、operator int()は可能
ポインタ=間接的にオブジェクト実体を参照するための変数 レファレンス=直接オブジェクト実体を参照するための変数
はずれ
>>450 リファレンス=参照を説明するのに参照ということばを使ってどうする
リファレンスの実装はほぼポインタだが、参照はあくまでもオブジェクトの
別名だろ
ポインタ渡しを隠蔽したものじゃないの?
ext2 とか ext3 のファイルシステムで例えると
ポインタ→シンボリックリンク
参照→ハードリンク
の違いみたいなものってこと?
ttp://... みたいな URL はポインタだね
いいえ
Ye Yeah!
いぇ いぇぁ
>>454 ポインタそのものを操作できることを忘れてる
答え 手間の要る実体アクセス:ポインタ 手間不要の実体アクセス:リファレンス
>>459 「ポインタ」と「リファレンス」を調べてみるといいよ。
こういうプログラミング概念は、
他の言語でも使われているので、
理解しておいても損はない。
手間にもいろいろあるだろ
リファレンス == プログラマの底なしの最適化に対する欲によって作られたinline functionの引数の為だけに生まれたconst type&が引きずるジレンマ
>>460 理解しようと努力して幾年も過ぎてしまった....今でもポインタ、リファレンスの区別すらできぬ
その俺様が、得た答えが
>>459 だ。
リファレンスって operatorを実現するために導入されたんだろ、違うのか?
>>463 >operatorを実現するために導入
さすがにそれは違う
参照=エイリアシング ポインタ=反復子
>>465 の
ポインタ=反復子 は正しいな
でも
参照=カモフラージュ じゃないか
>>464 ところがD&Eにはそう書いてあるんだ。
値渡しは効率悪いし、ポインタ渡しは([]、+、-など)演算子多重定義できないし
というわけでリファレンスを導入することにしたとな。
手間をdereferenceするときに*演算子が必要という意味で使っているのなら、
ポインタとリファレンスの大まかな違いは459の理解でいいと俺は思う。
ポインタには演算ができる *、++等 リファレンス演算というものはない あくまでも別名に過ぎない
for(int i = 0 ; i < 10 ; i++) { CSome s; GetSome(&s); if(s.id == i) }
すいません、途中で書き込んでしまいました。。 for(int i = 0 ; i < 10 ; i++) { CSome s; GetSome(i, &s); if(s.id == i) { break; } } みたいな処理をしたいのですが、この場合、CSome sは毎回Construct・Destructされるでしょうか?
される
>>471 されるんじゃね?
{ }スコープに出たり入ったりで
コンパイラの最適化でforの外に出される場合がある
>>472-474 さん、ありがとうございます
forの外に出されると怖いので、{}でくくることにしますた
>>474 最適化はロジックが変更されないことが前提
単純な整数型や実数型の演算ならループ外に共通処理を出すのは普通だが、
オブジェクトの場合は複数のオブジェクトを集約すると意味が変わって
しまうため、通常そのような最適化はなされないはず
477 :
デフォルトの名無しさん :2007/09/16(日) 18:34:16
`con'struct, `de'struct この`con'と`deってなに?'
>>477 単語の途中で切っちゃダメだ
でも接頭辞 con- とか de- とか re- un- im- とかって
習わなかったっけ?
#include<stdio.h> #include<string.h> char *search(char *s,char *p){ char *x; int i; x=p; i=strlen(p); while(1){ p=x; if(*s=='\0')return (char*)0; for(;*s==*p;s++,p++){ if(*s=='\0')return (char*)0; if(*p=='\0')break; } if(*p=='\0')return s-i; s++; } } int main(){ char *x; x=search("international","nat"); printf("%s",x); return 0; } これで結果が「national」になるようにしたいんですが "international"を"internanational"にすると1文字ずれてNULLが戻ります。 改善点を教えて下さい よろしくです
char*型の変数名がxって初めて見たwww
>>480 > for(;*s==*p;s++,p++){
この部分がマズイ
1.新しい変数(char*型)を二つ用意して…後は考えろ
2.比較する時に strlen で得た長さを利用して…後は考えろ
1.か2.のいずれかの方法で改善するだろう
あとは
search("international","ional");
の返り値はどうなるかやってみた?
> for(;*s==*p;s++,p++){ > if(*s=='\0')return (char*)0; > if(*p=='\0')break; > } ここで進めたsを復元する必要がある
訂正 search("international","onal"); だった
>>481 char *xって使わないんですね・・・
失礼しました
>>482 ありがとうございます
考え直してみます
>>483 ありがとうございます
>>480 naが一回一致するのでその時にズレると予想した。未確認だが、、
あと第一引数が"nat"で終わるパターンも試した方が良さそうだ。
if(*s=='\0') return (char *)0;
の行が気になる。
あと、アドバイス。
引数はいずれもconst char * にした方が良い。
文字列自体は書き換えないでしょ。
>>485 >char *xって使わないんですね・・・
自由だけどxって16進数の値を入れたり、xyzの1つとして数値を入れる人が多いと思う。
自分ならこう書く。 char *search(const char *str, const char *key) { while (*str != '\0') { const char *s = str; const char *k = key; while (*s == *k) { ++s, ++k; // while (*s++ == *k++) if (*k == '\0') return str; if (*s == '\0') return NULL; } ++str; } return NULL; }
誰ならこう書くという話なら、俺ならstrstrを使う。
プログラミングって面白いね!
どうして?
>>480 #include <iostream>
#include <string>
std::string search(const std::string& target, const std::string& str) {
if(target.find(str) != std::string::npos) {
return target.substr(target.find(str));
} else {
return ""; // or assert or exception
}
}
int main() {
std::cerr << search("international", "nat") << std::endl;
std::cerr << search("international", "onal") << std::endl;
std::cerr << search("international", "not found") << std::endl;
}
時と場合によりそうな質問で申し訳ないんですが 基本クラスのメンバ変数を 1:protectedにして派生クラスのメンバ関数でアクセスすべきなのか 2:privateにして派生クラスのメンバ関数から基本クラスのメンバ関数を介してアクセスすべきなのか 2-a:派生クラスのメンバ変数を引数として基本クラスのメンバ関数に渡す(関数の本質的な処理は基本クラスのメンバ関数で行う) 2-b:派生クラスの関数内で基本クラスのゲッタ関数で取ってきて派生関数内で本質的な処理をする 迷うところが多数あるのですが、これはどっちでやるのが基本なのでしょうか? 派生クラスのメンバ変数も基本クラスのメンバ変数も使う処理なので、 基本クラスのメンバ関数だけというのは無理という前提でお願いします
>>494 抽象的な質問には抽象的な回答しかできない。具体的に困っているケースが
あるならそれを書いたほうがいいよ。
ケースバイケースだと思うが 基底クラスに変数を持たせてるなら 本質的な処理?も基底クラスで行うだろう。 あと、俺なら変数の入出力が激しいならprotectedにする。
>>494 少なくとも1.は避けたほうがいい。
派生は誰にでも可能で、protectedメンバ変数は事実上writable by worldだ。
つまり保護されていないも同然だ。
publicにしたくないデータなら、privateにすべき。
やっぱりC覚えた後はC++に行くべきなのでしょうか・・・
JAVAでもVBでも好きなように。
>>501 時代に取り残されるとCOBOL技術者みたいな末路が待っているかもよ
>>500 それならprivateメンバ変数も基本クラスのpublicメンバ関数を用いて変更可能だったら
事実上writable by worldってことではないの?
>>504 publicメンバ関数がprivate メンバ変数の参照を返すようだと無意味だが、
ちゃんとルールに沿った形でしか変更出来ないって意味だろ。
結論 ケースバイケース
>>504 「何でカプセル化なんてするの?」ってのと同質の質問だなw
インターフェースと実装を明確にすれば自ずと分かる 自分で人に使ってもらうライブラリでも書いてみればわかる
C++で、プロパティみたいに自由に参照できる変数を定義すると 怒る人が多いんだけど、なんで?
カプセル化をぶち壊してどうする 参照も基本的に使用は最小限
今、書いてるソースを見たらクラスが3つあって全部でメンバ関数が23個あったんですが、 そのうち21個の関数の引数がなし(void)だったんですが これっておかしいですか? 関数内ではほとんどメンバ変数をいじったりしてるのですが
>>511 エスパーじゃないので、なんともいえない
>>511 熟考した結果そうなったんだろ?
別にいいじゃないか
常識に囚われるな
>>511 クラスに対しての操作をそうする事で必要分隠蔽できているのなら、それでいいんじゃないかな
voidである事よりも 23個もメンバ関数を持ったクラスの方が気になるが 基盤となるクラス作ってたらその位になるのかな
516 :
511 :2007/09/17(月) 13:23:14
ありがとうございます
とりあえず思ったとおりの動作になってくれているのでこのまま行こうと思います
>>515 クラス3つで合計23個です
でもまだまだ増えそうですが・・・
>>510 それを実現するためにoperatorがあるんじゃないの?
これならシームレスにカプセル化できるっしょ?
見落としてた。スマソ(´・ω・`) 基本的に閉鎖的の方が良いから 上手く機能しているなら全然おkだね
正常に動作してるものを弄ってはならない とか言われてるんだけど、これってリファクタリング全否定なんでしょうか?
>>519 いいな。今でもCOBOL技術者ってひっぱりだこだろ。
COBOL 技術者は売り手市場だな
>>520 採用している開発手法によるな。ウォーターフォール型では一度完成して
検証済みのものに手を入れるのは御法度。まあ、リファクタリングを導入
するなら、上層部の意識改革+強力なリーダーシップ+開発者へのユニット
テスト文化の浸透が不可欠だね。そんなに簡単なことじゃないよ。
>>523 上層部の意識改革+強力なリーダーシップ
日本ではここが一番難しい
米より15年遅れてるソフト業界と言われる所以
>>516 俺が書いたクラスで一番メンバ関数が多いのは、趣味で作ってる俺Lispの基底型SExpressionで、
いま数えたら、メンバ関数が54個、そのうち24個が引数無しだった。
STLのbasic_stringなんて100超えてるぜ!!
>>528 めず
むかしむかし、ある地獄にとても仲のいい二人組がいました。
その子達は名前をゴズとメズといい、
ゴズは山へ金儲けに、メズは川へ珪砂狩りに行きました。
bcc使ってるのでgetter/setterは__property使って見かけ上はメンバ変数になってます><
>>521-522 そんなに需要があるの?
何故?
うちの親が作ったのは
鶏の卵の市場予想プログラムと計算機ぐらい
大学生のときに作ったものばっかで
今は何もやってないわ
ちなみに、大学は武蔵工業大学らしいわ
>>532 修正
大学かどうかは分からんが
かなり何もやってないことは確か
大学の頃はカードだったみたいだし
まぁどうでもいいな
COBOL システムの寿命>COBOL プログラマの技術者としての寿命
>>532 COBOLは時代遅れの言語と見られてて
若い人がやりたがらないから。
>>532 コボルは今の若い衆には受けが悪いだろ。
時代遅れの仕様に需要もいつまで続くかも分からないし。
だから技術者の数が少ない。反面一定の需要は根強く続いている。
だから相対的に技術者の需要がある。
class D : public B{ ... }; class D d; class B b = d; これでBの要素だけコピーできたのですが、 このコピーコンストラクタを自動で作ってくれるのって言語の仕様ですか? それともコンパイラ依存ですか?
デフォルトコンストラクタを生成してくれるのは言語仕様。
コピーコンストラクタを自動で作ってくれるのも仕様
>>538 へー、すごい気が利くんだね、すごいや。
コピー代入演算子を自動で作ってしまうのも言語仕様
気が利くっつーか、余計なお世話。 わざわざ使えなくしなきゃいけないことも多いし。
ストラテジパターンを使って主要な処理をストラテジに委譲しようとしているんだが 処理に必要なメンバ変数はストラテジ基底クラスをfriend指定して ストラテジ基底クラスからprotectedでgetterを作って 実装部に当たる派生クラスに限定公開している。んで、思いの外getterの数が多くなったから いっそストラテジ派生クラスを全てfriend指定しようかとも検討しているんだが どっちの方が良いかな。始めからクラスのメンバに全てgetterを付ける、と言う手もあるけど。 やっぱりこの辺は好みの問題?
簡単に書くと class Enemy { public: action(){ m_pstrategy->action() } private: int m_hp; float m_speed; float m_direction; friend class EnemyStrategy; EnemyStrategy* m_pstrategy; }; class EnemyStrategy { public: virtual void action()=0; private: Enemy* enemy; protected: int getHP(){ return enemy->m_hp; } float getSpeed(){ return enemy->m_speed; } }; みたいな感じになってる。規模はもうちっと大きいけどね。 あくまでみたいな、だから↑のコードの意図したとこ以外のツッコミは無しの方向で・・・
>>546 Enemy から頻繁にアクセスされる属性を抜き出して EnemyParameter
クラスを作り、EnemyStrategy.action(EnemyParameter&) とする。
EnemyParameter には public な getter を用意し、Enemy の private
メンバとする。俺ならこの場面で friend と protected は使わない。
548 :
544 :2007/09/17(月) 19:34:09
一つに纏める事も考えていたが・・・ふむ、ちゃんと考えてみようかな 死亡権限や影響権限等を少々凝った形で持たせてるがなんとかなる範囲だし 回答d
ポインタが理解できれば 天国にいけますか?
>>549 天国へはいけまへん。理解出来なければ地獄堕ち。
>>549 ポインタ程度理解できようができまいが、
あなたは地獄行きが決定しています。
ポインタが理解できない → プログラマ失格となり他の業務をやることに → その業務で優れた成績を残し昇格 → 天国へ ポインタが理解できる → プログラマの能力を認められる → ひたすらプログラムを作り続ける → 終
ポインタが理解できない。→プログラマ失格となり他の業務をやることに。 →その管理職になり「腐れ上司」のレッテルを貼られる。 →憎まれながらも(気付かないので)幸せな人生を送る→天国へ ....あれ?
優れた成績を残せる訳も無いが
>>553 は普通によくあることなんだろうなぁ・・・
ポインタ程度の壁で行き詰ってるようじゃその先の壁なんて越えられるかどうか
壁で向こう側が見えないのさ
557 :
デフォルトの名無しさん :2007/09/18(火) 08:08:05
クラス内でprivateに他のクラスを使いたいのですが、 そのときは以下のようにすればよいのですか? クラスAの中でクラスBを使う class A { B *b; public: A() { bの初期化 } }; もしこのように書けば良いとすると、bの初期化をどうやって 書けばよいかが分りません。 どうか教えてください。
___ ━┓ / ―\ ┏┛ /ノ (●)\ ・ . | (●) ⌒)\ . | (__ノ ̄ | \ / \ _ノ /´ `\ | | | |
560 :
557 :2007/09/18(火) 09:10:35
返答ありがとう。 あるクラスのなかにインナークラスのインスタンスを保持したいのと、 そのインナークラスのコンストラクタに自由に引数をわたしたいのです。 インナークラスへ引数をわたさなくてよいなら、たんにクラス内でクラスを 宣言すればできましたが、そうじゃないばあいができなかったです。
>>557 を見て、インナークラスをやりたいとわかるのはすごいな。
日本語もコードも、どう見ても単なる外部クラスの集約だよなあ。
564 :
デフォルトの名無しさん :2007/09/18(火) 13:36:19
クラスAのメンバに他のクラスBとかクラスCのポインタを持たせるときに BとかCのヘッダをインクルードしてるのにもかかわらず、 Cだけはさらに前方宣言しなきゃいけなくて、 Bはなぜかしなくてもいい場合とかがあります。 そのしなきゃいけない場合としなくてもいい場合のルールがさっぱり分からないんですが、 一体どういうことなんでしょうか? いつも、メンバにもたせた瞬間に山の様なコンパイルエラーがでたら、 理由は分からないけど前方宣言してみたら消えるかな とか思ってなんとか適当に対処してきたんですが。
良エスパーアラワル!
相互にインクルードしてる場合、そうなりうる。 -- a.h -- #ifndef a_h #define a_h #include "b.h" class A { B *b; ...... }; #endif -- b.h -- #ifndef b_h #define b_h #include "a.h" class B { A *a; ...... }; #endif -- x.c -- #include "a.h" ↓展開すると #define a_h #define b_h class B { A *a; ...... }; // Aが未定義 class A { B *b; ...... };
567 :
デフォルトの名無しさん :2007/09/18(火) 14:02:25
>>566 そういう単純な循環なら分かるんですが、
そうでもないっぽいんです。
もうすこし複雑で同じ問題が起きる状況ってありえますか。
初心者には気づきにくいけど遠まわしに同じようなことがおきてる、
っていうような。
そりゃ、どこかでヘッダが循環してれば、同じことは起きうる。 解決策のひとつとしては、ヘッダから別のヘッダをインクルードするのを極力やめるとか。 例えば A へのポインタを持つだけの場合、A の定義は必要ないから、a.h をインクルードせずに #ifndef b_h #define b_h class A; class B { A *a; ...... }; #endif だけにする。同様に a.h の方も #ifndef a_h #define a_h class B; class A { B *b; ...... }; #endif だけにする。すべてのヘッダをそのようにする。 継承してる場合や実体を含んでる場合やtypedefやマクロやなんやらを参照する場合は必要だから、 そのとき *だけ* ヘッダから別のヘッダをインクルードしても良いことにすれば、そういう問題はあまり起きなくなるんじゃないかな。
書いてから、これ 「常に前方宣言しろ」 って言ってるのに等しい気がした。 まぁ結局、常に前方宣言するか、インクルードの循環に神経尖らすか、エラーが起きるごとに対処するか、くらいしかないのでは。 あと↓みたいな案もあるけど、あんまり見ないような気がする。 #ifndef a_h #define a_h class A; #include "b.h" class A { B *b; ...... }; #endif #ifndef b_h #define b_h class B; #include "a.h" class B { A *a; ...... }; #endif
改行変になったorz
572 :
デフォルトの名無しさん :2007/09/18(火) 14:54:00
>>569 今までクラスAのメンバに
クラスBへのポインタを持たせるために、
Aのヘッダに
Bのヘッダをインクルードしてましたが、
助言に従いBの前方宣言だけにしてみました。
が、A.cppの方で
Bへのポインタのメンバ変数を使おうとしたら
「認識できない型がB使われています」
と怒られました・・・なぜでしょうか。
573 :
572 :2007/09/18(火) 15:09:28
すまそ。継承してました。
VSEEって2008であっても無償なの?
577 :
デフォルトの名無しさん :2007/09/18(火) 15:27:45
インクルードしたヘッダのなかでインクルードしたヘッダのなかで・・・ みたいに遠くで使われてたりするとわけわからなくなってきて 発狂しそうになります。
#include "test.h" if( test() ){ retrun; } 上記のプログラムを#defineでtestの部分を引数にしてマクロ化したいのですが #includeを#define内に組み込むことは可能でしょうか?
コンパイラによると思うがまず不可能じゃね?
やっぱり無理ですか、諦めて別の方法を考えます
582 :
デフォルトの名無しさん :2007/09/18(火) 19:16:01
#defineと constでグローバル変数を宣言して値を代入するのって いったい何が違うの? (´・ω・`)
>>582 があほ過ぎということと
俺達が普通ということ
584 :
デフォルトの名無しさん :2007/09/18(火) 19:31:23
#define はコンパイル時に置き換えられるだけで const は変数っていうか定数かを宣言するから メモリにその実体が存在することになる。 っていうのが初心者的理解です。 間違ってたらすみません
#defineはただの痴漢
>>584 最適化次第では色々起きるので、constな変数が必ず変数として実態を持つかは微妙。
「#define」はCプリプロセッサが処理する。
「const」な変数はCコンパイラが処理する。
constの挙動はCとC++で違うのに、 なんで誰も問いたださないんだ?
>>582 はそれ以前のところから始める段階だ、と踏んだからだろう。
プリプロセッサの領分とコンパイラの領分を理解したら、次は君のいうディテールの話になるけれど、
まずは第一段階が大事かと。
え?今何してるかって? プリプリプリプリプリプリプロセスだよ 同僚はブリブリブリブリブリブリブリブリブリブリブロセスしてるよ
>>582 const変数に値を代入することはできません(C99/C++)。
const変数は仮令グローバルでも実体を持たない場合があります(C++)。
static const変数は実体を持たない場合があります(C89/C99/C++)。
Cプログラマって 普通の人より彼女ができ安かったり セクロスしまくりなんですか?
当たり前じゃん。毎日ウィンウィン言いながら叩きつけてるよ
594 :
デフォルトの名無しさん :2007/09/18(火) 22:20:16
#include <stdio.h> int hoge(void); int main (void){ quit; return 0; } int hoge(void){ printf("hogehoge¥n"); return 0; } とやってもhogehogeと表示されません どうしてでしょうか?
関数を呼び出してないから
余計なお世話かもしれないけど、 バックスラッシュ (U+5C)ではなく、本当に円記号 (U+A5)なのが気になる。
わろた
呼び出さないのは反則すぎるだろう…
誰も quit って何だよとは突っ込まないのな。
遠回しに為されてる。
もしかしたらquitで任意アドレスをコールできるのかもしれないぞ
これは罠ね
603 :
デフォルトの名無しさん :2007/09/18(火) 23:02:44
メインと括弧の間のスペースはとかいってみる
確かに hoge の後ろにはないのに main の後ろにはなぜかあるな。
コピペなんだろ
そもそもコンパイルできないんじゃ
きっとコンパイルオプションで#define quit hoge()のようなものが与えられているのだろう。
なかなかカオスな展開に
クラスの隠蔽化(カプセル化)にはどういう利点があるのでしょうか。 市販のライブラリであれば利用者に中身が見られないようにする、 個人ではプログラムがすっきりして見やすくなったり拡張しやすくなる ぐらいしか思い浮かばないのですが。
きっとこんな風に起動しているのだろう。 hoge.exe > NUL
612 :
デフォルトの名無しさん :2007/09/19(水) 00:39:51
言語:C++ 環境:VC6.0 ADOXを用いてACCESS(MDB)のフィールドの設定方法を教えていただきたいです。 具体的には、フィールドの既定値・UNICODE圧縮・空白の許可の3つの要素です。 propertyを取得することはできたのですが、更新方法がわかりません。 ご教授願います。
>>612 Accessのヘルプからオブジェクトモデルのマニュアルを見つけ出せ!
614 :
デフォルトの名無しさん :2007/09/19(水) 00:55:44
>>609 すっきりしてないごちゃごちゃで見にくいソースをメンテしたいなら別にしなくていいんじゃない
メンバ変数にポインタを持ったクラスで、 そのポインタ値をコンストラクタで要求するように設計したいのですが、 そのときに不正な値が送られて来ないかチェックする方法ってありますか? やはりリファレンスを持たせるべき?
普通にチェックすれば? class Foo{ Bar *bar; public: Foo(Bar *bar); }; Foo::Foo(Bar *bar) { if (bar == NULL) { throw std::invalid_argument(); } this->bar = bar; }
>>616 コンストラクタでゴニョゴニョするのは気持ち悪いので、
ファクトリメソッドを用意してみては。
class Foo {
// 略
public:
Foo(Bar *bar) : _bar(bar) {}
Foo *create(Bar *bar) {
return bar ? new Foo(bar) : NULL;
}
}
>>616 ぬるぽかどうかをチェックするだけなら簡単だが、それでいいのか?
まず本当にそんなことが必要かどうか、考えたほうがいい
リファレンスを受け取って、アドレスを取ってポインタを保持するという
方法もあるでよ
>>609 プログラムのバグってのは大抵は状態=データを何か不正なものにしてしまうこと
によって起きるので、データを触る人が少なければ少ないほど
訳の分からないバグは起きにくくなるし、バグが出た場合も問題を
局所化しやすくなるよ
まあCやC++のような言語では、言語レベルでのクラスの保護なんぞ容易に
破られ壊されることがあるが、それは仕方が無い
#define private public
#define private __declspec(dllexport)
Cで ・fopen ・ファイルへの書き込み ・fclose ・system(外部プログラム呼び出し) ・結果を保存 という作業をループで何千回〜数万回処理するプログラムを作ってるんですが、途中から "Too many open files"というエラーが出てきてファイルへの書き込みが出来なくなります fcloseで閉じてるのに開きすぎとはこれ如何に それとも、そういう意味のエラーじゃないんですかね?
正しくfcloseできてないに1票
626 :
デフォルトの名無しさん :2007/09/20(木) 02:05:32
ファイルが閉じられるまでSleep入れとけばOK
sleepかよ
結果を保存ってのがどういうことなのかわからないし そのエラーが出るのが繰り返しの20回目くらいなのか250回目くらいなのか それとも数千回までは大丈夫なのかによっても原因が変わってくるかもしれないし。
ファイル書き込みが遅延してるんじゃね? OSとか詳しくないから予測だけど。 開けなかったらしばらく待って、再試行。長時間だめならタイムアウトエラー吐き出しでいいんじゃね? closeきちっとしてればだけど。
最初は1ms sleepしておいて、次に試行して失敗したら2ms、次が4ms、8ms、16ms、32ms、64 128 256 512 1024 ...
システム見直せの一言で片づけたいなw
633 :
デフォルトの名無しさん :2007/09/20(木) 03:16:50
windows APIなら5000くらいは同時にオープンできる ファイル閉じるのを待つため次のようにやっている fp.open("file" , ios::out ); fp.close(); while(fp.fail())Sleep(100);
vipper.orgが今現在ハッキングかまされてるな あの程度の練度までいくのに何年掛かるかな
634みたいな釣られやすいバカがいれば1秒
エイプリルフールでもないのに管理人の悪ふざけとも思えないんだが .netもあの調子だし
637 :
デフォルトの名無しさん :2007/09/20(木) 11:41:51
http://ja.wikipedia.org/wiki/Strcat 「バッファオーバーラン」の項目なんですけど、
strncat(s, ".exe", sizeof(s) / sizeof(char) - strlen(s));
じゃなくて
strncat(s, ".exe", sizeof(s) / sizeof(char) - strlen(s) - 1);
の間違いですよね?
(sizeof(char)は環境によらず常に1だろってのはともかく)
そうだね。修正よろしく。
CONFIG.SYSのFILES=の数字に左右される
20ぐらいでおk
641 :
967 :2007/09/20(木) 12:55:44
質問があるのですが、ユーザ入力で半角英数字以外受けつけなくしていんです。 単体テストをしたいんですが、どうしたらいいでしょうか。 整数だけの判定ならできます。
>>637 どうせ直すなら、ついでにおかしな日本語も訂正しておいてくれ。
>バッファオーバーランを防ぐ最も最適な方法は、字数制限付き文字列連結関数であるstrncatを使うことがある。
「最も最適」とか「方法は〜ことがある」とか。
--
バッファオーバーランを防ぐ方法の一つとして、字数制限付き文字列連結関数であるstrncatを使う例を挙げる。
--
こんな感じでいい気もするけどね。
>>641 >整数だけの判定ならできます。
それができているなら、その応用でできるでしょ。
試しにそのコードを晒して味噌。
644 :
641 :2007/09/20(木) 13:27:15
とりあえず正常系テストを int arrInput[4]; // 乱数配列 int retResult; // 結果受け取り変数 // int cntLoop; // ループカウンタ // int cntCk1; // チェックカウンタ // int cntCk2; // チェックカウンタ // int cntDbl; // 重複回数 /* 正常系テスト1 1234入力 */ printf( "正常系テスト1\n"); printf( "ユーザ入力で1234入力\n"); retResult = GetUserInput(arrInput); printf( "・戻り値:\n" ); printf( "期待される値:ERR_RET_NORMAL(0)\n"); 改行多すぎって怒られたので2回にわけます
645 :
641 :2007/09/20(木) 13:28:25
printf( "実行結果:%d\n", retResult ); printf( "・整数配列:\n" ); printf( "期待される値\n"); printf( "arrInput[0]:1\n"); printf( "arrInput[2]:2\n"); printf( "arrInput[3]:3\n"); printf( "arrInput[4]:4\n"); printf( "実行結果:\n" ); printf( "arrInput[0]:%d\n", arrInput[0] ); printf( "arrInput[1]:%d\n", arrInput[1] ); printf( "arrInput[2]:%d\n", arrInput[2] ); printf( "arrInput[3]:%d\n", arrInput[3] ); if( retResult==ERR_RET_NORMAL && arrInput[0]==1 && arrInput[1]==2 && arrInput[2]==3 && arrInput[3]==4 ) { printf( "正常系テスト1成功\n" ); } else { printf( "正常系テスト1失敗\n" ); やはり半角英数字のあらわし方がわかりません。
アホかい、肝腎な入力ロジック無しでどうしろっての。 つーか、GetUserInput()の段階で数字以外をどう扱ってるってのよ。
647 :
デフォルトの名無しさん :2007/09/20(木) 13:41:20
648 :
641 :2007/09/20(木) 14:02:38
>>646 ******************************************************************************/
/* ヘッダファイルの読み込み */
#include<stdio.h>
#include "../00_common.h"
/*******************************************************************************
関数名 :main関数
戻り値型 :int
引数 :無し
仕様 :GetUserInputに対する各テストケースを実施する
戻り値 :ERR_RET_NORMAL 0 // 正常終了
*******************************************************************************/
>>648 オレは
>>646 ではないが
>>646 はどうやって入力を受け付けているのかが知りたいんだと思うよ
scanf fscanf fgetc getchar fgets なんかで入力を受けてから
変換してるんじゃないかとは思うんだが
あと、気になったので突っ込んでおく
> 00_common.h
かなり危険な香りがする
> 引数:無し
!!!
>>637 char s[80];
strncat(s, ".exe", sizeof(s) - strlen(s) - 1);
なんだこれ。charはautoの配列であって、ゴミだよな中身は。
strlenは世界の果てまで0を探しに行ってSEGVを起こすかもな。
こんなコードは窓から投げ捨ててしまえ。
main関数だった orz 吊ってくる
単にsはcharの配列だよって説明してあるだけでは
すまん、俺も吊ってくる
656 :
デフォルトの名無しさん :2007/09/20(木) 14:37:54
はじめまして 設計の話なんですが、出席番号と氏名が一緒になっている文字列から【出席番号】と【氏名】を 別々に取り出すにはどうしたらいいか教えてください。 出席番号は3桁で氏名は10桁です。 ついでに聞きたいのですが、文字長ってなんですか? 出席番号の桁や氏名の桁と関係あるんですか?
コピーコンストラクタやoperator=って、 コンパイラが吐き出すデフォルトの動作のままでよい場合でも、 それらをprotectedにしたい場合は、自分で中身を書かないとダメなものですか? publicをprotectedにするだけの宣言方法は無いですか?
>>656 市長 市の長
村長 村の長
ってことは
文字長 が何か分かるよね
659 :
まり :2007/09/20(木) 14:50:10
はじめまして。 文字列からデータを取り出したいのですがどうしたらよいでしょうか。 詳細を記しますと 同じ文字列に入っている出席番号と氏名を別々に取り出し、構造体に格納したいのです。 出席番号は3桁、氏名は10桁とされています。 ちなみに文字の長さとはなんでしょうか 文字のサイズのことですか? この場合出席番号は半角数字で3桁なので3Byteってことですか? 氏名は全角で20Byteでいいのでしょうか?
>>656 規則性を見出してコーディング
>>657 class a{
private:
void operator=(const a&){}
};
の様に空実装するだけで防げる。
661 :
まり :2007/09/20(木) 14:52:00
>>656 も私です。
ごめんなさい。
書き込まれていないと思ってもう一度書いてしまいました。
>>658 さん
文字の長さってことですよね。
ただいまいち理解し切れなくて。。。
662 :
まり :2007/09/20(木) 14:54:14
>>660 さん
今PAD作成中でして、文字列の文字長が○○なら。。。って分岐をつくろうかなと思っているんですが
もう何がなんだかわからなくて
>>660 空実装にしてしまうと、実際の代入処理も行われなくなりませんか?
派生クラスのほうでこの基本クラスのoperator=を使うので、
代入処理自体はコンパイラが吐き出すものを使いたいのですが。
>>656 >>659 const char * str = "123abcdefghij";
struct Foo {
int num;
char name[11];
} foo;
sscanf(str, "%3d%s", & foo.num, foo.name);
>>664 宣言だけ置いておいたらどうなる?
protected:
void operator=(const a&);
>>666 「外部参照が未解決です」って言われます…。
668 :
まり :2007/09/20(木) 15:25:23
>>662 さん
自分で調べなさいと。。。
そして自分で調べてわからなければ誰かに聞きなさいと、、、
669 :
デフォルトの名無しさん :2007/09/20(木) 15:38:08
>>662 文字長ってのは書いた人がいい加減なだけで、文字列長のことだと思いますよ。
文字列の長さ(文字数またはバイト/ワード数。環境や定義による)のこと。
670 :
まり :2007/09/20(木) 15:55:53
>>669 さん、わかりやすい説明ありがとうございます!!
文字列長がどうたら言ってる奴にはさっさとソース書いてやったほうがはえーんじゃね?
勉強してるとこなんだろ? んで「文字の長さって・・・?」となっちゃったわけだ。
>>671 やっぱりprotectedにするためだけに、
デフォルトで吐き出されるものと同じで済むものでも
自分で書かないといけなくなるんですね。
protected:
void operator=(const a&) default;
みたいな記述があればよかったのに…。
default よりは super だべ
C++0xスレで= defaultを見かけた覚えがある。 こういう用途にも使えるのかどうかは知らないけど。
C++のテンプレートクラスの前方宣言とfriend宣言について教えてください template <class T> A<T>; template <class T> class B { friend class A<T>; }; template <class T> A<T>; の部分がエラーとなりコンパイルできません。 ただの前方宣言なのに何故でしょうか?
>>678 テンプレートクラスのfriendは規格外だったはず
構文が間違っとるよ template <class T> class A;
レスありがとうございます。
>>679 テンプレートクラスのfriend宣言はいろいろな書籍に載っていました。
>>680 なるほど、微妙ですね。。
template <class T> A<T>;
は文法違反ですか
この文法の説明が載っている
良い書籍はありますでしょうか?
プログラミング言語C++第3版
を見たのですが、明確な説明を見つけられませんでした。
gcc 3.4で普通にコンパイルできて動くプログラムが gcc 4.1になると、同じプログラムなのにコンパイルはできても 実行すると途中でアボートしてしまうのですがなんででしょうか? gcc 4.1になるとコンパイルできないとかだったら、ソースのミスと 考えられるのですが、gccのバージョンによってコンパイルはできるのに 実行だけできないなんてことが起こるのでしょうか?
はい
gcc3.4で動かしてたときも未定義動作がたまたま動いてただけじゃない?
>>682 起こります
特に下のようなコードになっている部分が怪しいです
#include<stdio.h>
int main(void){
char *ptr;
scanf("%s", ptr);
printf("%s\n", ptr);
return 0;
}
>>681 自分でも B の方は
template <class T>
class B {
って書いてるじゃないか。だったら A も
template <class T> class A;
になるのが自然だと思わない?
>>682 もともとダメなプログラムが、それまではたまたま偶然運良く動いてただけ
え?今何してるかって? プリプリプリプリプリプリプロセスだよ 同僚はブリブリブリブリブリブリブリブリブリブリブロセスしてるよ
>>686 確かに。
記述に惑わされていた気がします。
A<T>という形はオブジェクトの定義のときの
記述でした。{ } ; があるとクラス定義、無ければ宣言
ですね。
690 :
682 :2007/09/20(木) 20:13:41
みなさん返信ありがとうございます。 もう一度ソースを見直してみることにします・・・
>>687 それが業務プログラムでリリース済みだったらガクブルだな
一回でもまともに動いたんなら問題ない。腕の見せ所だ。
そういう仕事は往々にして評価されない訳だ 炎上した後でもない限りは
業務プログラムは無闇に開発環境を変えたりしないから平気なんだYO 新しいコンパイラが出てても、それまでと同じ古いコンパイラをずっと使い続けさせられるんDA
C++なら何気に静的オブジェクトの初期化順に依存したコードになっていて 今までは動いてたけど、それが変わるとダメになったとかな
副作用のあるコードの評価順序でたまたま動いてただけとか。
スタック破壊の可能性もあるだろうな 「printf一杯入れたら治った!」 とか言ってるアホがいたなぁ
return (0)とreturn 0ってどう違うの?
return (0);//バカ return 0;//正常
sizeof intとsizeof(int)ってどう違うの?
>>701 sizeof unary-expression
sizeof ( type-name )
b = a + 1; // 正常 b = ((a) + (1)); // 話ししたくない人
sizeof int; // エラー sizeof(int); // マル int i; sizeof i; // マル
文法的にはどちらも正しいよ ただ括弧付きなのは冗長
int a = (0); int a = 0; と同じ。本来括弧は不要。だが、括弧があっても当然値は変わらないので問題はない
void f(); ... (((f())));
>>703 無くてもいいのにつけてるってことだと思われ。
まあ、どっちでもいい。
気にすることはない。
(J_J) = ((((((O_O))))));
>>698 return(0)は 古い書き方 って、確か昔読んだ本に書いてあった気がする。
察するに制御構文の一種として考えると ... if(1), switch(2), while(3), for(;;)
みんなカッコ付いてるから合わせてんじゃないか?
みんなではない
(void)(function());
質問があります。 UNIX上で、dateコマンドの代替になるプログラムをCで作りたいのですが、 strftime関数に(char *)0を渡したときに戻すデフォルトの出力が 普通にコマンドラインからdateコマンドを実行した時の出力と 異なってしまいます。 (具体的には、日付の日本語表示などのロケールが適用されてない) マニュアルには「デフォルトは%cと同義」とあるのですが… strftime関数にロケールを反映させる方法は無いのでしょうか?
setlocale(LC_ALL, ""); かな
>>714 #include <stdio.h>
#include <time.h>
#include <locale.h>
void main(void)
{
time_t t;
struct tm *date;
char str[256];
t = time(NULL);
date = localtime(&timer);
setlocale(LC_ALL, "");
strftime(str, 255, "%Y, %B, %d, %A %p%I:%M:%S", date);
printf("%s\n", str);
}
VisualStudio2005のMSDNで _wfopenの所にある if ((fileHandle = _wfopen( L"_wfopen_test.xml",L"wt+,ccs=UNICODE")) == NULL) // C4996 ↑ ↑ この「L」ってどういう意味合いなんですか?
ワイド文字リテラル
BCBを使ってます。 void func(int cnt) { int a[cnt]; ... } int a[cnt]; の行でエラーが出ます。C++ではできないがCではできると聞きました。でもコンパイルできません。 BCBで上記のエラーメッセージは「C++エラー」とでるので、CでなくC++としてコンパイルされてる模様です。 Cとしてコンパイルするにはどうしたらいいのでしょうか。このソースの拡張子は .c なんですが。
C99に準拠したコンパイラじゃないとダメ
Cでは変数を要素数に指定できないはずだが 大人しくmalloc使っとけ
細かい仕様は知らないが、 動的配列を使いたいなら、C なら malloc() 、C++なら new を使え。
>>719 その形で配列を宣言するにはコンパイル時に要素数が定まってないとだめだよ
大人しくVBつかっとけ
全然大人しくねーよ
大人しくC++ with STL, boost使おうぜ!
>>722 C++ の動的配列は std::vector だろ。
>>719 >Cとしてコンパイルするにはどうしたらいいのでしょうか。
bcc32 -c func.cでobjファイル作ってobjファイルをプロジェクトに突っ込むしかなかった希ガス
BCBはC99対応してないからどのみちコンパイルは通らないけど
解析結果をソートするようなプログラムについて助言ください 文字列A,文字列B,数値データで入っているファイルがあるんですが こんなの↓ strA1,strB1,0.76 strA2,strB2,0.80 strA3,strB3,0.72 ...(ウン万行) このデータを3列目の数値データをキーにソートして、上位100個程度を取り出したいです。 C++のpartial_sortを使えば良さそうだと思ったのですが、数値データをキーに他データも並べ替える方法があれば教えてください C,C++に限らずある程度高速にソートできる手段があればなんでもかまいません
そこでtreeですよ
>>729 母数が大きくて上位100件なら全件ソートしない方法の方が速いかもしれない。
まず100件読み込む。適当なアルゴリズムでソート。
次の1件を読み込み100番目より上位ならば100番目を削除して挿入ソート。
同順位の扱いが必要ならもう一工夫必要にはなる。
CreateInstance("Excel.Applicってウワーナニヲスルー
>>729 数値データのファイルサイズはどのくらいになる?
サイズによってはデータを全てメモリに読み込んでから
処理したほうが早くなるので
#include <pstade/vodka/drink.hpp> #include <string> #include <vector> #include <list> #include <pstade/oven/algorithm.hpp> #include <boost/shared_ptr.hpp> #include <boost/lambda/lambda.hpp> #include <boost/lambda/bind.hpp> #include <pstade/oven/sorted.hpp> #include <pstade/oven/copied_to.hpp> #include <pstade/oven/foreach.hpp> struct Data { std::string strA; std::string strB; int nA; int nB; }; int main(int,char*[]) { namespace bll = boost::lambda; namespace oven = pstade::oven; typedef boost::shared_ptr<Data> pData; std::list<pData> src_data; std::vector<pData> dest_data; PSTADE_OVEN_FOREACH ( i, src_data | oven::sorted(bll::bind(&Data::nA, *bll::_1) > bll::bind(&Data::nB, *bll::_2)) ) { dest_data.push_back(i); } } その辺のオープンソースライブラリを使って作ってみました よければ実験してください><
>>731 なるほど、そういう方法も考えてみます
>>733 おおよそ10Mのセットをまたいくつかソートする必要あります
Rという解析ソフトで値を全部変数にぶっこんで処理させると、3Gのメモリもスワップにつっこむ有様す
いっそのことDBにぶち込むとか
>>736 手間はないけど、処理速度は期待できないよね
そんなことするくらいなら普通にPerlとか使った方が…
time_t data; sscanf( str, "%d", &data ); こうやってsscanfを使うとき、time_t型に対応する変換指定子は普通何を使うもんなんでしょうか?? %dで問題は無いものの、warningが出て気持ち悪いです。 キャストして sscanf( str, "%d", (int *)&data ); にすればwarningは出なくなるんですが、、、
time_t の型は決まっていない。 処理系によって 32 ビットだったり 64 ビットだったりするので、そういう使い方は無理。 やるとすれば time_t data; long long x; sscanf(str, "%lld", &x); data = (time_t) x; とかかな。
741 :
デフォルトの名無しさん :2007/09/21(金) 20:32:33
[1] 授業単元:C [2] 問題文(含コード&リンク): #include <stdio.h> int main(void) { int num; printf("整数:"); scanf("%d",&num); if (num) printf("その数は0ではない。"); else printf("その数は0。"); return (0); } をif分ではなく、条件演算子を用いて書き換えよ。 [3] 環境:Windows Bcc C [4] 期限: (2007年9月25日まで) [5] その他の制限:
すみません誤爆しました。
( num == 0 ) ? printf("その数は0") : printf("その数は0ではない");
環境がbcc32指定でbcc32独自の言語拡張使ったらぶち殺されるかな。やっぱ。 __closureとか__finallyとか__delphiclassとか
745 :
デフォルトの名無しさん :2007/09/21(金) 21:01:20
t_start関数って何?
printf("その数は0%s。", (num ? "ではない" : ""));
>>747 わかんない。
とりあえず、知らないなら黙ってて。
>>745 timer_startだとエスパーしてみる。
大きい配列を宣言するときはstaticを付けたほうが良い、と聞いたんですが、何故でしょうか??
>>751 そう言ったやつに聞けよ。
何かの間違いだと思うけどね。
>>751 一般的にstaticがない(=自動変数)場合はスタックに確保される。
一般的にstaticをつければヒープに確保される。
スタックはヒープに比べ容量が小さいのが普通。
よって、大きな配列などだと確保できない可能性が出てくる。
ってな感じの理由だと思う。
環境によって異なるだろうし、じゃあでかいのは全部ヒープに確保すれば
万事解決かっていやそうでもないだろうし、一概に絶対なんてことは言えないとは思う。
static付けた場合は静的記憶領域に確保されると思っていたが。 それに確保する時の処理がスタックの方が早いとは思うが 容量が違うって訳分からんぞ。
>>751 とりあえず
#include<stdio.h>
main(){
char str[256][256][256];
memcpy( str,"hello,world", sizeof(str));
printf("%s\n", str);
}
を動かしてみろ。コンパイルは通るがたぶん動かない。
次に、charの前にstaticを付けてみれ。
staticの有る無しで、strが収まる場所が変わる。staticが無い場合に格納される所は、
大きさの制限が厳しい。
>>751 そう言ったやつに聞かないのは、何故でしょうか??
夜中だからじゃないの
761 :
デフォルトの名無しさん :2007/09/22(土) 05:18:38
string s="0aあい"; のような文字列から、1文字ずつ機械的に取り出す方法はありあせんか? s[0]、s[1]はできても、s[2]はできないので困っています。
マルチバイト文字使ってりゃ当たり前だろ 全体的にunicodeに統一してみたら?
横からレスだが、Unicodeに統一って具体的にはどうするの? UTF-8やUTF-16は一文字ずつ扱いにくいので、1文字=1要素のUTF-32とかUCS-4にするってこと?どうやってリテラル書くの?
Unicode にしても、UTF だと大して変わらんぞ。
#include <string> #include <iostream> int main(){ std::wcout.imbue( std::locale("") ); std::wstring s = L"0aあい"; std::wcout << s.substr(2,3); } でそれっぽい事はできたけど環境によってはコンソールで文字化けする
Unicode、それもたとえUTF-32/UCS-4でも、 結合文字列があるから結局1要素1文字とは限らない。
それでもICUなら、ICUならなんとかしてくれる…
768 :
ICU :2007/09/22(土) 10:36:48
〉 _`、
ICU便利だけどデカ過ぎるから、ちょいとした小物には使いにくいだろな。 ICUのUCharはUTF-16なので、処理系のwchar_tと異なる場合には ワイド文字リテラルが使いにくいという悩ましさもある。
delete[] は type* (この場合 char* )から sizeof(type) * (プログラマからは見えない、確保された要素数) の分だけのバイトを開放するという挙動でしょうか?
ファイルにデータを書き込む処理を別スレッドでやると 完全に書き込まれる前に終了してしまうんですが 何か良い方法ないですか? バッファをフラッシュするだけでは不十分ですかね?
>>772 Win32API なら終了前に WaitForSingleObject
>>772 環境も言語もファイルの読み書きの手段も何もわからんが、
取り合えず、ファイルはちゃんとクローズしてんのか?
stdioのようなものでは、明示的にユーザがフラッシュせずとも、
クローズ時にユーザメモリ側のバッファはフラッシュされる。
が、OSカーネル側でも普通はバッファリングされている。
ダーティページをディスクにいつ書くかはOSの都合による。
ファイルの開き方によってその辺は変わることもあるし、色々だ。
その辺の制御を細かくやる必要があるのなら、
stdioやiostreamsなんてものは使うな。
あーそれと、VC++なら、CreateThread()は使うな。
_beginthreadex()にしとけ。
>>772 posix なら pthread_join
776 :
722 :2007/09/22(土) 16:42:52
レスサンクスです。 基本的にWin32API使ってます。 またご指摘通り_beginthreadex()にしてます。 WaitForSingleObjectでINFINITYにしてやってみましたが、やっぱり書き込まれてないです。 ファイルのクローズはしていて、ダメ押しでフラッシュしているんですが…。
アホすぎるんだよ プログラミングやめちまえ
778 :
772 :2007/09/22(土) 16:44:14
(誤)722 → (正)772
そもそもWriteFileが呼ばれるよりも前に、 プロセスが終了しているのではないだろうか。
>>776 んじゃ、実験的にメインスレッドを終了しないでキー入力待ちで放っておいたら書き込まれるか試して味噌。
>>776 #include<windows.h>
#include<stdio.h>
#include<process.h>
void write_file(void *dummy){
char *filename="write.txt";
FILE *fp;
fp=fopen(filename, "w");
if(fp!=NULL){
fprintf(fp, "File write start ... ");
Sleep(5000);
fprintf(fp, "finish!\n");
fclose(fp);
}
_endthread();
}
int main(void){
HANDLE th;
th=(HANDLE)_beginthread(write_file, 0, NULL);
Sleep(1000);
WaitForSingleObject(th, INFINITE); // この行をコメントアウトするかどうかで動作が変わるよ
printf("\nmain finished.\n");
return 0;
}
>>757 実行はできるが問題あるコードだ
例えば
#include<stdio.h>
#include <string.h>
main(){
char str[256][256][256];
char hello[] = "hello,world";
memcpy( str[0][0], hello, sizeof(hello));
printf("%s\n", str[0][0]);
}
>>781 それって正しく動くと保障されるのかな?
_beginthread()ってスレッド終了時に自分でスレッドハンドル閉じてしまう
んじゃなかったっけ?
784 :
781 :2007/09/22(土) 17:35:10
ごめん _beginthreadex でないといけないようだ
785 :
772 :2007/09/22(土) 17:36:59
( ´,_ゝ`)プッ バカジャネーノ
786 :
781 :2007/09/22(土) 17:42:26
>>776 >>781 の訂正版
#include<windows.h>
#include<stdio.h>
#include<process.h>
unsigned __stdcall write_file(void *dummy){
char *filename="write.txt";
FILE *fp;
fp=fopen(filename, "w");
if(fp!=NULL){
fprintf(fp, "File write start ... ");
Sleep(5000);
fprintf(fp, "finish!\n");
fclose(fp);
}
_endthreadex(0);
return 0;
}
int main(void){
HANDLE th;
unsigned thId;
th=(HANDLE)_beginthreadex(NULL, 0, write_file, NULL, 0, &thId);
Sleep(1000);
WaitForSingleObject(th, INFINITE); // この行をコメントアウトするかどうかで動作が変わるよ
CloseHandle(th);
printf("\nmain finished.\n");
return 0;
}
スレの無駄死ね
object GetObject() { object o; return o; } みたいな書き方って、メソッド内のオブジェクトは破壊されるよね? std:stringとかはどうやってそこらへんを解決してるの?
789 :
776 :2007/09/22(土) 17:46:25
ありがとうございます。
>>781 のような形で書いているんですけどね…。
現状では、完全に書き込まれることもあれば、
中途半端なままファイルが生成されてしまうこともある、といった状況です。
しかし、スレッドの終了直前で、ブレークポイントやMessageBoxで時間稼ぎすると
完全に書き込まれるようです。
また、メインスレッドはサブスレッドの終了にともなってすぐに終了することはないです。
790 :
776 :2007/09/22(土) 17:47:44
もう少し具体的に説明すると、 ・メインダイアログからウィザードを呼び出す ・ウィザード上で実行ボタンを押すと別スレッドでファイル処理 ・ファイル処理が完了すると同時にウィザードを閉じてメインダイアログに戻る といった感じの処理です。 メインダイアログでオブジェクトの実体を保持しているので、 プログラムを終了するまでは元のデータは残っているはずです。
>>790 CreateFile()でFILE_FLAG_WRITE_THROUGHを指定するか
最後にFlushFileBuffers()を呼んだらどうかな
>>790 書き込みが終わる前にメインスレッドの方でファイルを閉じてたりしない?
>>788 >みたいな書き方って、メソッド内のオブジェクトは破壊されるよね?
はい。そこに何か問題はありますか?
# 勿論、objectがコピーされるコストは掛かるけれど。
>>788 C++では参照だけが呼び出し側に渡されるんではなくて、オブジェクトが
コピーされるんだよ(参照を戻すように明示的に書くことも出来るけど)。
だから元が壊されても問題はない。
勿論正しくコピーが動作するようにクラスを書かなければいけないし、
コピーのコストはかかるがね。場合によっては最適化によって
コピーが削られることもある(それが言語仕様のレベルで認められている)が、
あまり過大な期待はしないように。
コピーのコストがバカにならないようなら、古き良き引数での参照渡しを
検討したほうがいいだろう。
オブジェクトの破壊はreturnでコピーコンストラクタが走ってから起こるという認識でいいの?
796 :
790 :2007/09/22(土) 17:59:25
>>791 772で言っていたのはFlushFileBuffers()のことです。
ファイルをクローズする前に入れていました。。
FILE_FLAG_WRITE_THROUGHは試してないのでやってみます。
>>790 ファイルの操作はサブスレッドにすべて任せているのでそれはないです。
>>795 コピーが終わった後だから、そうだと思うよ
コピーするなら test* clone() { new test(*this); } とかせんか?
ハァ?
フゥ!
>>798 それが適切な場面ではそうすればよいが
そうでなければコピーはコピーコンストラクタにやらせるのがC++の流儀だと思う
継承とポリモーフィズムを多用したコードなら、そうしたコードを
書きたくなることが多いかもしれない
>>798 ハンドルクラスを作るときにはやるときがある
とくに継承関係があるクラスに対して
804 :
788 :2007/09/22(土) 18:20:52
thx、何となくわかったよん。 フィールドに参照持たせた場合は shallow or deepに気をつけんと死ねそうだね
805 :
デフォルトの名無しさん :2007/09/22(土) 18:42:44
>>761 です。
woutとかICUって初めて聞きました。
調べてみます。
ありがとうございます。
>>796 100% Windows ではなく 790 の作ったプログラムのバグだと思う。
再現できるコードを見せられますか?
807 :
796 :2007/09/22(土) 19:32:58
>>806 すいません、解決しました。
どうもスレッドにファイル処理クラスのポインタを渡して操作していたのが良くないようです。
スレッド内で生成する方法に変えたら
ファイルに書き込み終わってから終了するようになりました。
↓こんな感じで
UINT __stdcall ThreadProc(LPVOID pParam){
// CFileCtrl *hoge = (CFileCtrl*) pParam;
CFileCtrl hoge;
// hoge->Write();
hoge.Write();
...
}
みなさんどうもありがとうございました。
>>807 親スレッドのほうで元のCFileCtrlオブジェクトを先に解放してたとか?
スレッドプログラミングに慣れてないんなら マルチコア/マルチプロセッサのPCで試験したほうがいいよ 問題のあるコードでもシングルコアでは普通に動いてしまうこともある
プログラミングに慣れてないんなら 死んだほうがいいよ 問題のあるコードで世界一恨まれることもある
でもスレッドプログラミングってシングル時に パフォーマンスが落ちないように作らない? 綺麗にスケールするよう心がけて。
>>811 それはそうだな。
全然C/C++ではないが、今日PythonでJavaのPipedStreamモドキをこしらえて、
それを使ってマルチスレッドでフィルタをパイプライン風にチェインして
並行処理をするようなプログラムを書いた。
俺の貧弱なシングルコアのノートでは、綺麗にスケールどころか
無駄にオーバーヘッドがデカくて、単にシングルスレッドで直列で
処理させたほうが格段に高速だったよ。
「定本 Cプログラマのためのアルゴリズムとデータ構造」で 昇順に並んでいる連結リストに要素を挿入する関数が以下のように書かれていました /* List 5.3 関数insert */ #include <stdlib.h> /* @@@@ */ struct CELL { struct CELL *next; int value; } header; insert(int a) { struct CELL *p, *q, *new; /* 挿入すべき場所を探す */ p = header.next; q = &header; while (p != NULL && a > p->value) { q = p; p = p->next; } /* セルを挿入する */ if ((new = malloc(sizeof(struct CELL))) == NULL) new->next = p; new->value = a; q->next = new; }
この本には「二つのポインタpとq使うのがミソ」と書かれていますが ポインタ一つで可能な気がしたので、自分で以下のように書いてみたんですが insert2(int a) { struct CELL *p, *new; /* 挿入すべき場所の直前の要素を探す */ for (p = &header; p->next != NULL && p->next->value < a; p = p->next) ; /* セルを挿入する */ if ((new = malloc(sizeof(struct CELL))) == NULL) fatal_error("メモリが足りません"); new->next = p->next; new->value = a; p->next = new; } 正直、違いが解りません 何故ポインタは二つ必要なのでしょうか
本のことは知らんが、別にどっちでもいい 同じアルゴリズムを実現するのに、書き方がひとつしかないなんてことはない 書きやすい&読みやすい方をどうぞ
>>813 headerは基点を表すだけの変数なので、本来値(value)は不要であり
CELLの実体でなくポインタで十分
この場合、コードは以下のようになり、pおよびqの2変数を使うのがよくあるやり方
(実際にはこの例でも1変数でできないことはないが若干記述がややこしくなり入門書として不適)
本の筆者が途中でコードを簡略化しようとしてheaderをポインタからCELLの
実体にしたとき、見直しが不十分だったと勝手に推測してみる
struct CELL* header = NULL;
…
struct CELL *p, **q;
p = NULL;
q = &header;
while (p != NULL && a > p->value) {
q = &p->next;
p = p->next;
}
if ((new = malloc(sizeof(struct CELL))) == NULL)
new->next = p;
new->value = a;
*q = new;
}
817 :
816 :2007/09/22(土) 22:21:20
ごめん mallocの後に fatal_error("メモリが足りません"); が抜けてる
( ^∀^)ゲラゲラ
それよかp = NULLの方がアレだと思う
アレって何
821 :
816 :2007/09/23(日) 12:53:53
ああ、申し訳ない ×p = NULL; ○p = header; 10年くらい前、開発環境がVC++に移る前はこんなリスト操作を量産して したので懐かしくて動作確認もせずに適当に書いてしまった ちょっとボケはじめているようです
822 :
デフォルトの名無しさん :2007/09/23(日) 12:55:16
static void ParseString(map<string, string>& m, const char* str); こんな関数を作ってるのですが map::insertの引数が const参照になってます。 この関数のローカル変数をinsertしても、 関数から抜けたら消えてしまいますか?
>>822 問題ない
map<string, string> は自分で実体を管理すると宣言しているわけので、
insert した時のパラメタがそのまま格納されるわけではない
たくさんの変数の値を初期化する関数を作ろうと思っているのですが 関数で数値を変更してreturnで返す時、たくさん返すにはどうすればよいのでしょうか? 配列を使う事を考えたのですが、それだと結局たくさんの変数全てに代入していかないといけなくなると思います もっと効率の良い方法はないのでしょうか?
構造体にでも入れてポインタ渡しとか
たくさんの変数は構造体にする 初期化関数に構造体のポインタを渡す 関数内で初期値を代入する
なるほど・・・ やってみます ありがとうございました
でも、ポンタってむずいんですよね....
ポンタは難しいかもな
なーに、煮て焼いて喰うだけさ
どうでもいいけど半熟煮卵ってなんであんなに旨いんだろうな
どうでもいいけど半熟煮卵ってなんであんなに不味いんだろうな
どうでもいいけど半熟煮卵ってなんであんなに旨いんだろうな
どうでもいいけど半熟煮卵ってなんであんなに不味いんだろうな
どうでもいいよ (´・ω・`)
コンパイラが暗黙的に作るコピーコンストラクタやコピー代入演算子の動作は、 全てのメンバ変数に対してそれぞれ operator= を実行することと同じですか? それとも、ただの memcpy ですか?
>>837 コピーコンストラクタはそれぞれのコピーコンストラクタ。
コピー代入演算子はそれぞれのコピー代入演算子。
構造体st_aをメンバに持つ構造体st_bがあったとして、 st_b->st_a->メンバ みたいにアクセスしたいのですが、それぞれどうやってtypedefすればいいでしょうか?
>>839 さっぱりわからんが、それは typedef で解決する問題なのか?
>>840 すみません、自己解決しました。
typedef {
int i;
st_a_t *st_a;
} st_b_t;
typedef {
int j;
} st_a_t;
st_a_t *p;
st_b_t *st_b;
st_b->st_a = p;
printf("%d", st_b->st_a->j);
みたいなことがやりたかったのですが、先にst_aへのポインタを宣言して、
それをst_b->st_aへ代入すればいいんですね。
>>841 st_b_tの前でst_a_tを宣言品。
843 :
841 :2007/09/23(日) 22:12:31
>>842 適当に書いちゃいました。一応誰が見るかわからないので、修正しておきますね…
typedef struct {
int j;
} st_a_t;
typedef struct {
int i;
st_a_t *st_a;
} st_b_t;
st_a_t *p;
st_b_t *st_b;
st_b->st_a = p;
st_b->st_a->j = 123;
printf("%d", st_b->st_a->j);
return 0;
844 :
デフォルトの名無しさん :2007/09/24(月) 01:21:15
プログラム中で nanosleep() を使っているのですが、 あるところから、停止している時間が短くなりません。 ・・・ int sec=1; //この値を色々変えている struct timespec treq, trem; treq.tv_sec = (time_t)0; treq.tv_nsec = (time_t)sec; と定義して、nanosleep(&treq, &trem) をfor()文中で使用しているという 状況です。 詳しく調べていないのですが、見た目では、 sec=999999999 からら secの値を下げていくと、だいたい、 sec=9999999 より値が小さいと、停止時間が一定となってしまいます。 sec=9999999 でも、sec=1 でも停止時間が同じです。 使い方が間違っているのでしょうか?
どのOSのことかわからんけど、そのOSのスレッド切り替えの間隔が10msごとなのでは。
846 :
デフォルトの名無しさん :2007/09/24(月) 01:26:56
>>845 Red Hat Enterprise Linux 3 です。
リアルタイムOSなら…リアルタイムOSならなんとかしてくれる…かも
うるさいわ自分で何とかせえや
850 :
デフォルトの名無しさん :2007/09/24(月) 02:11:19
>>847 ありがとうございます。
あんまり使いたくないですが、
for()で一時停止(っぽく)します。
851 :
デフォルトの名無しさん :2007/09/24(月) 02:32:00
すみません、本当に初心者でも質問してよいのでしょうか? (とりあえずしちゃいますが) VC6.0でSDKを使ってボタンを2つ配置したウィンドウを作っています。 そのとき、ボタンのウィンドウプロシージャだけを別にしたくて サブクラス化しているのですが、どこのHPを探してもボタンを2つ配置した 場合、ウィンドウプロシージャも、そのボタン用として2つになっています。 これを1つにすることはできないのでしょうか? 何がしたいかというと、ボタンやエディットボックスなどを複数個配置しても、 ウィンドウプロシージャは、メインのプロシージャと、ボタン用のプロシージャ エディットボックス用のプロシージャ、というようにしたいのです。
っ スーパークラス化
>>851 間違いなくあんたより初心者はわんさかいる。
それでだめなら、ハイパークラス化
855 :
デフォルトの名無しさん :2007/09/24(月) 03:00:00
>>852 さん
キーワードありがとうございます!また調査ができます!
>>853 さん
いるかもしれませんが、いろいろな掲示板を見ていると痛感します。
理解できないことが多すぎです。
856 :
デフォルトの名無しさん :2007/09/24(月) 03:01:48
>>850 ですが、
for()にでかい値を与えてループさせることで10ms以下の間隔を得る方法より、
もっと効率が良い、リソースの消費が少ないというような方法はありますか?
>>856 >for()にでかい値を与えてループさせる
再現性もないし、うっかり最適化すると消えてなくなるぞ。
カーネルを再コンパイルする気があるなら、切り換え時間を10msより短くできたと思うがお勧めしない。
>>850 > 1/HZ 秒の分解能をもっている
昔はHZが100だったので10ms余計にかかるんですね。
このHZが例えば1000だっt
ネタなのか本気なのか区別がつかないレスはやめてください
VS2005でC++始めたばっかなんですが、 基礎から学ぼうと思ってるんですが、プロジェクトは何を選んだらいいんですかね?
win32コンソール
己の分を弁えて何も選ばないのがいい
質問です。 例えば CFoo と言うクラスがあったとして CFoo foo; と宣言するのと CFoo* foo = new CFoo(); と宣言するのとの違いが良く把握できません。 後者はインスタンス作成と同時にコンストラクタを呼び出して、 インスタンスのポインタを foo に代入しているんですよね? で、前者の方はCFoo型の変数 foo は宣言のみで中身はカラッポかと思いきや、 . でメンバ変数やメンバ関数にアクセスできますし・・・ これがよく判りません。これはどういう扱いになってるのでしょうか?
Javaとかから始めた人には疑問かもね
どんだけぇ〜
>>866 寿命が違う。
コンパイラの実装の仕方は必ずしも同じでないが、
スタックとヒープの違いで説明されることが多い。
そのあたりの用語でググれば妥当な解説が見つかるだろう。
>>866 C++では、必要がない限り前者を使えば充分です。
>>869-870 即レスどうもです。
スタックとヒープですか・・・早速ググってみました。
つまり、前者の場合は
スタックにインスタンスが作成され、
関数の終了(グローバルならプラグラムの終了?)にインスタンスは削除される
後者の場合は、
ヒープにインスタンスが作成され、
明示的に削除(deleteですよね?)しない限りインスタンスは削除されない?
と言う認識でいんでしょうか・・・?
と言う事は、後者の場合はキチンとしないとメモリリークしまくりって事なんですかね?
バカじゃねぇの きちんと解説読め
そうですけどわざわざローカル変数にCFoo* foo = new CFoo(); なんて書く人いないだろうから 心配することないです
>>871 正確には関数ではなくスコープが切れたらだけど。
ループ構造の複雑なプログラムだとエラい事になるな。
それを回避する為にjavaやC#なんかにはガーベジコレクションが用意されている。
>>872-874 再度即レスどうもです。
とりあえずは
>>870 さんの言うとおり、前者を使っておけば問題ないと言う事なんですね。
気になる部分は焦らずに解説サイトじっくり読む事にします・・・。
ありがとうございました。
876 :
デフォルトの名無しさん :2007/09/24(月) 15:07:06
空のプロジェクト
そらのプロジェクト なんかかっこいい
なんかアホな質問するんですけど、 関数の内部で定義した構造体を他の関数から呼び出すことは無理でしょうか? やはりグローバルで定義しなければ呼び出せないのでしょうか? よろしくお願いします。
【-●_●)ノ”んなこたぁない!
new/mallocでヒープ領域に動的確保。 staticを付けて静的記憶領域に確保。
宣言じゃなくて定義だろ?
>>878 関数の中で定義しようが、外で定義しようが
構造体を“呼び出す”ことはできない。
struct aa{ struct bb{}; }; void function(){ aa; aa::bb; }
OS:ubuntu linux 7.04 端末エミュ:gnome-terminal Shell:zsh 4.3.2 g++:4.1.2 日本語のディレクトリ名が文字化けせずに表示可能 以上の環境下で以下のコードをコンパイルし実行すると #include <string> #include <iostream> int main(){ std::wcout.imbue( std::locale("ja_JP.utf8") ); std::wstring s = L"0aあ亜\n"; std::wcout << s; } 0a??とコンソールが対応しているにもかかわらず文字が化けてしまいます windowsではlocale("japanese")で上手くいったんですが… 文字化けさせずにワイド文字をコンソールに出力させる方法ってないんでしょうか?
886 :
デフォルトの名無しさん :2007/09/24(月) 18:24:19
手持ちの参考書ではexplicitの詳細が書かれていなかったので
webで色々情報収集していたら
http://hw001.gate01.com/eggplant/tcf/cpp/forgotten.html 上記のページのexplicitの項について
>if(a == ArrayA(100)) {
>と解釈して、コンパイルを通してしまいます。
>これを防ぐためのキーワードが、explicitです。
とありましたが、Visual C++ 2005ではコンパイル不可でした。
ArrayAに関して変換関数やoperator==を実装することによって正しく動作
するのは把握してますがexplicitとは無関係だと思うのでArrayAの右辺値が
ArrayA型に非明示的に型変換されるということはありえないと考えてよろしいでしょうか?
887 :
886 :2007/09/24(月) 18:33:58
半分自己解決(?) ArrayAのコンストラクタをint型を引数に取る変換コンストラクタとして利用し、 operator==の右辺値の引数としてArrayAをとる場合に、 >if(a == Arraya(100) という解釈が行われるってことですかね。その変換コンストラクタにexplicitが 無い場合はコンパイルが通り、explicit付だと不可でした。
>>885 >文字化けさせずにワイド文字をコンソールに出力させる方法ってないんでしょうか?
あります。
>>885 >文字化けさせずにワイド文字をコンソールに出力させる方法ってないんでしょうか?
ないです。
890 :
885 :2007/09/24(月) 18:57:34
>>888 それは標準ライブラリだけでできるでしょうか?
>>890 >それは標準ライブラリだけでできるでしょうか?
できます。
>>887 bool operator==(const ArrayA& r1, const ArrayA& r2);
があって(これは必要)、 r2を100で初期化するときに
const ArrayA& r2 = 100 を許すかどうかがexplicitによって決まる
引数を一つとるコンストラクタによる型変換を禁止するのがexplicit
この場合コンストラクタとして明示的に呼び出すことしか許されない
ArrayA a(123); みたいに
894 :
886 :2007/09/24(月) 19:15:59
>>893 分かりやすい解説、ありがとうございました。
>>891 >>892 つまりはこれはコードの問題じゃなくて、実行環境、コンパイル環境の問題ということですね?
まぁ確かに標準ライブラリのみ使用のコードがwindows cl.exeとLinux g++で違う動作をする
ってのはおかしいと思いましたが
>>895 標準ライブラリも各ベンダが実装している。
Locale周りは結構動作がまちまちだよ。
>>885 coLinuxのDebian serge環境(gcc 3.4.4)という怪しげな環境で試してみたが
imbue()効かないようだな。
std::locale::global()で設定してやるとおkだった。
VC++もこの辺未だに腐ってるし、localeまわりが完璧に動く環境って
あまり見ないが。
ああ、勿論g++のオプションでinput-charset, exec-charsetはちゃんと指定するのは
前提な。
明らかにふざけたレスに、真面目にレスしなくてもいいよ
明らかにふざけたレスに、真面目にレスするお
>>899 違う違う、それはchar側のエンコーディングだ
902 :
デフォルトの名無しさん :2007/09/24(月) 22:58:59
質問さしてください?
していただけませんでしょうか?
質問なんですが、 C++でリストボックスのに記載されている文字列を 選択・未選択に関わらず全て取得するにはどうすればよいでしょうか?
環境を書くのだ
ループ
>>895 >>897 >>897 の方法ならどうやら上手くいくようです
この方法はvisual studioでは上手くいかなかった記憶があるんですが、
最近のgccだと上手くいくようですね
オプションの設定はgcc-4.1.2ではどうやら必要ないようです(g++ filenameという記述でも上手く動作した)
助言ありがとうございました
>>899 全然違うものという気もしますが
ワイド文字の型でutf-8コードを表示するって分には問題無いように思えます
>>905 C++にリストボックスはないから・・・ちゃんと環境書いてくれ。
選択してるなら取得できるんだろ ただのアホでカウント取得してループって方法が思い浮かばない
>>906-907 ,909-910
すみません。環境はVisual C++ 2005です。
im = (int)SendMessage(GetDlgItemhDlg(hDlg, IDC_LIST), LB_GETCOUNT, 0, 0);
for(i=0;i<im;i++) {
SendMessage(GetDlgItem(hDlg, IDC_LIST), LB_SETCURSEL, i, 0);
GetDlgItemText(hDlg, IDC_LIST, data, sizeof(data));
MessageBox(hDlg, data, _T("確認"), MB_OK);
}
みたいにしてメッセージボックスで取得できたかどうか確認してるんですが、
文字列がカラッポです。何がいけないんでしょうか・・・?
リストボックスにはちゃんと値が入っています。
えぇーどんだけ〜 LB_GETTEXT
>>912 LB_GETTEXTと言うメッセージがあるんですね・・・。
助かりました。ありがとうございます。
>>902 void test(char ****N,int n)
…
*N = (char ***)malloc(sizeof(char**)*n);
for(i = 0; i < n; i++)
(*N)[i] = (char **)malloc(sizeof(char*)*n);
for(i = 0; i < n; i++){
for(j = 0; j < n; j++){
(*N)[i][j]= (char *)malloc(sizeof(char)*4);
}
}
for(i = 0; i < n; i++){
for(j = 0; j < n; j++){
sprintf((*N)[i][j],"%d",++k);
…
printf("%s ",(*N)[i][j]);
…
int main()
…
char ***N;
…
for(i = 0; i < k; i++){
for(j = 0; j < k; j++){
…
915 :
デフォルトの名無しさん :2007/09/25(火) 00:37:16
>>914 ありがとうございました。
勉強になりました。
学校の宿題って感じにみえるな
参考書を使って勉強してるんですが、そのまま写したのにエラーが出てコンパイルできません。 どうやら参考書自体が間違ってるようです。どこが間違ってるのか教えていただけませんか? 参考書:これからはじめるC言語 基礎の基礎 コンパイラ:lsi-c ver3.30c (試食版) #include <stdio.h> #include <string.h> /* 構造体の定義 */ struct person { char name[20]; /* 体重 */ double height; /* 身長 */ double weight; /* 体重 */ } /* 関数のプロトタイプ宣言 */ int set_struct(struct person* p_dat); /* main関数 */ int main(void) { /* 変数の宣言 */ struct person dat; /* set_struct関数を実行 */ set_struct(&dat); ↓↓↓↓↓
↓↓↓↓↓ /* メンバーの値を出力 */ printf("%s\n", dat.name); printf("%f\n", dat.height); printf("%f\n", dat.weight); return 0; } /* set_struct関数 */ int set_struct(struct person* p_dat) { /* 構造体のメンバーに値を代入 */ strcpy(p_dat->name, "山田太郎"); p_dat->height = 173.5; p_dat->weight = 63.0; return 0; } 長文失礼いたしました。
すみません。エラーの内容書き忘れていました。 エラー内容 c13:illegal type specifier combination 連レス失礼しました。
>>920 struct person の定義の最後、セミコロンがない。
>>921 ありがとうございましたコンパイルできました。こんな単純なミスで無駄にレス使ってすみませんでした。
参考書にはちゃんと書いてありました。単なる見落としです。
あなたはすぐにわかったのに、こんな間違いに気づかず2時間も悩み続け
挙句の果てに参考書のせいにした自分がとんでもなく情けないです・・・
少しでもそう思うなら死ねばいいよ
>>922 エラーメッセージに行数も出てるはずだからエラー1個とか単純なものなら
その周辺を探せばすぐ見つかることが多い。後メッセージの内容にも
'type'って書いてあるから型関連のエラーと当たりを付けることができる
(今回は少し違ったけども)。
925 :
デフォルトの名無しさん :2007/09/25(火) 03:34:56
>>922 気にすんな
長いプログラム書いてても、しょーもないミスはするもんだ
ただ、そのしょーもないミスのレベルが経験重ねると
ミスのレベルも上がってくる。
ま、とりあえず気長にね
>>925 気にしろ!
短いプログラム書いてても、しょーもないミスをするもんはする
ただ、そのしょーもないミスを経験重ねても繰り返してるなんて
いつまで経っても使えない奴。
ま、とりあえず死ね
>>926 何おこってんの?
ミスのレベルも上がるって書いてるでしょ?
どこに同じミスを繰り返すって書いてる?
ま、いいや
お前も死ね
>>926 の言う通りまたミス繰り返しやがったw
どこに同じミスを繰り返すって書いてる?
ミスを繰り返すって書いてあるだけだぜ?
ミスのレベルがあがって許されるのはドジっ娘だけだろ
ここはどこの居酒屋ですか…
配列を初期化した後にその要素数を調べるのはどうしたらいいのでしょうか? int hoge[] = {1,3,5,6,7,9,}; int n; for (int = i; i < n; i++) // n は要素数 { cout << hoge[i]; } のように順番に取り出したいのですが明示的にnを指定せずに 自動的に要素数を所得させたいのです
それくらいなら、boost::size(hoge)が楽。
>>908 > この方法はvisual studioでは上手くいかなかった記憶があるんですが、
VC++8.0(VS2005)ではそうだな
> オプションの設定はgcc-4.1.2ではどうやら必要ないようです
UTF-8なソースの場合は要らない、というだけだと思われ
>>935 ありがとうございます
boostは便利そうなんですが、どんなものがあるのか
どんな事が出来るのか、またどうやって利用すれば良いのか
を知るまでが大変そうですね・・・
c++での時間の扱いはどういうのがありますか? やっぱり time.h 使うんですか?
>>938 Cに対して時間に関しては特に追加のライブラリはない。
標準の範囲内では <time.h>, <ctime> で。
boost になんかあったかもね。
C++にはboostとかSTLとかライブラリ?がいっぱいあるけど それぞれの位置づけがよくわかんない どれが標準でどれがセミ標準でどれが趣味なのか 体系付けて一覧できるHPってある?
人生、宇宙、すべての答えが載ってるHPってある?
俺の人生と俺の認識できる宇宙なら2ちゃんねるでじゅうぶんですwww
標準はstl、boostがセミ標準 それ以外って何?
boost-sandbox, boost-vault
>>937 スマートポインタとかなら#includeするだけで使えるしスゲー便利だから
その辺から徐々に使っていくといい。
サンプルとテストプログラムを動かしたりしながら自分用にドキュメントを翻訳しているだけで もう半年ぐらい費やしてるんですが、まだ「こういう機能があると知っている」程度にしか理解できてません 使いこなせるまでに死んでそうな気がします…
車輪の再発明は無駄だ、あるものを使え それは確かなんだが、星の数ほどもある既存の道具を探して学ぶにも限度があるよな
time.hのtm構造体についての質問です。 なぜtm_monは0〜11であり、 なぜtm_mdayは1〜31なのでしょうか。 どちらか一方にそろえる形で両方を0から起算、1から起算とするわけには いかなかったのでしょうか。
(´・ω・`)知らんがな
K&Rにでも聞きにいってくれ。
>>952 英語では月を 1, 2, ..., 12 と書くよりも January, February, ..., December のように書くので、
配列のインデックスとして直接使える方が良かった(例:↓)という説がある
const char *monthNames[12] = { "January", "February", ..., "December" };
printf("%s", monthNames[t.tm_mon]);
日は英語でも 1st, 2nd, ..., 31st のように書くので、1...31 そのままなんだろ、たぶん
車輪の再発明と車輪がどういう仕組みかを理解する事は違う。
誰もその車輪の性能を説明してくれない。車輪作った人ですらも。 挙句の果てに「使ってから文句家」「自分で分解して調べろ」だろ。 これじゃどうしようもない
使い方の説明もいいかげんだから ばらしながら使い方覚えないと駄目だしね しかし教材として考えればなかなかいいかもしれん 膨大なMLにヒントは用意されているし
replace_copy_if(v.begin(), v.end(), back_inserter(v2), bind2nd(ptr_fun(str_comp), "C"), "C++"); これ、Borland Turbo C++ だとコンパイルできない。 g++だとできる。 "C++"を string("C++")にするとTurbo C++はコンパイルできる。 単なる実装の違いということ?
旧い実装のコンパイラなんか使うからだろ。
>>960 コンパイラじゃなくてライブラリじゃないの?
>>957 何を期待してるの?
どうしようもない。っていう意味には、
あなたのスキルが低いからという理由も含まれるんだよね?
少なくとも車輪を分解して調べられる。
これをメリットととるかデメリットととるかだな。
サポート期待するなら、商用製品買えばいい。
分解するのがめんどくさいなら、自分で作ればいい。
選択する自由は自分にあるだろ。
ま、使いづらい・わかり辛いとかって時点で車輪じゃないんだろうな。 個人の技術レベルをあげるほうがのほうが先だろうけど。
list<CHoge *>で持ってるメンバ変数を const list<const CHoge * const> &の参照で返す関数を作りたいんですが 単純にキャストすると怒られます どうすればいいんでしょうか 今は仕方ないので別にlist<const CHoge * const>を作ってコピーしてますが const参照させるためだけに全く同じ内容のリストを作るのが嫌なんです 何とかならないでしょうか
>>964 CHoge * と const CHoge * const はバイナリレベルで互換することが保証されて
いるので、 list 自体も const な参照ならキャストしちゃっても安全だと言えると思う。
コメント添えてキャストすればいいんじゃない?
ただし public なインターフェースであればメンバへの参照を返すのは実装を
固定することに繋がるのでお勧めしない。
>>962 仕様書くらい用意しろボケ
という話です
用意終わた いえーい!
>>955 なるほどthx、ちょうど友人と配列に英語での名前取った時に都合がいいんじゃ
ないかって議論もしてました。
>>968 なるほどthx、ちょうど友人と配列に英語での名前取った時に都合がいいんじゃ
ないかって議論もしてるんじゃないかって議論もしてました。
970 :
デフォルトの名無しさん :2007/09/26(水) 20:28:09
int data[10] ={10,20,30,40,50,60,70,80,-999} このようなint配列があります 配列の内容を実行結果のように表示するプログラムを作りなさい -999になれば処理を終了します ポインタを固定して表示させる処理とポインタを変化させて表示させる処理の2つ作成しなさい この内容がわからないので教えて下さいお願い致します
命令形で問われても答える気になれない
実行結果のようにとか言っておきながらないし
>>970 >配列の内容を実行結果のように表示する
実行結果がわからんから答えられないなあ
要は添え字で処理するかポインタで処理するかということか?
添え字なら data[i] で扱って i を変えてく
ポインタなら
int *p = data; pを順番に進めていけばいいんでないか?
しかし実際はどちらもポインタ演算という…
976 :
デフォルトの名無しさん :2007/09/26(水) 21:21:46
[1] 授業単元: 教科書 [2] OS Windows [3]問題 int data[10] ={5,8,10,2,1,14,35,6,12}: 配列中の最大値と最小値を表示するプログラムをポインタを使用して作成するプログラムが解らないので教えて貰えませんか?
宿題スレへ池
max_element min_element
979 :
デフォルトの名無しさん :2007/09/26(水) 23:22:39
int a[0] = {10}; int a = 10; って実質的に同じ?
int a[0] = {10}; int b = 10; *(a + 0) == a[0] == b
ん?int a[0]ってコンパイル通るのか?
蟹炒飯をググってみたがさっぱりわからんかった。 そしてコンパイルは通らなかった。(VSEE 2008) C99からの仕様?俺の無知?だんだん不安になってきた・・・
struct TEST { DWORD dammy ; BYTE x ; DWORD dammy2; BYTE y; }; TEST Test ; ZeroMemory(&Test, sizeof(TEST)) ; Test.x = 0xAA ; Test.y = 0xBB ; 脳内結果予想 00 00 00 00 AA 00 00 00 00 BB 現実 00 00 00 00 AA 00 00 00 00 00 00 00 BB 00 00 00 なんです?
986 :
985 :2007/09/27(木) 02:23:54
途中で送信してしまいました>< なんでこういう結果になるのかわからないです。よろしくお願いします。
>>986 DWORDが4バイト境界に配置されたため。
しかも説明が抜けてる。il||li(つω-`。)il||li バイナリはファイルに保存したときに思い通りにならないって話です
>>986 アライメント、パディング、構造体とかでぐぐれば幸せになれるよ。
*char[] = {"hoge","hage","boke"} こういう初期化を std::string 使って表現出来ないのでしょうか?
std::string *Bjarne_Stroustrup[] = {new std::string("hage"), new std::string("hage"), new std::string("hage")} ;
994 :
デフォルトの名無しさん :2007/09/27(木) 11:39:57
995 :
デフォルトの名無しさん :2007/09/27(木) 11:50:57
vs2005を使ってるんですが、グローバルな関数の関数ポインタと クラスのメンバ関数の関数ポインタを統一的に保持しておきたいです。 (どんな自作クラスのメンバにでも対応したい) 実現する方法があれば書き方を具体的に教えてください。 class CFuncHolder{ private: void (*m_pFunc)(char*); public: CFuncHolder(){}; void SetFunc(void (*pfunc)(char*)){m_pFunc = pfunc;} void RunFunc(char* str){m_pFunc(str);} }; void gfunc(char* str){ MessageBox(NULL,str,"",NULL); } class cfunc{ public: void func(char* str){MessageBox(NULL,str,"",NULL);} void (cfunc::*GetFuncPtr())(char*){return &cfunc::func;} }; void main(){ CFuncHolder fh; fh.SetFunc(gfunc); fh.RunFunc("hohoho"); //cfunc cf; //fh.SetFunc(cf.GetFuncPtr()); }
そんなあなたに boost::function
997 :
デフォルトの名無しさん :2007/09/27(木) 12:43:20
>>996 ども。保持する方は、
class CFuncHolder{
private:
boost::function1<void, char*> m_func;
public:
CFuncHolder(){};
void SetFunc(void (*pfunc)(char*)){m_func = pfunc;}
void RunFunc(char* str){m_func(str);}
};
とかでいいんですよね?
で、渡す方は、boost::bindとやらが使えるっぽいのですが、書き方がさっぱり分かりません。
void gfunc(char* str){
MessageBox(NULL,str,"",NULL);
}
class cfunc{
public:
void func(char* str){MessageBox(NULL,str,"",NULL);}
void (cfunc::*GetFuncPtr())(char*){return &cfunc::func;}
};
void main(){
CFuncHolder fh;
//グローバルの関数ポインタを渡す
fh.SetFunc(gfunc);
fh.RunFunc("hohoho");
//クラスメンバの関数ポインタを渡す
cfunc cf;
//fh.SetFunc( boost::bind(/*?????*/) );←ここの書き方教えてください。
fh.RunFunc("hehehe");
}
boost::bind(&cfunc::func, cf, _1);
ごめん↑のは多分動かない
1000 :
デフォルトの名無しさん :2007/09/27(木) 12:59:39
そして伝説へ・・・
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。