【初心者歓迎】C/C++室 Ver.70【環境依存OK】
1 :
デフォルトの名無しさん :
2009/11/22(日) 16:04:30
ぬるぽ
>>1 乙
自分は立てたくても立てられなかった
>>2 ガッ
4 :
デフォルトの名無しさん :2009/11/22(日) 19:49:45
おつ
生態シミュレートのプログラムを作ろうと思ってるんだけど、無限に要素数を増やす方法を どうしたらいいのかがわからないんだけど。 一応ひとつ思いついた方法としては、構造体の中に、自分自身へのポインタを持たせて、 そのポインタをはじめは0にしておく。で、新しくnewかなにかをして、そのポインタを既存の要素に 持たせる・・・って感じなんだけど、これだと、途中で要素が消失したとき、その後の要素が 行方不明(ポインタが何処にも存在しない状態)になってしまう・・・ね。 はじめからポインタを用意してたら、上限数が決まっちゃうし、どうしたらいいかな?
STLの適当なコンテナ使えよ どうしても自分で書きたいならリンクリストでググれば望みのものがでてくる で、なんで生態系シミュレートにリンクリストがいるんだ? 生物を数珠つなぎにしてなにかいいことあるのか?
無限に増えるシミュだとすぐにメモリが枯渇する気がする
>>5 消える要素の後の要素のポインタを、消える要素の前の要素のポインタにつっこめばいい。
9 :
デフォルトの名無しさん :2009/11/22(日) 21:13:54
質問です。 char *func(){ char str[]="hogehoge"; return str; } void func2(){ char *str; str=func(); } とした場合、 func2内での、strの配列の領域が保証される寿命ってどこまでなのでしょうか? func()抜けた瞬間、strが解放されると思ったんですが、一応暫く使えてるんですが・・・
>>9 抜けた瞬間消えるけど、わざわざクリアしないし、しばらくは残ってるな。
基本、アクセスしちゃだめ。
いやいや、staticでない関数内で確保した領域のアドレスを関数外に返しちゃ駄目でしょ void func(char *str){ str = "hogehoge"; } void func2(){ char *str; str = func(str); }
間違えてた、返り値消してない void func(char *str){ str = "hogehoge"; } void func2(){ char *str; func(str); }
14 :
デフォルトの名無しさん :2009/11/22(日) 21:35:50
>13 何がしたいの
>>9 >char str[]="hogehoge";
これ結構な高コストだからあまり多用しないほうがいいよ。
static char str[]="hogehoge";
なら良いけど。
>>17 ポケモンカードでいうと、エネルギーカード2枚分くらいのコストですか?
>>17 分かってないなぁw
改悪になってる・・・
ひょっとして"hogehoge"用に領域が9バイト確保された後、コピーされると思っていない?
違うんだなぁ、これがw。
プログラムがRAMにロードされたとき、
データとして"hogehoge"はメモリ上に展開されて、
その代入ではホゲ文字列の先頭アドレスがstrに設定されるだけ。
分かる?スタティックにする理由は何?
コピーされなかったら配列は永遠に初期化できないじゃないか。 char *str = "hogehoge"; ならともかく。
コンパイル時に数が決まるから strcpy() よりは早いけどな。 まあ、ループ展開しないと比較演算は必要だから同じか。
25 :
20 :2009/11/22(日) 23:01:28
>>23 おぉ、すまんすまんw。
自分のコーディングスタイルと違うので間違っちゃったw。
char str[]="hogehoge";
ってすると、スタックに積まれてたw。
これは危険だ!
なにげに勉強になっちゃったw。
では、さらばだ!
>>6 いや、数珠つなぎにしたいとかじゃなくて、無限に要素を増やしたいから、どうしたものか・・・と。
で、自分がとりあえず考えた方法があれだったっていう
>>8 だなぁ・・・。
やっぱ、そうしかないのかな?
とりあえず、回答ありがとう。
>>5 遅くていいならディスク上にファイルとして配列を持ち、ガリガリやれよ
相当遅いが、1TBの配列だって持てるわけだ
*dataと*tmpを用意、*dataに大きさNの配列を動的に確保 要素数がNを超えそうなら*tmpに大きさ2Nの配列を確保して*dataの内容をコピー後ポインタをスワップ スワップ後のtmpを解放 まあただのvector実装なんだが
そも無限は無理。
>>26 だから、無制限に要素を増やそうとすると数珠繋ぎとかになるんだよ
じゃなきゃ、溢れた時にでかい領域を再確保してコピーするとかな
で、それらをきっちりやってくれるのがSTLコンテナだが、原理知らないで使うと
えらいパフォーマンス落としたりもするから、一度自分でそれらしく書いてみても
いい
理屈が理解できたら、STLコンテナを使っちゃった方が安心で軽くて楽だが
128KBくらいのブロックをつなげろよ。 HDDのクラスタと同じようなもん。 vectorなどは、再配置するから効率悪い。 ブロックで管理すれば再配置無し。
実質ブロックで管理(仕様では明記してないけど)してて それなりに高速なデータ構造となるとstd::dequeかな。 悩んだらとりあえずdequeつかっとけというのが俺の経験則。
64bit数が10億個ほど出現して、以前に出現したかどうかを 高速、低メモリでチェックするはどうすればいいですか。
setでいい気がしてきたのでこれでいってみます
リロードし忘れてた
鳩の巣法が思い浮かんだけどどうせ64ビットのハッシュ値とかだろうしなあ
質問です。 名前空間でクラス名を分けた場合、 -> Hoge::Foo FooはHogeで完全に修飾しています(のはず) このように、よく、C++で「完全修飾」という言葉を聞くのですが、 この「完全」とはどういう意味が有るのでしょうか。 また、「不完全修飾」みたいなものがあるのでしょうか。 今まで単純に、「修飾している」という感覚しかなかったので…… よろしくお願いいたします。
>>33 そもそも10億個の64bit値を格納するメモリが最低でも8GBほど必要だけど、
低メモリとか言っていられるのか?
最初の1まんこだけ抽出して、値の偏りを検出して、残りのまんこは推測する^^
HDDを使ってデータベース作っても良いです
じゃあSQLiteのDBに突っ込んで検索だ。
Hoge::Hoge() {〜} Hoge::Hoge(Fuga fuga) { Hoge::Hoge(); 〜 } これっていいの?
>>38 現在の名前空間関係無しに、グローバルから全部書いたときじゃない?
>>43 たぶん良くない。
何がしたいのかよくわかんないけど。
あ、コンストラクタから同じ this を初期化するコンストラクタを呼び出したいなら、
現行規格では無理。 C++0x を待ちつつ、 private メンバ関数に分けるとかする。
ヒーププロファイラを使いたいのですが MinGWかVCで使えるやつありますか。 Google perftools はビルド可能なんですか
この構造体Aは全く同一ですか。 A x; と変数を確保すると、 x.leftとx.rightはA = struct A or struct Bですが、下の記述の方がわかりやすいだけですか。 typedef struct A { struct A *left; struct A *right; } A; typedef struct B { struct B *left; struct B *right; } A;
typedef は別名を付けるだけだから。
ということは同じっていうことですか
typedefが無かった場合、struct〜って書くでしょ それと同じってこと。
別名を付けるだけだから、 実際には struct A と struct B であって それぞれは別物。 つーか、質問の意図が不明確だから答えづらい。
qsortとstl sort比較した。 vcで最適化がうまくいくとstlが速いけど、bcc gccではqsortが速かった
#include <time.h>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
int qsort_cmp(const int* a, const int* b) { return *a - *b; }
class stl_sort_functor_cmp { public: int operator()(const int &a, const int &b) const { return b > a; } };
unsigned int xor128() { static unsigned int t, x=123456789UL,y=362436069UL,
z=521288629UL,w=88675123UL; t=x^(x<<11); x=y; y=z; z=w; return w^=(w
>>19 )^t^(t
>>8 ); }
void do_stl_sort_functor(int size) {
vector<int> v(size);for (int n=0; n<size; n++) v[n] = xor128();
double start_time = clock();
sort(v.begin(), v.end(), stl_sort_functor_cmp());
double elapsed = clock() - start_time;
cout<< " STL functor sort " << elapsed / CLOCKS_PER_SEC<<endl; }
void do_qsort(int size) {
int *v= new int [size];for (int n=0; n<size; n++) v[n] = xor128();
double start_time = clock();
qsort(v, size, 4, (int (*)(const void*, const void*))qsort_cmp);
double elapsed = clock() - start_time;
cout<< " qsort " << elapsed / CLOCKS_PER_SEC<<endl;
delete v; }
int main() {
int size = 10000000;
do_qsort(size); do_stl_sort_functor(size);
do_qsort(size); do_stl_sort_functor(size); }
>>53 qsort() は関数ポインタを大量に呼び出す分、stl に比べて分が悪いですね。
2分木をファイルへ保存するにはどうすればいいですか?
qsortの方が速くなるようだと根本的に書き方がおかしいと思われ
>>53 ECC(Embarcadero C++ Compiler 6.2.0)だとSTLの方が速かった
BCCもバージョンによって違うよ
特にヘッダーファイルはコロコロメーカーを変えているからね
qsort() はデータの移動が発生する時バイト単位でコピーするから、 代入演算子でコピーする STL の方が速くなるのは当然。
研究に用いるシミュレーターのツールキットがC++で書かれているため 必要に迫られて、勉強を始めました。 しかし、配列すら宣言できないひよっこです。 どなたか助けて下さい…。 あまりに巨大なツールキットなので、質問の意味が支離滅裂になるかもしれませんが、 ご了承下さい。 使用しているシミュレーターはGEANT4という高エネルギー放射線のシミュレーションツールキットです。 OSはFedora11を使用しています。 コンパイラはgcc-g++です。 検出器を定義するソースコード部に、配列を定義したいのですが、できません。 書式は、 G4double mc[1000]; G4というのは、GEANT4内で使われている接頭詞のような物みたいで、G4intやG4string等もあります。 多分、Cで言う所のdoubleと同じかと思います。 こう書けば、ダブルのタイプを持つmcという配列が1000個、準備されると認識していたのですが… makeにかけると… src/BodySD.cc:86: error: invalid types ‘G4double [1000][const G4double]’ for array subscript と出て、エラーとなってしまいます。 書く場所がマズいのでしょうか…。 とりあえず、読み込まれているヘッダーの中や、定義したいソースの中、使いたい関数の中等 試してみたのですが、どれもダメでした…。 どうすればいいでしょうか。
61 :
60 :2009/11/27(金) 23:04:55
まずG4doubleの定義を確かみてみろ。
すみませんでした。ソースコードをよく見たら G4doubleはプロトン粒子砲を発射するためのスイッチでした。
64 :
60 :2009/11/28(土) 03:58:43
BodySD.cc
ttp://codepad.org/UGM9339c ApplicationManager.hh
ttp://codepad.org/CIkJITXy EventAction.cc
ttp://codepad.org/TEcY4hyR この3つが、おそらくシミュレーション中に密に連携を取り合っている部分だと
思っています。BodySDで検出器の動作を定義し、エネルギー沈着が起これば逐一
ApplicationManagerを用いてデータを更新し、イベントが終了した段階で、EventActionを呼び出し
ファイルに、各検出器での沈着エネルギーを出力したいと考えています。
が、このように改変しても、先程の現象に変わりは無く…。
どなたか、助けていただけないでしょうか。
出力の場面については、多分ですがミスってる気がしてます。
検出器ナンバーを呼びにいかなくても、ループで回して出力すればいいだけだと、
貼り付けながら思ってしまいました。
typedef double G4double; されてるじゃないか 添え字の型がおかしいぞボケ!ってエラー出てるんだから theEdepPerDetector[copy_number]のcopy_numberを整数型にしろ
don't panic そんなとこで研究してる人なら自力でできる
だいたいなんで検出器の番号が浮動小数点型なんだ
下らない質問ですいません namespaceはjavaのパッケージの事で、 namespace hoge;はjavaのimport hoge.*;と同じような事をしているのですか?
パッケージと名前空間の違いはいろいろあるけど、しばらくはその理解でも構わないと思う。
70 :
68 :2009/11/28(土) 14:55:06
C++を学ぶときはJavaの知識は一時的に捨てるか Javaのオブジェクト確保の実態や ガベージコレクションの概要なんかを理解してからの方が無難。
>>62 >>65 >>67 ヒント、ありがとうございました!!!!!!
検出器ナンバーをdoubleからintにすると、コンパイルが通りました!
なんとも初歩的なミスでお恥ずかしい限りです。
とりゃえず、全力でシミュレーションしていきたいと思います。
本当にありがとうございました。
>>66 初歩的なミスでパニクってしまっていました。
励まして下さってありがとう。頑張ります。
std::stringではなくstd::vector<char>を使いたい時ってどんなとき?
>>74 string にも '\0' は入るんだが。
まぎらわしいってこと?
>>73 std::string はメモリの連続性が保障されていない(?)から
sprintf のようなC言語よりの関数には
メモリの連続性が保障されている
std::vector<char> を使うことがある
文字列を取得する際のバッファとしてね
C++0xからstd::stringもメモリ上の連続性が保証されるようになるね std::ropeははなっから連続してない
private void setXXX(String s); C#やJavaだとこんな感じでメソッドを宣言していますが、 public: void setXXX(string s); みたいな感じにC++は宣言していますが、これがデフォルトなんですかね? おまけの質問で申し訳ありませんが private: int test; int hoge; hogeもprivateになるってことで、おk?
>>79 そうだよ。
こんどから自分で試してから聞こうね。
ok
82 :
79 :2009/11/29(日) 19:17:27
>>80 ありがとうございます
試したいとは思っているのですが、メモリリークが怖くて怖くてやる気になれません
まだ、簡単なメモリの管理の仕方もわからないのでorz
そのうち、自分でも試してみるようにします
>>82 メモリリークをなんだと思ってるんだ?
コンパイルしただけでメモリリークなんか発生しないし、
そんなコード片だけじゃ実行したとしてもメモリリークの原因になんかならないし、
本当に発生したとしても普通の OS 使ってるなら、プロセス殺せば何も残らん。
変な理由で怖がってないでコンパイルぐらい自分でやれ。
C++の勉強をするときはJavaの知識はいったん捨てなさい。 Javaではオブジェクトを確保するのに必ずnewを使うけど C++ではこれはちょっと厄介。もっと素直になりなさい。
メモリモデルがわかれば簡単。余計なメモリを確保しなけりゃいいんだからね。 とりあえず、スタック領域とヒープ領域の違いを明確にすれば、 そのうちJAVAのテクニックも使えるようになると思うよ。
動作が安定している正規表現ライブラリはなんでしょうか。 boost 鬼車 posix bregexp だとどれがいいですか。 bregexpは長い正規表現を間違える経験があります
あと安定以前に移植性が無いと駄目なんです。 bregexpはまとめれば1ファイルのヘッダに収まる位なんですが posix regex.hは割と多くが対応していると思うんですがBCCだと無いです。 別名で互換のが入ってますが、完全な互換ではないです。 拡張正規表現が使えるかどうかが判明しないです
俺は正規表現は標準待ちなので使ったことないんだが、 客観的に考えて、比較的枯れていて移植性というならBOOSTが一番だと思う。 素人のたわごとなんだが。。。
長いの間違えるのが嫌なら自分で作ればいいじゃない
正確には、コンパイラがメモリ確保するときに使用可能な領域にするだけだがな。 Cコンパイラから、OSへは返還していない。
移植性って意味じゃboost::xpressiveなんかは造り的には良さそうだけどな 安定性は知らん
posix regex.hは駄目だった バイナリ、特に0を含む文字列が扱えない。 boost行ってみる。
boost::xpressiveは依存複雑、バージョン違いの問題ありで駄目だ。 bregexpか、マイナーなやつ発掘してくる。
boost::regexというものもある訳だが
boost::regexと鬼車はバイナリ必須なので無理・・・ 標準のCコンパイラ単体でビルド完了したいんです。
いつもお世話になっております。 class Test { private: string s("str); } なぜ、ダメなんですか?
あなたの脳が駄目です
>>95 一応確認しとくと正規表現パターンは動的に変わる必要があるんだね?
あるよ Bregexpをヘッダオンリーで出来るように書き換えたのでこれ使うことにした。 鬼車も手を加えたら、軽量化してヘッダーオンリーに出来そうだけど。 文字コードの部分をばっさり削れそうだけど
最近のg++なら<tr1/regex>もあるけど
いまどきBCCがどうとか言っている時点で一般的なアドバイスは無意味だよな。
VC9EEでprintfにあるひとつのクラスインスタンスの関数の返却値を表示させようとして、食わせてたら、 なんか、関数呼び出し順がソースで見て左から呼ぶのかと思ったら、右から呼び出してて、値がおかしくてハマッた。 規格だと関数の引数としての実行順番って規定されてないんだっけ?? それとも64bit整数使うと挙動変わったりする?まったく64bit整数使わないから挙動が解らん。 以下のような感じ。 printf("%u %u %.2lf\n",R(),R.Last(),R.LastDouble()); Rは乱数クラスでオペレータ()を呼び出している。クジも引いてる。 Last()は最後に引いたuint32を返却。 LastDouble()はLast()をdoubleに正規化して返却。 わけわからん。。。
不定だよ
「不定」ではないだろw
順序がね
107 :
103 :2009/12/02(水) 19:47:43
不定ではないな。 コンパイラで適宜に決められてはいる。
109 :
デフォルトの名無しさん :2009/12/03(木) 01:45:08
あるWindowsアプリケーションのプラグインを作成しており、 そのプラグインの内部データを監視・変更するためにGUIを付けたいと思っております。 本体からDLL関数が呼ばれたときにダイアログを生成し、 また呼ばれたときは本体に影響しないようすぐリターンを返したいのですが、 モーダルはダイアログを閉じるまで制御が返ってこないし、 モードレスでも結局ウィンドウメッセージは処理しなければならないので すぐに返せないのではないのではないかと思いますが、 この場合スレッドを別に立ち上げなければならないのでしょうか。
普通にモードレスでいいだろ。
111 :
109 :2009/12/03(木) 07:49:29
ええと、その場合作ったダイアログのメッセージループはどうなるのでしょうか。 DLL関数の中で延々メッセージループを回されたら本体側が困ると思うのですが。
スレッド使えば?
>>111 モーダルは自分でメッセージループ持ってる
モードレスは本体のと共用
int *p; p=malloc(1); *p=10; と int x=10; は同じような機能と考えていいの?
>>114 いいえ、原則的に前者は確保した領域の解放が必要になります。
また、最適化が阻害されるので後者に較べて不利なコードになる可能性が考えられます。
1バイトじゃ駄目だろ。
まぁ動くだろうけど、ダメだね。
int *p; p=(int*)malloc(sizeof(int)); // ヒープ領域にメモリを確保する *p=10; free(p) // ヒープ領域は明示的に解放してあげないとだめ int x=10; // スタック領域にメモリを確保する // スタック領域は関数を抜けると自動的に解放される ヒープ領域・スタック領域はggr
キャストすんなうぜえ
C++ならキャスト必須だが、そもそもC++ならmallocも使わないか
VC++ 2008 Express EditionでC言語で開発を行ってます。 デバッグ方法について質問します。 普段デバッグを行う際には、プログラムを止めたい場所でF9でブレークポイントを張った後、デバッグをしているのですが 以下のようなメモリ破壊を起こすようなバグを取り除く際にいつも苦労しています。 プログラムのどこかでメモリ破壊が起こる<-問題個所 該当個所を呼び出そうとした際にプログラムが停止する<-エラーが発覚してプログラムが止まる場所 「どこが破壊されているのかは分かるけど、どのタイミングで破壊されたのかが分からない」という状況です。 これまでは、プログラムが止まった場所から少しずつ前の処理でブレークポイントを張り続けて、該当箇所のメモリ破壊がいつ起こってるのかを突き止めているのですが こういうタイプの不具合に対応するために、 「指定したメモリ領域に変更が起こったらプログラムを止める」 ということができればもっと楽なのに・・・ なんてふと思ったのですが、VC++の機能として該当するような機能はないでしょうか?
>>121 止まった場所がライブラリの中ではなくライブラリを呼んだ自分のコードで起きた場所が知りたいなら、
スタックトレースウインドウがあるのでそれでさかのぼる。
条件ブレークもあるみたいだがつかったことねー。。。orz
>>122 ご返答ありがとうございます。
スタックトレースウインドウって言うのは「呼び出し履歴」ってタブのウィンドウのことでいいですか?
「呼び出し履歴」のことだとすると、今回のケースでは、関数の引数がポインタで、処理しようとしているアドレス自体は正しいけど、アドレス先のデータが破壊されている
という状況なので、呼び出し履歴を見ながら変数を追うという方法がとれなくて・・・orz
いつもだと、エラーが起こる前に通る場所にブレークポイントを張りまくって、該当のアドレスに変更がかかったタイミングを突き止めるということをやってるのですが
破壊されるアドレスを指定して、そこに変化がかかったら(これがいわゆる条件ブレーク?)みたいなことができたら楽だな〜と^^;
debug_all()って関数を適当に作って、全ての関数の頭に追加して、問題が発生しないことが分かっているところで
global_debug = チェックしたいデータのアドレス;
って打ってあげれば、どの時点でデータ破壊が起こったのか分かるのかな〜と思ってやろうとしたのですが、開発環境レベルでこんな機能があったらいいのにと思いまして^^;
void* global_check_address;
void debug_all(){
static int before;
if( (int*)global_check_address != before )
{
printf("error\n"); /* ここにブレークポイントを張る */
}
before = (int*)global_check_address;
}
hoge()
{
#ifdef _DEBUG
debug_all();
#endif
・・・
}
ところで、お前らは何で開発してますか? オイラの環境 os:gentoo linux ide:netbeans 6.7
>>123 そう、呼び出し履歴であってると思う。
で、俺も不明瞭だから、条件ブレークをテストしてみた。
IDEにブレークポイントウインドウがあるんだが、
F9でブレークポイントを貼ると、そのウインドウのリストに載るのでそれを改変。
方法は対象のリストを右クリックして、条件というメニューから条件を書き込む。
trueの場合だと、たとえばi==jなどのブーリアンになるように設定する。
変更されたら。の場合だと、変数名をそこに書き込んでダイアログを閉じる。
あと、ブレークポイントの貼る位置は、値を評価したり変更したりする次の行。
以下のコードを使った。初めて触ったけど何とかなったから大丈夫だと思う。
#include <stdio.h>
int function(int& i){
int k=0;
k=i;
i++;//この行にブレークをはって、条件をkが変更されたら。にする。
printf("%d",k);
return i;
}
int main(){
int i=10;
for(int j=0;j<i;j++){
if(j%2) function(i);
printf("%d\n",j);
}
return 0;
}
>>124 俺は
Win7Home 64bit & VC9EE
でも、64ビットな事はやったことない。。。
ここでいいのかちょっと怪しいけど・・・ レゴのMindstorm・・・nxcに関する質問ってどこですればいいですかね
>>124 おまえ犬糞なんて使ってんのかよ
ギャハハ
本当にくだらない質問なんですけど [hogehoge]================> [ 73%] みたいな表示を標準入出力ライブラリ関数だけでやってみたいと思うのですがどうしたらよいでしょうか?
どのレベルでわからないのかがわからないな。 iostreamの存在自体を知らない(いまこのレスで初めてこの言葉を見た)とか、 そういう段階の質問?
プログレスバーを作りたいってことなんだろう。 ヒントとしては、 printf("[hogehoge]=> [%2d%%]\r", percent); printf("[hogehoge]==> [%2d%%]\r", percent); というかんじ。\r がポイント。画面の横幅は標準では扱えないから80固 定でいいだろう。
それだと改行されるからダメだな 昔のLHA風に.....が増えていくなら簡単だが
基本的に1ラインだけは可能だよなぁ。マルチラインは標準では無理。
改行されねえよボケ どんな特殊環境を使ってやがんだよカス
>>125 おおおおできた!!これは便利だw
ありがとうございました^^
>>135 つたない説明で申し訳ないね。
お役に立てて何より。
137 :
デフォルトの名無しさん :2009/12/04(金) 03:50:06
質問させてください。 環境は、VC++2008 XPです。 エラーではなくワーニングが出ています。 warning LNK4006 Hoge<struct Matrix>::hoge(struct Matrix const &) はHOGE.obj で定義されています。2 つ目以降の定義は無視されます。 といった内容です。 エラー個所のソースは template<class T> class Hoge { public: void hoge(const T &test); }; template<class T> void Hoge<T>::hoge(const T &test) {} template<> void Hoge<Matrix>::hoge(const Matrix &test) {} といった具合です。 クラスのメンバ関数をオーバーロードして、Matrixクラスが引数に来た時だけ 処理の内容を変えようとしているのですが、上手くいきません。 ご教授ください。 よろしくお願いします。
138 :
137 :2009/12/04(金) 04:19:34
一応コンパイルは通るようになりました。 原因は、(当たり前かもしれませんが)テンプレートでクラスTを取っているのに そのTを使わないことでのオーバーロードを行うことはできないということでしょうか。 違っていればやり方を教えてください。 解決したやり方は ・クラステンプレートの特殊化としてMatrix用のテンプレートクラスを作成 ・テンプレートクラスの記述を全てクラス内部に入れ込み、インラインとした という方法です。
>ワーニング
classの宣言内で、 class c { std::string s; std::tr1::function f; などとスコープ演算子を付けまくるのがとっても面倒なんですが、 大抵の宣言はヘッダに書くのでusingするわけにも行かず、 class c { namespace std { string s; } とか class c { namespace tr1 = std::tr1; tr1::function という書き方がしたいところなんですが、何とかなりませんか? 或いは代替案がないものでしょうか?
>>140 using std::string;
using std::tr1::function;
取り敢えずこうしてみた namespace class_local { using namespace std; class hoge { string s; }; } typedef class_local::hoge hoge; 何かもっと良い方法があったらお願いします。
>>142 じゃぁ typedef で。
>>143 それでいいなら using declaration のほうがおすすめ。
using directive は影響が大きすぎるし危険でもある。
>>144 using declarationってusing std::stringみたいな書き方ですよね?
typedef でも using declaration でもそもそもの目的のタイプ量を
減らす効果が薄いかなぁ。
using directive は影響が大きすぎるから、>143の例では
namespaceで囲ってスコープ外にusingが漏れないようにした訳です。
これだけ悩むんならおとなしくタイプしてしまったほうがマシ、っていうのが一般解じゃないかね。
マっぽくない解答だなぁそれ
あーだこーだ言っても結局クラス内typedefに落ち着くと思う
usingだと
>>143 みたいに無理やり感のある方法をとらないといけないし、衝突するかもしれない
2回以上使うならtypedefでタイプ量は確実に減るし
OpenMPを用いたプログラムを作成しようと VC++ 2008 Express Edition と Windows SDK for Windows Server 2008 and .NET Framework 3.5 を導入しました 試しに、 #include <stdio.h> #include <omp.h> int main() { #pragma omp parallel { printf("hello\n"); } } というプログラムのビルドを行い成功したのですが exe実行時に「このアプリケーションの構成が正しくないため、アプリケーションの開始に失敗しました。 マニフェストファイルを参照して原因を調べてください。...」とエラーが出てしまいます Dependency Walker を使い赤字のDLLは一つずつ潰していったのですが解決しません どうかご助力お願いします
150 :
149 :2009/12/07(月) 19:12:08
すみません、とりあえずリリースモードで動きました 何が解決に繋がったかわかりません 相変わらずデバックモードでは動きませんが、これはインストールした環境ではデバック版のライブラリがないためのようです スレ汚し失礼しました
初めてLinuxサーバ向けにプログラムを作ることになりました が、導入以前に疑問が。 初歩的な質問で恐縮なのですが、Linuxでは、gcc等でコンパイルされた実行ファイルは、 コンパイル環境に左右されず、どのディストリビューションやバージョンでも実行できるのでしょうか?
CPU違うと無理。 それどころかディストリやバージョン違いでも 不具合が出る可能性有り。 ソースレベルでなら大抵は互換してるけどな。
>>152 ありがとうございます。大変参考になりました。
>>150 デバッグ用のmsvcrtは配布されてないから、デバッグビルドは開発環境のないところで動かないよ
学校で「gcc ○○.c -o □□.exe」と入力してコンパイルする方法を教わったのですが、 家のパソコンで同じようにやってみてもエラーが出て出来ません。 「'gcc'は内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。」 ↑こういうメッセージが出ます。どうすればよいでしょうか? OSはどちらもVistaです。
そりゃgccがインストールされてないんだろうよ。
残念!あなたのPCにはGCCがインストールされていない!
Windowsでgccを使いたかったらcygwinかmingwをインストールして下さい
SFU にしろよ。
BCC5.5は?
>>160 ADLとテンプレート周りが腐ってるからだめだ
TCC1.01 は?
テンプレートがない(確か) 例外処理もないんじゃなかったか? それに16bit専用だったと思うが
じゃあ LCC-Win32 は?
DOS時代のコンパイラってだけ
javaの場合staticなメソッドはインスタンスから独立しているため、一般的な作業に使われています C++のstaticなメソッドもjavaと同じような感覚でいいのでしょうか?
イエス。そのクラスの名前空間に入っているだけの関数と考えてもらって差し支えないです。
まあでも本当に一般的な作業なら、クラスのメンバにしないけどな。
>>170 staticしか持ってない管理クラスで一般的な作業させてるんだけど、おかしいか?
JavaやC#では単なるメソッド集みたいなクラスがどうしてもできるけど、C++ではそういう 関数はグローバル関数にするのが一般的。 グローバル関数で実現可能なことは、わざわざメンバ関数にしない方が安全だ。
>グローバル関数で実現可能なことは、わざわざメンバ関数にしない方が安全だ。 安全っていうと、どう違うん? 実質グローバルと変わらないと認識してたんだけど・・・。
EffectiveC++の受け売りなんだが、グローバル関数のほうが強くprivateメンバを隠蔽出来る。 privateなデータメンバにアクセスできるものは極力減らした方が、安全性や保守性が高まる。 friendでないグローバル関数ならprivateメンバにアクセスできないことは自明なので、 privateメンバに手を加えるとき、考慮しなくてすむよね。
単なる関数集クラスがあってもいいとは思うけど、それにメンバ変数を追加しだしたら赤信号。
メンバ関数が静的なのか非静的なのか はっきりしてほしいところ Monostateパターンなのかどうなのかも はっきりしてほしいところ そこらへんが曖昧だから話が噛み合わない
>>171 それは通常namespaceを使うんじゃないだろうか
関数を実装するのに使うけど外に晒したくない関数が欲しいときはクラス化してstaticメンバにするかな class make { public: template<class xxx> static std::tr1::shared_ptr<xxx> shared(void) { return std::tr1::shared_ptr<xxx>(create<xxx>(), destroy<xxx>); } private: template<class xxx> static xxx *create (void) { std::cout << "create" << std::endl; return new xxx; } template<class xxx> static void destroy (xxx *ptr) { std::cout << "destroy" << std::endl; delete ptr; } }; いい例がぱっと思いつかんけどこんなのとか あとはてんぷらプログラミングとかやろうとすると、グローバルじゃなくてクラスメンバのほうが使い易い 既存のクラスにstaticを継ぎ足し継ぎ足しするのは危険だけどそうじゃなきゃグローバルよりできることは多いと思う
みなさんは、演算子のオーバーロードについてどう思いますか?
>>179 あって助かってる。
が、意味不明なオーバーロードされてると殺意を抱く。
182 :
デフォルトの名無しさん :2009/12/12(土) 03:03:38
ベクトル計算とかマトリクス計算とか便利すぎて死ねる
reinterpret_cast< unsigned int >("hoge") これの結果は環境によって変わったりしますか?
する
>>183 実行するごとに変わったり変わらなかったり。
つーか、いわゆるユーザー定義型的なクラスを作る時には、演算子オーバーロードは 必須だよな スマポやイテレータなんか、演算子オーバーロード無かったら糞以下だろう そういう振る舞いを求められてないクラスで面白がって使う演算子オーバーロードは ほとんどが害悪だけど
STLのアルゴリズムを適用しやすいように比較演算子を定義したりとか。
組み込み型を擬態するためにとかならいいけど、演算子は必要最低限にしとかないと意味が分かりづらい糞コードになる
演算子を本来の意味とは全く違う用途、 例えば << や >> を streamとの入出力に使うとかって、最低だよな。 いやマジで。
だがboost::formatは正直便利だ
>>189 はきっと Boost.Xpressive で頭痛がして
Boost.Spirit で発狂した経験がある。
シーケンシャルな演算子で丁度いいのがそれしか選択肢が無い
>>183 それは要するに "hoge" という文字列の置かれたアドレスの一部あるいは全部を
unsigned int として返す、という式になるけど、処理系によってメモリの使い方が
ことなるから、当然定数のアドレスも異なる。
コードを書き換えてコンパイルし直せば、定数の配置も変わりうるからアドレスも変わりうる。
また、Windows や Linux では(バージョンやディストリビューションや設定によって変わるが)
ヒープやスタックの位置をランダムに変えているので、プロセスの起動ごとに変数や定数の
アドレスが変わるが、Mac OS X はそういうことはしていないので起動ごとにアドレスが
変わったりはしない。
194 :
デフォルトの名無しさん :2009/12/12(土) 20:55:27
typedef struct _TAG_ELEMENT { struct _TAG_ELEMENT *next; char str[ 256 ]; } ELEMENT; 上の構造体を使って、線形リスト?を作りました。 で、strcmp()の仕様にのっとり、昇順にソートをしようとしたのですが、うまくいきません。 いったいどうしたらいいのでしょうか?
>>194 どんなコードを書いて、どう上手くいかなかったの?
CALLBACKって何のためにつけてるんですか? 関数ポインタに渡すときはつけないとダメなんでしょうか?
何のため・・・難しいことを訊く MS様がここはCALLBACKだとお決めになられた箇所には、CALLBACKを付ける MS様がルールで、俺たち平民はそれに従うのみよ 関数ポインタならなんでも付けるわけじゃなくて、CALLBACK規約の関数ポインタの場合だけ付ける まぁ呼び出し規約でぐぐってくれ
>>197 それは呼出規約というものを指定しているんだ。
呼出規約というのは、関数の呼び出し方と値の戻し方を機械語レベルで規定したもので、
それが異なるとCのソースレベルでは同じに見える関数でも機械語レベルでは別物に
なってしまい、呼び出すことが出来なくなる。
LinuxやMaxのアプリだとCALLBACKみたいなのは無いの?
>>197 関数の呼び方にstdcallとpascalって二つあって、CALLBACKはその
どちらかに設定されてるんじゃないの?
>>200 あるよ。というか、もともと呼出規約なんてものは処理系ごとに異なっているものだ。
さすがにそれじゃあ開発に支障をきたすので、ある程度規格化されているけど。
>>200 もちろん呼び出し規約を指定することは出来るけど、わざわざ指定するような例は見たことないな・・
>>197 誰も書かないので書いとくが、引数をスタックに積む順番が変わる。
関数呼び出しのエンディアンみたいなもんだね。
いや、レジスタだけで渡したりとか色々ある VCのnaked規約なんかに至っては、スタックフレームの生成もret命令もてめーで書け、 という潔さ
nakedは割り込みハンドラをCのインラインアセンブリで書くときに使うかなぁ gccだと__attribute__((naked))
あぁ〜、objectみたな神様クラスがあれば楽なのに
208 :
デフォルトの名無しさん :2009/12/16(水) 22:56:57
C++じゃなくてCなんですが、 可変の3次元配列を利用したい場合はどうしたらよいですか。 たとえば、int arrray[x_max][y_max][z_max]の3次元配列を使いたい場合、 1.十分大きな配列を確保して、array[i][j][k]とアクセス 2.array = malloc(sizeof(int) * x_max * y_max * z_max)とし、 array[ (i*y_max + j)*z_max + k] でアクセスする。 の方法を考えたんですが、他に良い手法はありますでしょうか。
int ***a; としてループでmallocしまくる 遅いからおすすめはしないが
(゚Д゚≡゚Д゚)
>>208 標準Cなら俺の知る限りその2つの方法しかない。
しかし、1は容易にスタックオーバーフローを引き起こすのでお勧めできない。
int a[10][10][10]くらいですむならいいけどね。
213 :
212 :2009/12/17(木) 00:43:56
すまん、そういえばalloca()もあるね。 でも1と同じでスタックオーバーフローに繋がるから、お勧めはできない。
>208 3.int (*p)[Y][Z] = malloc(sizeof(int) * x_max * y_max * z_max) とすればp[0][1][2]でアクセスできるよ。 ただしY, Zは固定。 Y,Zも可変にしたければ>209の方法しかない。
215 :
208 :2009/12/17(木) 14:23:43
>>211 すみません、説明不足でしたね。
例えば、プログラム中で設定ファイルを読み込んだり、
途中で入力した数をx_max,y_max,z_maxに代入して、
arrray[x_max][y_max][z_max] を使いたいと言う事です。
>>209-214 結局は、可変な3数を使う配列を使いたい場合、
2.が良いと言う事ですね。
そうやって作ってみようと思います。
皆さんどうもありがとうございました。
216 :
デフォルトの名無しさん :2009/12/17(木) 17:12:13
すみません初心者です。 1,・・・,100の整数から10個の整数を 非復元抽出でランダムで取り出すプログラムを教えてください。
1~100の数字入れた配列つくってランダムに並び替えして前から10個取り出すとかわ?まぁ俺も初心者だからわからんけど
初心者歓迎のスレだが初心者が回答をしていいとは言っていない
219 :
デフォルトの名無しさん :2009/12/17(木) 17:41:06
文系の大学生で一般教養科目のC言語を履修しています。 途中の課題のソースファイルを自宅に持ち帰ったのですが、 学内のLinuxで見た時には一つだったのにWinでひらくと「Cファイル」と「C〜ファイル」の二つになっていました。 ワードパットで編集できるみたいですが、この場合両方に同じ編集を施して、 両方をファイルサーバーにコピーすると1つのファイルに戻ったりするのでしょうか? いきなりファイルが増えて混乱してます。 よろしくお願いします。
>>219 ~がついているほうはエディタのバックアップファイルだと思う。
おそらくそっちは削除して、.cファイルだけ編集して書き戻せば平気。
221 :
デフォルトの名無しさん :2009/12/17(木) 18:02:54
>>220 ホント助かりました!
ありがとうございます!
課題系が増える季節か
Test *t; Test *t = new Test(); この2つは何が違うんですか?どっちも、自動で破棄されない点は同じですが Test *t;はdelete t;をしても、デストラクタを実行してくれない
>>223 前者はTest型へのポインタ、つまり「Test型のインスタンスのアドレス値の置き場」を
作っただけで、Test型のインスタンスを作っていません。
従って、デストラクタも実行されません。生まれていない生物が死ぬことはできないので。
225 :
223 :2009/12/17(木) 22:13:57
>>224 なるほど、ありがとうございます。
Test *t();は単純に「Test t(); + ポインタ」だと思っていました
いや Test *t(); は、 「Test *を返すtという名前の関数の宣言」であって Test *t; とは全く別物だし。
>>216 int a[100], i, j;
for (i = 0; i < 100; i[a] = i + 1, i++);
for (i = 0; i < 100; i++)
{
j = (int)((rand() / (RAND_MAX + 1.0)) * 100);
j[a] != -1 ? printf("%d\n", j[a]), j[a] = -1 : i--;
}
なんという嘘だ
>>216 int main()
{
static int const range = 100;
static int const num_samples = 10;
int source[range];
for (int i = 0; i < range; ++i) { source[i] = 1 + i; }
srand(time(0));
assert(num_samples <= range);
for (int done = 0; done < num_samples; ++done)
{
int const num_remains = range - done;
int const x = (int)((rand() / (RAND_MAX + 1.0)) * num_remains);
printf("%d\n", source[x]);
source[x] = source[num_remains - 1];
}
return 0;
}
Visual C++つかってるんだけど include <stdio.h>が普通に通るけど stdio.hってファイルだよね?なんでこれでコンパイルが通る? C:\Windows\System.なんとか.h みたいに直接書かなくても良いのはなぜ?あとstdio.hの本体はどこにある?
環境変数 INCLUDE でパスが指定されてるから。 #include <c:\\vc\\include\\stdio.h> #include </vc/include/stdio.h> のように絶対パスで指定することもできる。 ちなみに、 #include "stdio.h" "" で囲むと先にカレントディレクトリから探してくれる。 で、無ければ INCLUDE で指定したパスから。
>>230 ツール→オプション→プロジェクトおよびソリューション→V++ディレクトリ
あ、Cが抜けた。最後は「VC++ディレクトリ」ね。 ここでインクルードファイルやらライブラリやらのパス設定を管理できる。
環境変数だね。
235 :
デフォルトの名無しさん :2009/12/18(金) 09:02:17
答えられないなら書き込まなくていいですよ^^
C++です。初心者です。new がよくわかりません。 MyClass a; MyClass b = MyClass; MyClass c = MyClass(); 上記それぞれ動きます。 MyClass d = new MyClass; これはエラーがでます。なぜでしょうか。
newはアドレス返すから 入門書読み直したほうがいい
MyClass *d = new MyClass;
コンストラクタが実行される
242 :
236 :2009/12/18(金) 19:44:28
ありがとうございました。
>>238 とてもわかりやすい説明ありがとうございます。
>>239 がいけるのは知っていたのでとても納得しました。
>>240 >>236 の上3つは同じ処理です。省略したものです。
僕は new はもしかしたら省略可能で省略されているのかと思って質問したわけです。
>>236 b はコンパイルエラーになるだろ。
ほんとに動くんなら、コンパイラどれ使ってるか教えて。
MyClassがstaticとか
247 :
236 :2009/12/19(土) 17:40:58
>>243 コンパイルエラーになりました。すいませんでした。
そっちか
= 0 を見つめているとこれが形而上学的なものに思えてきて、 = 0 を見つめ続けるとやがてゲシュタルト崩壊が始まる。
=> =)
<o> <o>
:-)
純粋仮想関数のあの書き方はどこから出てきたのだろうね。 単に予約語を増やしたくなかっただけ?
>>256 関数の中身は無いってことは空値みたいなもんだよな
てことは=NULLか
どーせNULLはプリプロセッサで0になるから=0でいいや
>>256 そういうこと。
新しい予約語を入れるのが無理な状況だったから、= 0になった。
C++でDirectDrawを使って簡単なゲームを作ろうとしているのですが、 フレーム制御関数をmain関数のどこで呼び出せばいいのかわかりません while(bIdle){ if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){ // メッセージ処理 TranslateMessage(&msg); DispatchMessage(&msg); }else{ // アイドル処理実行 bIdle = mainframe_Idle( ); } } 小さい画像をブロック崩しの弾を動かす感じにしたいんですが いろんなサイトを見て回って、何度やっても画像が彗星みたいな尾を引いて その場で止まったままになってしまいます
260 :
デフォルトの名無しさん :2009/12/22(火) 12:14:52
すみません、質問なのにage忘れました
ブロック崩しなのに TranslateMessage なんかしてんじゃねえよ 意味解ってんのか?
せんせい! 変数を全部floatで宣言したら動くプログラムがdoubleにすると全部NaNになるんですが なんでですか(><)
どこでNaNになるのか探せばいいのに(><) バグ取りすればいいじゃないですか(><)
>>259 厳密じゃなくていいならタイマー使ったほうが簡単だよ。
その場合 PeekMessage じゃなく GetMessage でいい。
266 :
デフォルトの名無しさん :2009/12/24(木) 00:28:39
map<string,int>の配列を返す関数を書いたのですが map<string,int> *foo(int n){ map<string,int> data; data["a"]=0; data["b"]=1; data["c"]=2; map<string,int> re[n]; for(int i = 0; i < n; i++){ re[i] = data; } return re; } この関数のmap<string,int> re[n]の部分で警告が出てプログラムが正常に動きません。 static をつけると引数のnが使えずグローバル変数を使うことになるのですが、 グローバル変数や配列の代わりにvectorを使う以外にいい方法はないでしょうか? OSはWindows vistaでコンパイラはg++.exe (GCC) 3.4.5 (mingw-vista special r3)です。
>>266 動的配列はnewしてください。
使い終わったらdeleteもわすれずに。
new[] delete[]するくらいならvectorのほうがまし。
200〜400バイトくらいのちっちゃいメモリをmallocしまくってるんだけど やっぱダサいのかな それとも最近のmallocなら下手に自分でメモリ管理するよりは性能いいかな
>>266 とりあえずローカル変数のアドレスを返すのはやめよう
>>269 基本的にはシステム標準のmallocでいいと思うけど、
それで物足りないなら、自分でメモリ管理のコードを書く前に、
既存のメモリ管理のライブラリを試してみよう。dlmalloc、tcmalloc、jemallocとか。
>>263 ,265
scanf("%f", &hoge);
とか値を格納した時点で既にNaNなんですが/(^o^)\
>>272 double値を読み込むときは%lfだけど、そこ直した?
>>273 でキタ - .∵・(゚∀゚)・∵. - ッ!!
ありがとうございました(´;ω;`)ウッ…
すげぇうれしそうだな
ワシも初めの頃はよく間違えてた。
というか、scanfをめったに使わないから、たまにテストプログラムで使うとき迷う。
VCの各Verで構造体アライメントの規定値をコンパイル時に確認できるディレクティブ等ってありますか?
ビットについて教えてください。 メモリでMbitと見るんですが 例えば32Mbitと書かれてあったらwikiだと 1,048,576(bit)×32=33,554,432で 16進数だと0x2000000になる計算でいいのでしょうか? よろしくお願いします。
メモリは大抵MiBじゃないっけ
MiV?
質問させてください。 void AAA::AAA(){ 内にある命令を、一定時間間隔で繰り返し実行したいのですが、どういった方法があるでしょう。 一応自分で考えたのは、 int repeat=0; if( repeat <= 繰り返し回数) { 命令 Sleep(待ち時間) ; repeat++; } なのですが、これだとなぜか全体の速度が遅くなってしまいました。 環境はWindows、Bolrand C++です。DXライブラリも使用しています。 なのでSleepの代わりにWeitTimerも試したのですが、結果は同じでした。 SetTimerも考えたのですが、どこに置いていいかわからず…。 (サンプルの改変のため、.hも.cppもいくつかある状態です)
multithred
>>282 FPS(frames per second)について勉強しよう
>>282 そのAAA()が頻繁に呼ばれてるなら、clock()とかgetTickCount()みたいな
関数で、前回呼ばれた時間を記録しておいて、前回の呼ばれた時刻から
一定以上の間隔が開いていたら処理を実行するって方式にすればいい。
287 :
284 :2009/12/26(土) 13:33:25
>>282 その方式でやりたいなら、マルチスレッド使わないと駄目だな。
んで、多分お前さんには無理だ。
解決法は上の方の人が言ってるから参考にしれ。
このAAA自体が繰り返し呼ばれているので、その中で一部の命令だけを
指定時間ごとに実行するようにしたかったんですが・・・。
現在はこの中の命令が連続で実行されている状態です。
printfを使っているとしたら無数に文字が出てきている状態です。
>>286 よりGetNowCountを使う方法を考えたのですが、
1000をかけて4などで割って余りが0のとき実行、はうまくいきませんでした。
試しにランダム(10)でif X=3になったときだけ実行をしたら無数に出てくる状態のままでした。
なので、命令自体が繰りかえし呼ばれているのでifでいいかなと思ったのですが…
>>290 ググってみたら、GetNowCount()ってミリ秒単位の関数みたいだけど、
1000を掛けるって?
>>290 void AAA::AAA()
{
static unsigned lastCount = 0;
unsigned now = GetNowCount();
if (now - lastCount <= 1000)
return;
lastCount = now;
// 処理
}
こういう感じで、一秒感覚で動くと思う。
>>290 >286 をやってみるなら前回実行からの時間を見ろよ。
暇だからコード書いてみた。
>>290 はこんな感じでいいのか?
#include <stdio.h>
#include <time.h>
bool CycleTimer(clock_t Interval){
static clock_t LastClock=0;//これがボトルネック
clock_t Now =clock();
if((LastClock+Interval)-Now <= 0){
LastClock = Now;
return true;
}
return false;
}
int main(){
int i=0;
while(i<60){
if(CycleTimer(1000)){
i++;
printf("A");
}
}
return 0;
}
WinMain { int count = 0; while() { if(count < 60) { 繰り返したい処理 ++count; } DXライブラリ固有の処理、FPSに関する処理 } } こんな感じの処理で済む話じゃないのか?
297 :
296 :2009/12/26(土) 15:33:24
更新してなくてちょいかぶったorz
DXライブラリでやってるなら、アレは描画すると強制的に60FPSに補正されるから、 もうフレームでいいんじゃね。
299 :
295 :2009/12/26(土) 15:36:15
今学習に使っているのは14歳から始めるC++ゲームプログラミングで、
現在サンプルを触ってみている状態です。
void TekiControl::move(float jx, float jy){
list<CharaData>::iterator it;
it = tekilist.begin();
(*it).anim->draw(0, (*it).x, (*it).y);
//子機発射処理 ※この部分を指定秒数ごとに実行したい
float dy = GameFrame::IdouHosei(8);
podsally( (*it).x+64, (*it).y+32, 20, 0,-dy);
podsally( (*it).x+64, (*it).y+32, 10, 0,-dy);
podsally( (*it).x+64, (*it).y+32, 20, 0,dy);
podsally( (*it).x+64, (*it).y+32, 10, 0,dy);
podmove(jx,jy); //子機移動
}
上スレのほうが適切でしたら移動します。
これはteki.cpp内で、
main.cppでTekiControl tekicnt;で宣言した後、tekicnt.move(jikicnt.getx(), jikicnt.gety());で呼び出しています。
(なぜintなどではなくTekiControlで宣言できているのかは実はわかっていません)
>>291 ミリ秒なんで1000をかけたら秒になって、適当な数で割って余りが0ならそのタイミングにならないかな?
と考えたのですが、もしかしたら考え方自体が間違っているかもしれません。
>>300 >ミリ秒なんで1000をかけたら秒になって、
秒単位にしたいなら割らないと。
>>300 WinMain
{
bool koki_hassha_chuu = false;
int frame_count = 0;
int koki_count = 0;
while()
{
if(!koki_hassha_chuu && 子機発射の条件) {
koki_hassha_chuu = true;
}
if(koki_hassha_chuu) {
++frame_count;
if(frame_count >= 子機発射間隔) {
frame_count = 0;
子機発射処理
++koki_count;
if(koki_count >= 子機発射最大数) {
koki_hassha_chuu = false;
koki_count = 0;
}
}
}
DXライブラリ固有の処理、FPSに関する処理
}
}
敵コントロールクラスの内部にゲームループを作るのはNG
>>296 int count = 0;
while(){
if(count<60){
float dy = GameFrame::IdouHosei(8);
//podsally( (*it).x+64, (*it).y+32, 20, 0,-dy);
//podsally( (*it).x+64, (*it).y+32, 10, 0,-dy);
podsally( (*it).x+64, (*it).y+32, 20, 0,dy);
podsally( (*it).x+64, (*it).y+32, 10, 0,dy);
//lastCount = now;
++count;
}
}
このような形でしょうか?
(whileには{が必要だったかと思ったので、勝手に足してしまいました。もし間違っていたら申し訳ありません。)
ただ、これだとwhileに)がないというエラーが出るので…
(1)で常に真にすると無限ループになるのか、固まってしまうので。
>>302 ごめんなさい、これがどの部分を指すのかわかりません。
>>298 DXライブラリ公式サイトの落ちものゲームの時間処理を参考に作ってみたのですが、
void TekiControl::move(float jx, float jy){ 内に
最初にWAITを宣言して、
int WaitCounter ; // 下に勝手に落とすまでの時間計測用
int NowTime ; // 現在のフレームで経過した時間
int OldTime ; // 前のフレームのときにGetNowCount関数で得たタイム
// 時間関係処理
//int TimeFunc(){
int Time ;
// 現在の時間を得る
Time = GetNowCount() ;
// 今フレームで経過した時間を得る
NowTime = Time - OldTime ;
// 現在の時間を保存
OldTime = Time ;
// ウエイトカウンタに経過時間を加算する
WaitCounter += NowTime ;
// 一定時間が経過していたら勝手に下にブロックを落す
if( WaitCounter > WAIT )
{
// float dy 〜の処理
// カウンターを0に戻す
WaitCounter = 0 ;
}
// 終了
return 0;
値を返せないと言われてしまいました。
この部分を削ると以前の状態に戻ってしまいます。
>>304 TekiControl::move の子機発射処理のところ だけ を
>302の子機発射処理のところに持ってくる
てか内容を理解せずにコピペするだけじゃ
まともなプログラムは書けないぞ
>>305 >>302 自体をどこに持ってくるべきかが分からないんです。ごめんなさい。
TekiControl::move内でいいんですか、それともこのcpp内の別の場所ですか?
なんとなくは理解しているつもりで自分なりに必要そうなところ、たぶんこれが動いているのではと思われるところを
抜いて使っているのですが、よくわかっていなくてすみません。
ここまで当たってみて、次何をしてみたらいいのかが分からないです。
いやもうDXライブラリすれ池よ C++の知識とゲーム作成の知識もなさすぎ もうちょっと勉強しろ
>>307 すみません、移動します。
本は一通り読んだつもりなのですが、この場合にあと調べるべきだったことは何でしょう。
ここから何を勉強したらできるようになるんでしょうか。
ごめんなさい。
FPSの概念と、リフレッシュレートあたりをググって理解しとけ。
まぁこういうスレタイなんだし、せめて若干優しげに誘導してやれw
自分には甘く初心者には厳しい
関数が実際にinline展開されたか調べる方法ってありますか? コンパイラは学校でGCCと自宅でVC++EE2008を使ってます
>>312 いつ調べるの?
まさかコンパイル時に調べるとかじゃないよね?
>>312 実際のアセンブリ比較以外ではなかなか難しいと思うが。
コンパイラさんが勝手にやったりするからね。
>>313 コンパイル時にメッセージとか出してくれたらいいなーとか思ってたんですが・・・
>>314 アセンブリですか
そこまで知識がないので今の自分には無理みたいですね
勉強してきます
即レスサンクスでした
いや簡単だから
>>312 ソース吐き出すオプション付けて出してみればいいじゃん
gccはアセンブリソースに元のソースがコメントで付かなかった
かもしれないが
gdbで見ればいいじゃんと思って試してみたがうまいこと展開されない もしかして-gオプションつけてると淫乱展開されない?
-O0だと-finline-functionsつけてもインライン展開しないんだな。 思わぬところで勉強になったぜ・・・
インライン展開させたい関数にstaticがついてないと、 関数その物は別に存在しちゃうんだな。 思わぬところで勉強になったぜ・・・
>>320 逆だろ。
static つけてヘッダで定義してたらインクルードするたびに別物になってしまう。
>>320 そいつがリンクされてプログラムに含まれるのは、アドレス取ったりしたときだけじゃないか?
>>322 プログラムの中にコードだけはある状態だった。
-gつけてたからかもしれんけど
inline int unko(int a, int b){ return a+b; }
main(int argc, char **argv)
{
int a=atoi(argv[1]);
int b=atoi(argv[2]);
int c=unko(a,b);
printf("%d+%d=%d\n",a,b,c);
}
これでunko()のコードがmain()でインライン展開されて、かつ、
unko()のコードがプログラム内に存在してた。
(ブレーク張ってももちろん止まらない)
なんか勉強のネタが増えてしまった。
>>321 そうならないように規格が追加されたんじゃなかったっけ
>>317 > gccはアセンブリソースに元のソースがコメントで付かなかった
-Wa,-adlh
>>325 そうなの?
俺は
>>321 と同じ考えだった。
とりあえずboostを見てみたけど、inline宣言された関数は沢山あるが
それらの中でstaticに宣言されている物はぱっといくつか見渡した限りは1つも無かったよ。
boostは広範に対応しなきゃならないライブラリだから、どのコンパイラでも通りやすい 書き方を選ぶだろ普通に
329 :
デフォルトの名無しさん :2009/12/27(日) 16:07:01
>>328 ああそういう要素もあるのか。
・・・実際はどうなんだろうねぇ?
> 320 名前:デフォルトの名無しさん[sage] 投稿日:2009/12/27(日) 01:23:34
> インライン展開させたい関数にstaticがついてないと、
> 関数その物は別に存在しちゃうんだな。
> 思わぬところで勉強になったぜ・・・
>
> 321 名前:デフォルトの名無しさん[sage] 投稿日:2009/12/27(日) 01:26:16
>
>>320 > 逆だろ。
> static つけてヘッダで定義してたらインクルードするたびに別物になってしまう。
>
> 322 名前:デフォルトの名無しさん[sage] 投稿日:2009/12/27(日) 01:27:54
>
>>320 > そいつがリンクされてプログラムに含まれるのは、アドレス取ったりしたときだけじゃないか?
>
> 325 名前:デフォルトの名無しさん[sage] 投稿日:2009/12/27(日) 02:38:27
>
>>321 > そうならないように規格が追加されたんじゃなかったっけ
だれか有識者plz
>>329 >321 の言っていることは正しい。
ヘッダで定義する関数に static を付けて内部リンケージにしてはいけない。
具体的には、別の inline 関数から呼び出された場合に ODR 違反となってしまう。
しかし >320 の言っていることも、特定のコンパイラで実験した結果として間違いではない
だろうし、そういう結果を生成するコンパイラの実装が許されないわけじゃない。
具体的には >322 の言うような場合への対応として非 inline な関数のコード生成が必要に
なることは考えられる。
>325 が何のことを言っているのかはわからない。
>>320 インライン関数がインライン展開されない場合はそうなってリンクでエラーになるCコンパイラは実在する。だけどC++コンパイラではお目にかかったことはないな。
>>331 gcc4.3.4で実験したんだけど、実在したよ
static宣言してないんだから、 あっちこっちで同じ名前の関数が出来れば、そうなるでしょ
でも俺も見たことないよ。 どんな特殊なソース?
Cのinlineにstaticが必要だとしてもコンパイラ独自拡張だからでいいとしても、C++でinlineにstaticつけないといけないのは変でしょう。 C++でインライン展開ができなかった場合やオプションで抑制した場合は、リンクでぶつからない用に細工した名前の関数が翻訳単位ごとに作られるコンパイラもあるようだよ。どうやら無名名前空間のような手法みたいだけど。
大元の質問に対してはアセンブリで見なくても、 mapファイル吐かせて関数の存在を確認するだけでいいじゃんと思ったのだが 思っただけで調べてはいないんだがinline展開されても名前は残るのかな?
inlineつきの関数でも内部リンケージじゃないと公開用に関数を生成するコンパイラもある。
>339の場合、インライン展開されたコードと展開されないコードが両方あるってことだね。
結局
>>332 を再現できないんだが。
頼むから再現するソースをうpしてくれ。
342 :
デフォルトの名無しさん :2009/12/29(火) 14:11:49
GCCのラムダ式が使える最新バージョンをMINGWにインストールするには どうやるんですか?
343 :
デフォルトの名無しさん :2009/12/29(火) 17:57:54
そのあたりにつきまして、 ヘッダで inlineに宣言した関数の中で、 static int i; の様な変数があってもよいのでしょうか? お教えください。 よろしくお願い申し上げます。
2) __inline/inline関数は他のオブジェクトファイルには含まれない。 インライン展開は、1つのコンパイル単位のコードに対して行われます。 extern関数はインライン展開されません。 関数に__inlineを指定すると、他のコンパイル単位からは呼び出せなくなります。 つまり、__inlineがC++のセマンティクスを持つため、「extern __inline」は期待したとおりに動作しない可能性があります。 C++の標準仕様では、インライン関数は、各「変換単位」で個別に定義される必要があります。 そのため、別のファイルのインライン関数とリンクすることはできません。 インライン展開された関数を複数のファイルから利用したい場合には、関数をヘッダファイル(「.h」ファイル)に置いて「extern __inline」と宣言し、この関数が必要な各ファイル内で、このヘッダファイルを「#include」を使用してインクルードします。 コンパイラが関数をインライン展開しないと決めた場合には、リンク後の関数の複製は1つだけになります。 ローカルだけで呼び出される関数(「static」)は、ヘッダファイルに配置しないでください。 これらの「static inline」関数は共有できないので、リンク後に複数の複製が存在することがあります。 ローカルだけで利用される関数に、「inline」ではなく「static inline」と指定する必要は必ずしもありませんが、コーディングスタイルとしては推奨されます。 コンパイラが別の最適化を行うことができるためです。
>344 extern inline の場合、内部の static な変数は同一のオブジェクトを参照する事が保証されている。 文字列リテラルも同じ。 14882/2003 7.1.2p4 参照。
348 :
344 :2009/12/29(火) 23:07:05
>>345-347 今まで
こういうソースを書いていたので、とても不安でした。
ありがとうございました。
>>348 動作に問題は無いが、いくつかのコンパイラでは関数ローカルな static オブジェクトを
含む場合にインライン展開が抑制されてしまう。
手元の gcc 4.3.4 で試したところ、関数ローカルな static オブジェクトを持たせた場合、
inline 展開自体は行われるものの関数の本体が出力されてしまうという結果になった。
static int i = 0; static inline int f() { return ++i; }
static inline int g() { static int j = 0; return ++j; }
int h() { return f() + g(); }
gcc -O3 -S -o - ↑ | c++filt すると、 f() のコードは出ないが g() のコードは出る。
そもそも inline の効果が本当に必要な場面なんてそんなに無い。
inline 指定がほんとうに必要なのか、たぶん考え直したほうがいい。
>>349 実際にinline化されてもされなくてもどっちでも良く、
単にヘッダに書きたいがテンプレート関数でない時にやってました。
>>350 ソースファイルが 10 個ぐらいで済んでる極小プロジェクトならかまわないけど、
いっぱいあるとか複数人で開発してるとかいうときには是非やめてください。
352 :
344 :2009/12/30(水) 00:37:38
>>351 > ヘッダで
> inlineに宣言した関数の中で、
> static int i;
> の様な変数があってもよいのでしょうか?
その例でいきますと
static inline int g() { static int j = 0; return ++j; }
でなく
inline int g() { static int j = 0; return ++j; }
です。
それでもダメでしょうか?
>>352 static は関係ない。
無意味な inline 化で実装をヘッダに晒すのをやめて欲しいという話。
くだらない変更で大量のリコンパイルを起こすようなことがないように。
C++で、短い関数はヘッダに書く人がいるんだけど 普通のことなの?
>>354 普通のことだよ。短い関数はインライン展開したほうが速いし小さくなる。
だけど、最近のコンパイラは最適化でcppに書いた関数も自動的にインライン展開される。さらに他の翻訳単位の関数までインライン展開される。
>>353 確かにくだらない変更で大量のリコンパイルを起こすってのは避けたいですねぇ。
PODのみで構成されたAを継承したBを、Aのサイズの範囲で メモリ直で操作する下のようなコードは安全でしょうか? VCでテストした限りではAの領域のみ削除されてますが。 struct A { int x; int y; }; struct B : public A { B(){}; virtual ~B(){}; void clear() { A* p = this; ZeroMemory(p, sizeof(*p)); }; } B b; b.clear();;
Bは仮想デストラクタがあるのでPODじゃ無いね。 B*をA*でアクセスするのは問題ない。ただそれと関係なくメモリ直は色々注意が必要だよ。 A* p = this; //ここで暗黙的型変換でアップキャストが行われている。一般的にこれは安全なので問題ない。
>>357 何を心配してるのかわからん。
POD だからってメモリフィルを使うのはあまりおすすめしない。普通に代入すればいいのに。
>>358 ,360
返答ありがとうございます。
>普通に代入すればいいのに。
これ、Cの構造体を継承したクラスで、
C側にポインタで渡したときにそっちでメモリフィルされてる
可能性が有ったもので。
>>361 ちょっとまて、CとC++をgotchaに使ってるの?
C++は例えPODでも最低1バイトのサイズを持つ事になってるから その辺はどうなんでしょうね
>>361 その場合は継承は不適切だね。メンバー変数にするべきだよ、
class B
{
private:
A hoge;
public:
A* get_c_ptr()
{
return &hoge;
}
const A* get_c_ptr()const
{
return &hoge;
}
};
>>363 それはメンバーが無いときでも1バイト以上の大きさを持つってことじゃなかった?
>>364 まあそうだね
確かメンバーが空の場合でもアドレスを取れるようにするためとか
C++ Glossary
ttp://www.kmonos.net/alang/cpp/glossary.html > EBO (Empty Base Optimization)
> 空の基底クラスの最適化。
>
>
> メンバ変数を一個も持たない、空のクラス、というものが出来ることがあります。
> しかし空のクラスであっても、アドレスは一意に決めなくてはならないので、 sizeof( EmptyClass ) は 0 にはなりません。
>
> EmptyClass arr[100];
> assert( &arr[0] != &arr[1] ); // アドレスは違ってて欲しい
>
> 単独で使う時にはこの無駄は仕方のないところですが、 例えばこの空クラスから他のクラスを派生する
> ときは、EmptyClass の分のサイズは 0 にして、派生クラスのメンバ変数の分だけを確保する、という最適化が可能です。
> C++の規格で許されているこの最適化のことを、Empty Base Optimization と呼びます。
>>364 うーん、それだと既存野コードで元の構造体を使ってるところを差し替えにくいのが困る。
具体的にはWinAPIで使ってるPOINTとかRECTとかを
継承させようとしてるんですが。
>>367 MFCのCPointやCRectがまさにその継承をやっていたと思うので、VCでは安全だろう。
規格まで確認したわけではないが、他のコンパイラでも安全だと思う。
(Aへのポインタとして扱うなら、ポインタの指す先の領域がどのように生成されたかに関わらず、同じ構造として操作されるはずだから)
ただ一般的にはメンバー変数として持つほうがコーディングスタイルとして良さそうだが、
>>364 がそういうことを言っているのかどうかはわからない。
>>364 危険という意味ではなくやはり設計スタイルの問題で不適切としました。
危険か安全かというとVCでは安全だと思う。
>>368-369 説明ありがとうございます。
自分もコーディングスタイルとしてはメンバにするべきだと思いますが、
差し替えるときの使い勝手に負けて、継承で行きたかったので、
安全だと判って助かりました。
>>370 >>364 はget_c_ptr()で構造体のポインタが簡単に取り出せるんだけど、それでもだめなん?
何か変な問題が出るたびに「あれかも」と調べるのは使い勝手がいいとは思えないけどなぁ
現状でPOINT*で受け取ってる関数を呼び出してる部分すべてと、 その中の自作関数すべて書き直すのはちょっとつらいので・・・
妥協案としてこういうのも考えたんだけど、なんかキモイよねぇ? class ClsPoint { POINT p; public: long &x; long &y; ClsPoint() : x(p.x), y(px) {}; };
グローバルoperatorのテンプレート特殊化って無理なんでしょうか?
こんな感じで試してみたのですが、コンパイル通りませんでした。 template<class T> T operator+(const T& v1, const T& v2); template<> T operator+<int>(const T& v1, const T& v2) { return v1 + v2; }; template<> T operator+<short>〜
組み込み型同士のグローバルオペレーターは定義できなかったりする
ユーザー定義クラスに変えてみましたが、それでも通らないようです。 class hoge { int x; }; 〜 template<> T operator+<hoge>(const T& v1, const T& v2) { return v1; };
Tが不明なんじゃない?特殊化のhogeが何にもかかわってないし。それではhogeがどこに来たら適用されることを期待しているか判らないよ。 もしそれが通ったら 1+1でも適用されてしまうような怖い気がするよ。
template<class Type> struct XXX { Type x_; }; template<class Type> XXX<Type> operator + (const XXX<Type>&, const XXX<Type>&) { return XXX<Type>(); } XXX<int> a, b; a + b; 普通に出来る
382 :
381 :2009/12/31(木) 20:02:22
あ、ごめん、なんでもない
特殊化じゃなくてオーバーロードで解決する #include <iostream> class widget { }; class gadget { }; template <class T> void operator + (const T &l, const T &r) { std::cout << "1" << std::endl; } template <class T, class U> void operator + (const T &l, const U &r) { std::cout << "2" << std::endl; } void operator + (const widget &l, const widget &r) { std::cout << "3" << std::endl; } int main(void) { widget w; gadget g; g + g; g + w; w + w; return 0; }
>>380 そうでした。
template<>
hoge operator+<hoge>(const hoge& v1, const hoge& v2) { return v1; };
こう書かないとダメなんですね。
>>383 なるほど、template operatorより通常のoperatorが優先されるんですね。
1〜10文字の間で書き込まれた文字を8けたの数字にする方法おしえて
1〜10文字の間で書き込まれた文字を8けたの数字にすればいいよ
このスレと、【C++相談室 part76】って何が違うの?
40桁の16進数でよければとっておきのがあるんだけどな・・・
初心者的質問、環境依存の話はここでするはずなんだけど
>>1 があんまり機能してないね
C++相談室 part76
【初心者歓迎】C/C++室 Ver.70【環境依存OK】
スレを勃てるまでもないC/C++の質問はここで 13
てかこの3つのスレ似てる
した二つは初心者用だけどね
a.cppで計算した2次元配列のhoge[x][y]という結果があるのですが、 これをb.cppでもこの結果を使いたいのですが、何か方法はありますか? 単純に単一の数値だけの受け渡し方法は出来たのですが、 2次元配列をどう扱っていいかがわからず、困っています。 aもbも.h(ヘッダ)を利用しています。
2次元配列はガチ鬼門 素直に1次元配列として扱う事を奨める
正確にはvalarrayを使うのがC++のやりかただよな。
そういう意味ではvector< valarray< double > >でいいのか
浮動小数点型から整数部分を取り出す方法について質問です。 現在xとyに浮動小数点型の座標が入っています。 printf(%f)でみると(300.00000,480,00000)のように座標が入っており、 キー入力で移動する状態です。 ここから座標の整数部分だけを取り出そうと思い、 (int)x,(int)を%dで出力したところ、とても大きな数になりました。 %fで出力すると、両方とも0.00000…という状態です。 浮動小数点型から整数型へ変換するときは(int)で小数点以下が切り捨てられると調べたのですが、 どこが間違っているのでしょうか。
>>399 #include<stdio.h>
int main(void){
double x=300.0, y=480.0;
printf("(%f,%f)\n", x, y);
printf("(%.0f,%.0f)\n", x, y); // 四捨五入?
printf("(%d,%d)\n", (int)x, (int)y);
return 0;
}
C++ではjavaみたいに、クラス名=ファイル名じゃないんですかね いちいち、クラスの実装を読む為にfind & grepを使うのが面倒くさいんですが C++のファイル名の命名規則はないのですか?
自分で好きなように決めればいいじゃないか。
規則に縛られるのが大好きな日本人らしい質問だね。
クラスとファイル名が一対一というのも不便。 ある程度関連の強いクラスやフレンド関数をまとめられる自由度があるほうがいい。 そのときの分かり易いファイル名のつけ方の扇子が問われるよな。
VS2005だと、定義へ移動がかろうじて機能するからboost読むときも助かるな。
*.cppにstatic hoge int =1;と宣言してありますが、 *.hにはstatic hoge intと宣言してありません 何故、シンタックスエラーにならないのですか?
>>406 何を言っているのか分からん。
意味が分かるようなソースを晒せ。
>>401 > javaみたいに、クラス名=ファイル名じゃないんですかね
むしろそんな言語はJava以外ないだろ。
C++は何でもプログラマ任せになるというところがいいんじゃねーか。
>>406 ヘッダーの#includeはただのプリプロセッサ。javaやdelphiやc#のusesとは根本的に考え方が異なる。忘れろ。
409 :
406 :2010/01/02(土) 22:15:12
>>407 hoge.h
class Hoge {
//定数の宣言が無い
}
hoge.cpp
#include "hoge.h"
static const int hoogeNo = 1;
みたいな感じです
>>408 ひとまず忘れてみることにしますが、まだいまいちわからないorz
プリプロセッサの働きで、こう書いたのと同じなる。;以外は問題ないよ。 class Hoge { //定数の宣言が無い } ← ;が無いよ! static const int hoogeNo = 1;
411 :
407 :2010/01/02(土) 22:23:30
>>409 するとプリプロセッサにより、
#include "hoge.h"の部分がhoge.hでそっくり置き換えられ、
次のコードがコンパイラに渡されるわけだ。
//hoge.cpp コンパイラが受け取る
class Hoge {
//定数の宣言が無い
}
static const int hoogeNo = 1;
全然おかしくないだろ?
hoogeNoはクラスの外
要素数が3のstd::vectorの配列の宣言はどう書けばいいですか vector<int> vec[N]; for(int i = 0; i < N; ++i) vec[i].resize(3); を短く書きたいのですが vector<int> vec(3)[N]; vector<int> vec[N](3); などはコンパイルエラーになってしまいました
要望にたいする答えじゃないけど vector<vector<int> >を使うのは駄目? vector<vector<int> >a(N,vector<int>(3));
ベクトルのvectorか
テストしてないけど どう? コンテナを派生させるのもどうかとは思うけど template<class T,int N> class VR :public std::vector<T> { VR() :vector<T>(N) { } }; VR<int,3> vec[100];
>>416 そんなきもいものを使うなら
boost::arrayかstd::tr1::arrayあたりを使うほうが健全に見える。
まぁこれだと固定長になるから微妙に要望と違うけど
>>413 見る限り Nx3 の固定長の二次元配列だし
良い初期化方法があるか無いか聞いてるだけでしょ
vector<int> v[N] = {
vector<int>(3),
...,
vector<int>(3)
};
残念ながら無い
構造体をインスタンス化?する時に、 struct Hoge h;とHoge h;の2種類がありますが 何が違うんですか?
>>419 前者だと Hoge って同名の関数があっても大丈夫。
>>419 違いは無い。前者はC言語の制約。後者はtypedefされた型としての宣言。
C++だと何も考えず後者。
423 :
419 :2010/01/03(日) 17:56:56
例外について質問です。 今作っているプログラムが極稀に 例外 0xc0000417 という例外を投げます。 この原因を調査するため、例外をキャッチし、その状況を出力するプログラムを書いたのですがうまくキャッチしてくれません。 VisualStudio2008 Express プロジェクトのプロパティで C/C++ > コード生成 > C++の例外を有効にする を「はい - SEHの例外あり」にしています。 0xc0000417をぐぐったところ、どうやらsprintf_sなどに不正な引数を渡した時の例外のようです。 そこでテストとして try { sprintf_s(NULL, NULL, NULL); } catch(...) { MessageBox(NULL, "error", "error", MB_OK); } としてみましたが、メッセージボックスの表示のほうに流れず強制終了ダイアログがでてしまいます。 sprintf_sの代わりに、newで1GB確保のbad_alloc や、ゼロ除算はうまくキャッチしてくれました。 何かキャッチの仕方がおかしいか、設定が足りない部分はありますでしょうか? よろしくお願いいたします。
>>424 設定変更してからプログラムがコンパイルしなおされたか確認できる?
しかし VS 使ってるならそんなことしなくても、ふつうにデバッガで例外発生時に
ブレークさせればいいのに。
STATUS_INVALID_CRUNTIME_PARAMETER でSIGSYSか
>>424 nullポインター例外等はtry catchではキャッチできないよ。構造化例外ブロックを作らないとキャッチできないよ。
デバッガーはキャッチできるのでデバッガで見るのが簡単。
>>425 変更してからのリコンパイルはされてるようですし、今もしてみましたけど駄目ですね
デバッガを使うべきについては、ユーザーにリリースしているツールでかつ極稀に発生するので
再現がほとんどとれないのです。
なのでユーザー環境で発生したらデバッグファイルを生成して、サポートに送ってもらおうと考えていました。
これから「構造化例外ブロック」というものについて調べてみようと思いますが、
それを(簡単ではないが)作れば、キャッチできるようになると考えて良いでしょうか?
>>427 試しにnullポインター例外を発生させてみましたが、きちんとcatchできるようです。
「SEHの例外あり」にすれば構造化例外も単なるtry, catch(...)でとれるような記述が
http://www.ne.jp/asahi/hishidama/home/tech/vcpp/seh.html このサイトにありました。
しかし相変わらずsprintf_s(NULL, NULL, NULL)の時に出る例外はとれません。
下記記述法も試してみましたが、同様でした(nullポインタは捕まえられたが、sprintf_sは捕まえられない)
__try{}__except(EXCEPTION_EXECUTE_HANDLER){}
それ、例外じゃなくってAssertじゃね? デバッガで止めて、前後のコード見てみ?
431 :
430 :2010/01/03(日) 19:47:04
>>424 のコード試したけど、アサーションが出てるよ。例外じゃないよ。
>>430-431 すいません。
何か根本的なところを間違えているのでしょうか
「sprintf_sは、例外を投げて例外がキャッチされなかったから強制終了ダイアログを出している」のではなく、
「内部でassertを吐き、その場でプロセスを終了している」のでしょうか?
そうなってくると「sprintf_sでアサートが起きたら何か処理をさせてログなどを吐かせる」という方法は無理ということでしょうか?
続きです。 ReleaseビルドしたEXEを実行すると強制終了ダイアログダイアログが出ます。 ここで「エラー報告に含まれるデータの参照 : ここをクリックしてください」をクリックし、 エラー報告に関する技術情報をクリックします。 そうすると Exception Information Code: 0xc0000417 Flags 0x00000001 以下略というような内容が表示されます。 そのため「例外が投げられたが、キャッチされなかったので強制終了した」と考えたのですが違うのでしょうか?
>>433 そのエラー報告を送ってもらえばいいんじゃないの?
私が作ったツールの状態の情報が欲しいのです。 Windowsの強制終了ダイアログの中身は、EXEファイルそのものと、例外の種類とそれが出たアドレスくらいしか情報が無いため、少々足りないのです。
例外ってのも色々あるんだが、そっちの世界をよく知らないのでどの例外だか分からん ただ、try-catchでどうにかする例外には見えないっつーか、CPUの吐く例外とかじゃ ねーの?
いつ強制終了してもいいように定期的にファイルに情報を保存しとくしか無いでしょ それが嫌なら強制終了が起こらないようにバグを潰すしかない
的外れなレスはしなくていいと思うぞ そもそも論とか意味がない
hogeB(test::hogeA())みたいになっている時、 test::hogeA()はstaticなメソッドなのか、それともコンストラクタなのかわかりません これは、ヘッダを見て解決するしかないのでしょうか?
>>439 そのとおりなんだけど、区別できないことで何か具体的に問題があったりする?
442 :
439 :2010/01/03(日) 22:46:16
>>441 他人が書いたコードを読んで勉強している最中なので、
できればstatic or コンストラクタの区別をつけたいなと思ったので
コールバックってのは 1.どこかに関数ポインタを渡す 2.あるタイミングの時(ex.ボタンがクリックされた場合)に、関数ポインタが呼び出される ってことで、おk?
「あるタイミング」というのが「非同期」を意味するわけではないとわかっていれば そんな理解で充分。 一番基本的なコールバックを使う関数は C標準に含まれているqsortやbsearchだけどな。 広義では、なんらかのオブジェクトを渡して、そこに含まれるメンバ (仮想関数だったり関数ポインタだったり)を呼び出す形式のものも コールバックと呼ばれる。
インスタンス化する時の方法は、 1.TestClass t(); 2.TestClass *t = new TestClass(); の2種類がありますが、どうやって使い分ければいいのでしょうか? GUI系のプログラムはほとんど、2.の方法でインスタンスを宣言しているように思えます
>>447 似たような質問を何度も見た
検索してみたまえ
>447 じゃー本題じゃないところで。 ×TestClass t(); ○TestClass t;
451 :
447 :2010/01/04(月) 15:55:45
>>450 コンパイラが文句を言わないので、無視していましたが
どんな違いがあるのですか?
>TestClass t(); これはTestClassを返すtという関数の宣言だろ
453 :
447 :2010/01/04(月) 16:13:29
>>452 TestClass t;
この宣言方法だと、TestClass t(1);みたいに引数を付けられなかったのか
知らなかったorz
感謝します
引数があるのなら、それを入れればインスタンスの生成になるよ、ややこしいなw
int t; → 変数の宣言 int t(); → 関数の宣言 int t(1); → 変数の宣言 int t(void); → 関数の宣言 こんな感じか
456 :
447 :2010/01/04(月) 16:42:19
>>454 えぇ〜と、何か勘違いしていましたね
申し訳ありません
>>449 のリンクを読みましたが、
インスタンスの生存時間によって使い分けるのが適切みたいですね
TestClass t;はnewより歴史が長いのかな〜とか、無駄な事も考えていましたが
あんまり関係なさそう
>>455 だな
C++で空のカッコがあったらvoidを入れてみると読みやすいな
いい例が思いつかないけど、 std::string s(std::string()); って感じで変数の宣言をしようとしたら、実は関数の宣言でしたーなんてこと、たまにあるよな?
<今日のポイント> 空の括弧を見たら怪しいと思え!
>>432 CのライブラリでC++の例外をキャッチしようというのが無理な話ですの。
boost::formatなどのC++のライブラリに置き換えて試して見るのもひとつの手ですの。
Hoge *h = new Hoge(); if( h ){} なぜ、インスタンスなのにifで使えるのですか?
ポインタはnullでないときはtrueとして扱われる。
STLの勉強をしようと思って書籍を調べていたら C++標準ライブラリチュートリアル&リファレンス が良いとありました。 しかし、Amazonでは取り扱い中止になっています。 内容が古いから取り扱いをやめてしまったということなのでしょうか?
>>464 内容が古いっていうか、在庫もないし、出版社ももう刷らないってこと。
>>465 ありがとうございます。
どこにも売ってませんね。Amazonだと1万で中古が売ってるけど・・・
同じような立ち位置の本はどのようなものでしょうか?
STLのオンラインマニュアルの邦訳じゃだめなの?
STLの適当な本と、Effective STL読んでおけばおk
c++のstringも文字列を追加する動作は遅いのですか? つまり、追加するごとにオブジェクトを作り直すのか?ということです
>>469 string が保持してるメモリの再確保の話だよね?
それなら reserve() を使って避けられることもあるよ。
471 :
469 :2010/01/05(火) 15:43:22
>>470 >string が保持してるメモリの再確保の話だよね?
その通りです、reserve()を調べてみる事にします
ありがとうございました
オブジェクトを作り直すってのがjavaのようなのをイメージしてるなら、 C++のリザーブは別の話題だな。
StringBufferのが近いな
>>469 +=で追加する場合はreserveを超えるとメモリの再アロケートが起きる。
+で追加する場合は新しいオブジェクトが作られる。
なお、C++0xで+が+=並みになる可能性がある。
そこまで書くならimmutableってキーワードを教えてあげたらもっと親切かも JavaのStringやJavaScriptのStringはイミュータブル JavaのStringBufferやC++のstringはミュータブル
いみゅたぶるの意味を教えてくれたらもっと親切かも
>>474 それはつまり右辺値参照のことを言っているのか。
右辺値参照が出来ても a = a + bは高速化されないけどな ま、moveを使うのなら a = move(a) + b + cと 比較的簡潔高速に書けるから便利だけどね。
>>479 > a = a + bは高速化されないけどな
operator=(basic_string&& str) があるから、今まで operator=(basic_string const& str) で
必要になってたバッファの再確保とコピーが減らせるんじゃないの?。
>>480 あーすまん、その通りだ。
(a+b)の部分は高速化されないけど代入の部分は確かに高速化されるね。
さんきゅー
DLLで公開されてる関数として __declspec(dllexport) tr1::shared_ptr<iface> CreateObject(param p) { return tr1::shared_ptr<iface>(new iface(p)); } というのがあったとして これを受け取るEXE側で使うライブラリの実装がDLL側と異なる場合ってヤバイですか?
あ、やっぱりそうですか・・・ しかたがないので生ポで頑張りますわ
>>481 e=a+b+c+d
だと
a+bで一時オブジェクトが作られた後、残りの+c+dではその一時オブジェクトに+=を適用できる様になるんだな。
ファイル入出力で困っているのですが、ファイルが存在するかどうかをチェックする方法はどういう方法があるでしょうか? Windows環境です。 fstreamでは存在するかどうかの判定はできませんよね・・?
>>487 存在しなければエラーになるでしょ。 fstream なら is_open() で調べるんだったかな?
Cスタイルキャストとstatic_castって何か違いがあるんですか?
Cスタイルキャスト = const_cast + (static_cast | reinterpret_cast)
static_castだけでもconst化できるでしょ?
Cスタイルキャストとstatic_castの違いなんてググれば すぐわかるのに何でここで聞くんだろう
>>487 VC++なら_access_s( path, 0 )で存在するかどうかをチェックできる
ファイルの存在なんてチェックした所で何にもならんよ チェックしてから実際に開いたりするまでの間に作られたり削除されたりしないとどうして言い切れるのか
>>488 >>489 >>496 ありがとうございます! 試してみたいと思います。
>>497 無かったらデフォルト内容で新規作成して、あったらそのファイルを読み込みたいんです。
プログラム内部の動作なので、削除されたりはしないと思います。
>>494 const_castはconst化じゃなくて非const化専用
あと非volatile化もだな
>>498 ネットワークドライブなら接続切れるかもしれないし
別のユーザーとかが手動で消すかもしれないし
二重起動された自分が消すかもしれないぞ?
開いてみて、失敗したらデフォルトを作るで何が不満なの
開いてみて失敗しても作っていいかは怪しくね? 何らかの理由で、存在はするけどオープンには失敗した、という場合、新規作成に 成功してしまうと既存のファイルが死ぬ まぁとりあえず、WindowsのAPIを適当に調べればいいんじゃね
ほかのプログラムが開いてるときに失敗するとか十分にありえるな その場合はエラー処理を変えた方がいいだろうし、予めファイルの存在を調べるのも悪くないと思う
504 :
デフォルトの名無しさん :2010/01/09(土) 18:28:19
C++のfstreamについての質問です。 fstreamをインクルードしてファイル操作を行いたいのですが ポインタの位置を変更するseekp()およびseekg()メソッドの1番目の引数 がlong型なので2GBを超えるファイルの操作が出来ません。 4GB程度のファイルの編集を行いたいのですが方法を教えてください。 vipでも同じ質問をしたのでマルチポストになるかもしれないのですが、 こちらのスレに誘導されたのでよろしくお願いします。
>>504 osのファイル操作API使うのがいいんじゃないかと・・・。
506 :
デフォルトの名無しさん :2010/01/09(土) 18:41:17
>>505 なるほど・・そういう方法もあるんですね
>>504 seekp(), seekg() の引数は実装依存で long とは決まってないはず。
どうやって実際に long だと判断したの?
あと、環境は?
508 :
デフォルトの名無しさん :2010/01/09(土) 19:01:50
>>507 そうなんですか。
環境は windows xp home sp3 , visual c++ 2008 express editionです
2GBを超えてからファイルの入出力が正常に行えなくなったのでそう判断しました
510 :
デフォルトの名無しさん :2010/01/09(土) 19:06:51
511 :
デフォルトの名無しさん :2010/01/09(土) 19:10:24
>>509 そのサイトの中で下記の様に記述されていたので、fstreamは諦めます
>これがC++では逆転して32bit Windowsではseekgなどは諦めざるをえないようです.
>次のようなコードはWindowsでは2GBを超えるファイルに対して期待通りに動作しません.
>詳しく言うとVC9まではseekg()が失敗します(VC10では大丈夫).
512 :
デフォルトの名無しさん :2010/01/09(土) 19:13:43
>>511 下記の様に記述されていたのでこの方法を使おうと思います
>ただしWindowsではstd::ifstream::pos_typeという型が拡張されていて, これを使うとfpos_t + fgetpos的な使い方は可能です.
VCだとfopenの方はseek64なんてのが増えて、__int64の範囲でアクセスできるようになってるのにな。
質問です。 int n=0; wchar_t buff[4]={0}; swprintf( buff, 4, L"ABCDE%n", &n ); としたときにnに何が入るかは決まっているのでしょうか? 手元の環境では5が帰ってきたのですが移植性があるか教えて頂きたい。
>>514 質問とは関係ないけど、buffのサイズが小さすぎないか?
516 :
515 :2010/01/09(土) 20:14:30
よく見たら、サイズ指定で4としてるからいいのか。
517 :
514 :2010/01/09(土) 20:27:15
ええ、(v)swprintfでバッファに入り切らないところにある%nの振舞いが判らないんです
本題ではないけど、どういう状況になると%nを使おうと思うのか とても興味がある。
C++からVBAでPowerPointを操作しています これはなんて名前の技術ですか? COM?OLEオートメーション?ActiveX?
初心者の質問です。 #include<stdio.h> void autosum(char *addr1, char *addr2, char *ans); void main(void) { char x,y; char ans[4]; x=10; y=20; ans = autosum(&x,&y,&ans); /*表示用*/ for(int i=0; i<=3; i++) printf("ans[%d]: %d\n", i, ans[i]); } void autosum(char *addr1, char *addr2, char *ans) { *ans = *addr1 + *addr2;//加算 *(ans+1)= *addr1 - *addr2;//減算 *(ans+2)= *addr1 * *addr2;//乗算 *(ans+3)= *addr1 / *addr2;//除算 } 四則演算の結果を出したいのですが「 3 番目の引数を 'char (*)[4]' から 'char *' に変換できません」と エラーがでます。ans[]で試したりしたのですがエラーがでます。 どのように直せばよいのですか?アドバイスお願いします。 環境はVisual C++2008 Express Editionです。
ans
&ans[0]
COM、OLEオートメーションはどっちもあってるけどActiveXは違うんじゃないのかなぁとおもう。 間違ってたらすまんね。
524 :
519 :2010/01/10(日) 02:36:28
わかりました ありがとうございます.
#include<stdio.h> void autosum(int addr1, int addr2, int *ans); int main(void) { int x, y; int ans[4]; x = 10; y = 20; autosum(x, y, ans); /* 表示用 */ for (int i = 0; i < 4; i++) printf("ans[%d]: %d\n", i, ans[i]); return 0; } void autosum(int addr1, int addr2, int *ans) { ans[0] = addr1 + addr2; // 加算 ans[1] = addr1 - addr2; // 減算 ans[2] = addr1 * addr2; // 乗算 ans[3] = addr1 / addr2; // 除算 }
>>525 さん有難うございます。
これ、テキストの問題でして元が↓でした。
#include<stdio.h>
???????/*算出関数のプロトタイプ宣言(問1)*/
void main(void){
char x,y;
char ans[4];
x=10;
y=20;
???????/*間出関数の呼び出し(変数xyアドレスと配列ansの先頭アドレスを引数で渡す)(問2)*/
}
void autosum(???????)/**addr1,*addr2,*ansで引数を受け取る(問3)*/
{
*ans = *addr1 + *addr2; /*加算*/
*(ans+1)= *addr1 - *addr2; /* 減算*/
*(ans+2)= *addr1 * *addr2; /*乗算*/
*(ans+3)= *addr1 / *addr2; /*除算*/
}
intを使わずにやる方法ってないのでしょうか?
それともテキストの間違い?(結構あったので)
何がしたいのかよく分からんが別にcharでも数値は入るでしょ その例だと乗算でオーバーフローするけど
気分を悪くしてしまってたらすみません 穴を埋めて四則演算の結果を答えるって問題を どうしても解けないの質問しました。
>>520 のを
ans = autosum(&x,&y,&ans);
↓
autosum(&x,&y,ans);
に変えるだけでおkかな?
for文の反復条件は>525氏が書いたように
i < 4
のほうが分かりやすいよ
530 :
デフォルトの名無しさん :2010/01/10(日) 04:02:14
質問です。 初心者なので質問の仕方自体が適切でないかもしれませんが、どうかよろしくお願いします。 c言語で、テキストファイル(.txt)上の数列を、int型の2次元配列に格納したいのですが、 数値の総数が不明な場合、どのようなプログラムが考えられますか? 【テキストファイルの例】 99 3 5 -3 12 ・・・(データがどこまで続くか不明) 41 -11 0 1 2 ・・・(〃) ・ ・ ・ ※数値の区切りはカンマなどスペース以外でも可です。 ※ただできればテキストファイル上の数値は列毎に後端で揃うようにしたいです。
>>530 1列の要素数がすべて同じという保障があるなら、
固定配列で一回1列目の要素数を確認して、mallocでメモリを確保して、処理して、最後にメモリ開放。
って流れじゃないかな??
>>529 さん
ans = autosum(&x,&y,&ans); の部分の ans= は
戻り値は無いのでいらなかったってことでいいのでしょうか?
助かりました、有難うございました!
533 :
530 :2010/01/10(日) 10:50:48
>>531 さん
レスありがとうございます。
こちらの説明が足りませんでした。
各行(横方向)の要素数は一律でない上に不明という状況です。
前提条件を覆すようで申し訳ありませんが、
どうも2次元配列で一気に格納するよりは、1次元配列で一行ずつ読み込んだほうがよさそうですね。
現状としては、数列を一行ずつ要素ごとに配列に格納する段階でつまずいています。
できれば全体の処理の流れを示して頂けると助かります。
>>530 c++でvectorを使えば簡単なんだけど、どうしてもcじゃないとダメなの?
cだと結構めんどくさいよ。
>>533 そこまでわかってたらアドバイスする余地ねーよw
>>530 スマートさにはかけるが2度読みするのが一番楽。
1回目にアイテムの数だけ数える。
格納した後のint配列をどう使うかによって工夫の仕方が変わってくる話
>>533 アクセスがトロくてもいいなら一方向リスト
struct intlist_t
{
int value;
struct intlist_t *next;
};
struct intlistlist_t
{
struct intlit_t *list;
struct intlistlist_t *next;
};
メンバ変数に別クラスをポインタとして包含している時に、毎回Nullでないことを確認してから ポインタを経由して別クラスのメンバ関数を呼び出すことにしてるんだすけど、 いちいちif(hogePtr != Null)をするのが面倒なんで何か上手い方法とかありませんか?
541 :
530 :2010/01/10(日) 12:34:36
皆さん、レスありがとうございます。
とりあえず
>>539 さんのものを元にやってみます。
int型配列をその後どうしたいのかとか、c出ないといけない理由とか、
いろいろ説明不足ですいませんでした。
>>540 NULLの代わりにダミーオブジェクトを放り込んでおく
ヌルオブジェクトパターン
>>540 if(hogePtr) にすれば文字数は半分近くになるよ
>>542 ありがとう。こんなデザインパターンがあったのか。まだ読んでないけど使えそうっぽい。
しかし、”してるんだすけど”って何だよorz
546 :
540 :2010/01/10(日) 12:55:51
なんか結局NullObjectってやつをnewしてあげないといけないのね。 オブジェクトの生成もせずに済むのかと早合点したけど世の中そんなに上手い話は無いってことか。
NULLのときでも何か処理するの? 場合によってはassertで済むんじゃない? NullObject なんてグローバル変数でおk
548 :
540 :2010/01/10(日) 13:06:27
いや、Nullだったらダメじゃなくて、Nullの時は何もして欲しくないのです。 で、そこいらにNullチェックがあってうざいなぁと思って、 ヌルオブジェクトパターン使えばnewも何もせずに済むもんかと先走ってしまった。 Singletonあたりと組み合わせるのが定番みたいなんで検討しみます。
NULLの状態を作らなくてすむ設計を心がければいい
っていうか俺の職場では別インスタンスのポインタ保持は厳禁 そのクラス内では許される
551 :
デフォルトの名無しさん :2010/01/10(日) 16:18:27
C言語初心者です。 質問させて下さい。構造体のポインタの質問です。 aとbがポインタとして、 a->bという記述は、「ポインタaが指し示すの構造体のメンバであるポインタbの指し示す値」 という認識は間違いでしょうか? プログラムを読んでいると、a,b,cがポインタとして c = a->bと記述されていて戸惑っています・・・ *cではなくcなわけだから、cはアドレスなのでc = &a->bと今の理解ではなってしまいます・・・
a->b は (*a).b の省略記法
よくわからないのですが、 (*a).b と a->b が等価なところからつきつめていけばどうでしょうか?
554 :
515 :2010/01/10(日) 16:42:54
>>551 > a->bという記述は、「ポインタaが指し示すの構造体のメンバであるポインタbの指し示す値」
> という認識は間違いでしょうか?
「ポインタaが指し示すの構造体のメンバであるポインタbの値」だな。
>>551 a->b というのは、(*a).bのことです。
よく考えてみてください。
bはポインタとして宣言されているのだから、
ポインタcに代入しても大丈夫なのです。
>>550 じゃあ、抽象クラスやインターフェースクラスはどう扱ってるの。継承オンリー?
それらのポインタでコンテナを作ったりしないの?
557 :
デフォルトの名無しさん :2010/01/10(日) 17:08:49
551です。 ご教授ありがとうございます。 基礎的な質問ですみません。 少しわかってきました。(間違っているかも・・・) (*a).bとかんがえると、a->bはアドレスとなります。 では、もしポインタbの値が欲しい場合は、*(a->b)と書けば良いという理解で正しいでしょうか? このように理解しました。間違っていたらご指摘お願いします。 a->b ←これはアドレス *(a->b) ←これは値
558 :
デフォルトの名無しさん :2010/01/10(日) 17:14:40
>>554 551です。
ありがとうございます。
「ポインタaが指し示すの構造体のメンバであるポインタbの値」にアドレスが
書かれていて、そのアドレスに変数がある(*b)という理解で正しいでしょうか?
559 :
デフォルトの名無しさん :2010/01/10(日) 17:17:27
551です。 連続で書き込みすみません。 では、もしポインタbの値が欲しい場合は、*(a->b)と書けば良いという理解で正しいでしょうか? ↓ では、もしポインタbが指し示す値が欲しい場合は、*(a->b)と書けば良いという理解で正しいでしょうか? の間違いでした。
>559 正解でよいと思う。 演算子の優先度は->の方が強いので *a->b でかまわない。明示する意味で()つけも悪いわけではない。 構造体の変数a,そのメンバbがあるとき a->b はbの型に一致する、というのが正確かな。
561 :
デフォルトの名無しさん :2010/01/10(日) 18:17:51
>560 ありがとうございます。 理解することができました。
562 :
530 :2010/01/10(日) 19:04:18
度々すみません。
>>539 のプログラムで、2次元配列全体の要素数ではなく、
↓のように各行毎の要素数を求めるにはどうしたらよいでしょうか?
99 3 5 -3 12 8 19 3
41 -11 0 1 2
99 3 5 -3 12 8 19 3 89
要素数8
要素数5
要素数9
1行読み込む ↓ 文字列解析
>>562 文字列処理がわからないっていってるのか?
デリミタ(区切り文字)で調べると大抵の人が何をやってるのかわかるぜ
565 :
530 :2010/01/10(日) 19:38:29
各行ごとに\0が現れる位置を調べればよいということでしょうか? [99] [3] ・・・ [\0] [41] [-11] ・・・ [\0] data[i][j] = '\0'の時のjがそのままi行目の要素数になるということなら、 かなり乱暴ですが、 for(;;){ if( data[i][j] = '\0'){ printf("i行目の要素数:%d\n", j) break; }else{ j++; } } こんな感じで?
>>565 その程度の問題なら、自分でいろいろプログラム書いて試してみ。
入力は超簡単なテキストファイル、例えば「1 2 3 4 5」だけの奴でいい。
キミのプログラムにこのテキストファイルを読ませて、「5」が出力されれば正解だ。
そうやって自分で試行錯誤しないと身につかないよ。
567 :
530 :2010/01/10(日) 20:43:16
>>566 ご指摘ありがとうございます。
自分で試行錯誤してみた所、↓のような形になってしまいます。
1行目の要素数:0
2行目の要素数:14
3行目の要素数:8
0 1 2 3 4 5
1 2 3 4 5
1 2 3 0
[ソースコード]
//各行の要素数の取得
for(i = 0; i < nrows; i++){
for(j = 0;; j++){
if( data[i][j] == '\0'){
printf(" %d行目の要素数:%d\n", i+1, j);
break;
}else{
j++;
}
}
}
//2次元配列上の数値の表示
for (i = 0; i < nrows; i++) {
for (j = 0; j < ncols[i]; j++) {
printf(" %2d", data[i][j]);
}
printf("\n");
}
>>567 「なってしまいます」じゃなくて、直るまで試行錯誤しろよ
それって
>>539 に追加したソースだよな?
i行目の要素数はnrows[i]だ
コメントが全くないソースだから仕方ない部分もあるとはいえ
for文ぐらいはちゃんとして理解して欲しいかな
nrows[i]じゃなかったncols[i]だった
571 :
530 :2010/01/10(日) 21:16:11
>>568 やってはいるのですが、なかなかうまくいきません。
テキスト上のデータ上に0があると、そこまでしか要素数を数えてくれないのはどうしたらいいのでしょうか?
char line[] = "1 2 3 4 5"; の文字列解析からわかってなさそうだな
>>571 dataはchar**じゃなくてint**だからな?
574 :
530 :2010/01/10(日) 21:45:13
>>569 すいません。やっと
>>539 のプログラムの流れがつかめてきました。
↓のようにしたらncols[i]がi行目の要素数だと分かりました。
本当にありがとうございます。
[ソースコード]
//2次元配列の表示
for (i = 0; i < nrows; i++) {
printf("%d行目の要素数:%d\n",i ,ncols[i]); //追加部分
for (j = 0; j < ncols[i]; j++) {
printf(" %d", data[i][j]);
}
printf("\n");
}
[実行結果]
1行目の要素数:8
0 1 2 3 4 5 6 7
2行目の要素数:14
1 0 1 2 3 4 5 6 7 8 9 10 11 12
3行目の要素数:19
2 1 0 1 2 3 4 5 6 7 8 9 10 1112 13 14 15 16 17
4行目の要素数:1
3
5行目の要素数:26
4 3 2 1 0 1 2 3 4 5 6 7 8 910 11 12 139 10 11 12 13 14 15 16 17 18
575 :
530 :2010/01/10(日) 21:46:51
>>572 すいません。独学の上、始めて一月くらいなもので許してください。
int型の配列の時もchar型と同じように文字列解析可能なのでしょうか?
やってみたら0が配列上にあるとそこまでしか要素が数えられなかったので。
>>573 そうかもしれません。char型に直さないといけないのでしょうか?
576 :
573 :2010/01/10(日) 21:51:48
>>575 いやだから、文字列解析は
>>539 の時点ですでに終わってるってこと。
dataには解析された結果が入ってるんだよ
577 :
530 :2010/01/10(日) 22:00:09
>>576 すいません、>573を誤読しました。
>>539 が各行の要素数を配列ncols[i]に入れてfor分を制御していることは分かりました。
もちろんそれで問題は解決しているのですが、
>>563-564 さんの指摘を考えると、
int型でもchar型と同じように文字列解析できるということなのかと思ったので。
はじめまして今日からC++はじめました こないだ久米井康孝の「猫でもわかるC言語」って本買ってC言語入門したけどマジで超分かりやすいは…… 大学にいた女だけに優しいクソ教師のベーシックよりずっとずっと分かりやすいっす ただ一つ不満を言うと、俺はC言語を習いたかったのに中身はC++だった……何をいってるか(ry C++とCて全く違うのでしょうか?できればC言語から習ったが良いでしょうか? 正直他にあったC言語の本はハードでとっつきにくそうだったんですけど……
C使わないといけない状況になる予定が無いならC++からでいいんじゃない? でもC++の入門書ってC知ってる前提の多いから気をつけろよ
CとC++は全然違うから、使いたいほうから勉強すればいいよ。 どうせ学ぶならC++をすすめるよ
581 :
515 :2010/01/10(日) 22:11:03
>>578 猫でもわかるCって本を買ったのに、中身はC++の解説書だったの?
ひどくね?
もしかしてVisual C++という言語製品と Cというコンピューター言語の区別がついてないとか無い?
>>578 C言語はさらーっとだけ最初に学んだ方が良いとは思う。
まあなんだ、
小中学生が
いきなりかけ算九九と文字式計算を勉強するか、
かけ算九九をかるく勉強してから文字式計算を勉強するか、
的な感じかな。
585 :
578 :2010/01/10(日) 22:42:09
沢山のレス感謝す
>>581 信頼のベストセラー類型20万部て帯だったんですけど
Visual C++を例にして解説してありました
>>582 今日は¥ついたエスケープシーケンスてので簡単文章書いたんですけど(ソース書く第一歩です)
『カテゴリから「コード」を選択し、テンプレートから「C++ファイル(cpp)」を選択してください』って書かれてたんですけど
猫でもわかるってタイトルからしてすでに詐欺本だってわかるだろ。騙されてるんだよあんた
587 :
530 :2010/01/10(日) 22:46:23
>>584 そうかもしれません。条件等もう少し丁寧に書く用意に気をつけてみます。
588 :
515 :2010/01/10(日) 22:47:39
>>585 目次を見たら、Cの範囲しか解説してないっぽい。
>>585 猫のホームページなら読んだことある。
本でも何でも最初はいいから、とにかく読んだり書いたりしてみる
のが良いかと。
>正直他にあったC言語の本はハードでとっつきにくそうだったんですけど……
いや、まともなプログラミングってのはそういうものだ。
厳格な文法の下 書かねばならないのだから、当然解説もそうなる。
590 :
578 :2010/01/10(日) 23:06:20
入門書読むための入門書になればいいと思ったんですけど、変なクセついて却ってマイナスになるならどうしよっかなって。
>本でも何でも最初はいいから、とにかく読んだり書いたりしてみる
わかりました!取っ掛かり探す段階なんでとにかく書こうと思います
>>579 プログラミング知らない人用って書かれてて自分でも理解できたんでその点は大丈夫かと
>>588 自分もそう思ったんですけど、515にあるようにC++ってコード選択したんで
…俺は何を勉強してるんだろうw
単にテンプレートにcファイルがなかったからじゃないか? たしかc++はcのコードも動くようにできてるはずだから気にしなくていい
592 :
515 :2010/01/10(日) 23:14:18
VC++には、C++としてコンパイルするかCとしてコンパイルするか 指定するオプションがあるけど、猫だし、まあいいやってはしょったんだろ。
C++でハードカバーの本ってあったっけ?
594 :
589 :2010/01/10(日) 23:17:15
>>590 C言語の
>取っ掛かり探す段階なんでとにかく書こうと思います
なら、猫の本でおk。
C++に進級するときは(猫のホームページを読む限り)
猫の本は止めといた方が良いと思う。
C++入門者にはエクスメディアの『ビジュアルラーニングC++』って本が
個人的なオススメだったけど、会社が倒産しちゃったんだよなぁ。
独習C ↓ 適当 ↓ Effective C++
596 :
589 :2010/01/10(日) 23:26:42
>>595 なるほど。それもいいな。
でもとりあえずはとにかく書くこと。書かないとぜーったいむり
597 :
578 :2010/01/10(日) 23:27:41
>>594-595 ありがとうございます、参考にします
>>591-592 何度もすいません、自分の勘違いでしたか
本をよく読んだらC言語では空行は無視されますが見やすいから入れますって書かれてました…すいません
>>591 だけど、C++モードでCを学んだら、後々大変なことになりかねないぞ。
変数の宣言位置とかさ。
それはともかく、入門書にはAcceralated C++を推すぜ。
>>598 C++からCだと、初期化位置で宣言できないなんて不便だな。って思う程度だけど。
逆にCからC++だと、頭でNULLや0を入れればいいなんて変な癖つけられて余計面倒だよ。
C++を使っていればオブジェクト指向の設計方法を学んでいるから、後からCを使ってもその設計手法が生かせるメリットあるよ。
600 :
515 :2010/01/11(月) 11:32:40
> 頭でNULLや0を入れればいいなんて変な癖つけられて Cでもこれはダメでしょ。
Cのように、関数の頭でまとめて宣言する方式の方が、 関数全体を理解しやすいし、正しい思考が出来る。 初心者はC++であってもそうした方がいいと思うよ
Cでも普通に{}でくくってスコープ絞ってるわ
604 :
デフォルトの名無しさん :2010/01/11(月) 13:00:29
>>599 >>601 時代に逆行するというか、
単にC++に詳しくない初心者程度だから
そのくらいの使い方しかできないんだろ。
>>601 >Cのように、関数の頭でまとめて宣言する方式の方が、
こいつに至ってはコンストラクタすら理解していないようにしか読めないww
605 :
604 :2010/01/11(月) 13:01:45
ごめん前後の文脈を読んでみると、
>>599 は別に間違ってなかったわ。
すまん
>>599 、申し訳ねぇ。。
俺はコンストラクタって呼ばれてるのか呼ばれてないのか 初期化の仕方によって違うときもあるから嫌いなんだよね チェックしようと思ったら動かしてブレークポイントで止めてみないとわかりにくいっていう C++の機能自体いいと思うもんがない 勉強したての当時は新しいってだけで覚えたけどね でもいま考えると欠陥言語だな 昔の人がなんで言語に型を入れたのか?とかそういうあえていれた制限を なにも考えずに無駄にとっぱらって悦にいってる言語にしかみえない
>>606 バカスw
お前の無知さが恥ずかしい。
<間違い>初期化の仕方によって違うときもあるから嫌いなんだよね
<間違い>C++の機能自体いいと思うもんがない
<間違い>昔の人がなんで言語に型を入れたのか?とかそういうあえていれた制限をなにも考えずに無駄にとっぱらって
だいたいC++も静的型付け言語だろ無能w
>>606 なんか勘違いしてないか?
C++は型をとっぱらってないだろ。
>>606 C++は、もともと抽象データ型をサポートするための C の拡張だし、
型を自由に定義できること自体は悪くない、はず
C++の問題は、言語仕様が混沌としてることもあるけど、ユーザが
やり放題すぎるのが原因にみえる。コンストラクタにしても、メモリ初期化ぐらいなら
まだしも、API 呼ぶとか時間のかかる処理を平気で入れたりするんだよね
あと、なんでこのスレの何人かがこんなにC++マンセーなのか分からん
>>610 > やり放題すぎるのが原因にみえる。コンストラクタにしても、メモリ初期化ぐらいなら
> まだしも、API 呼ぶとか時間のかかる処理を平気で入れたりするんだよね
必要なら入れるだろ。処理時間でコンストラクタに入れるかどうかなんて決めないよ。
>>611 C++に限らず、ほかの言語でも、コンストラクタでファイルオープンとか
DB接続とかやるのふつーだしな。
ソースコードの見た目から機械語が想像できる 抽象度の低い世界しか理解できない人がいるだけにしか見えない
>>612 しねえよw
initとかconnectとかそれ用の関数を用意するのが常識
FILE作ると同時に勝手にfopen呼んでたら大変なことになるだろ
>>614 いや、コンストラクタかファクトリメソッドが主流だろ?
MFCみたいにコンストラクタと初期化が別になってるほうが少数派なんじゃね?
>>614 コンストラクタで用意されてることもある。
どうでもいい処理のときには便利。
initの使い方間違える屑がチームにいると困るからRAII
多機能で長命なclassを駆使する奴がinit大好きなんだよね
フルボッコw
C++用のネットワークソケットの綺麗なラッパーってありますか?
OSはLinuxです。 綺麗の基準は、使いやすくて薄くてそこそこの移植性があってバグが少ないもので。
>>619 そうだね。initが必要なんてのはコンストラクト時にすでにクラスの状態が不明なんていい加減な設計だからだろうし。
>>618 そうだよね、保護方法が無いもんね。1回だけしか呼ばれないと保障されているコンストラクタで用事を済ますのが安全だし手間なしだし。
だから、
>>606 の
>俺はコンストラクタって呼ばれてるのか呼ばれてないのか
>初期化の仕方によって違うときもあるから嫌いなんだよね
が意味不明なんだよね。
initメンバじゃなくてresetメンバなら俺は許してる もちろんコンストラクトはちゃんとしてだが
初期化時に this へのポインタをよそへ渡すことが必要なときは init用のメソッドが別途必要になることもある コンストラクタ実行中に this を外部に漏らすと構築未完了状態のオブジェクトに アクセスされる恐れがあるからね(特にマルチスレッド時) まあコンストラクタで済むならそれで充分
>>610 僭越ながら申し上げます。
コンストラクタから例外投げても良いんだよ。
>>627 そういう場合はファクトリで隠蔽した方がいいと思うよ
>>624 boost::asioを試してみてくれないか?
感想を聞きたいんだな。
632 :
530 :2010/01/11(月) 17:45:41
質問です。
>>539 のプログラムでint型の2次元配列D[256][1024]を、main関数内で新しく宣言すると処理が実行されなくなるのですが、どういった原因が考えられるでしょうか?
グローバル変数でこの先困るのかは何とも言えないところがありますが、原因の見当がまったくつかなくて困っています。
-------------------------
#include <stdio.h>
#include <stdlib.h>
int D[256][1024]; ←グローバル変数にすると処理が実行される。
int main() {
int D[256][1024]; ←ここだと処理が実行されない。
FILE *fp = fopen("data.txt", "r");
int nrows = 0;
int i;
int j;
int n = 0;
int **data = NULL;
int *ncols = NULL;
int *row = NULL;
for (;;) {
int minus = 0;
int value = 0;
int c = getc(fp);
puts("ここまできてる?"); ←表示されない
以下実行処理
-------------------------
コンストラクタで失敗する設計って俺には理解できないな こっちは例外とか強制的に処理しなきゃなんねーのかよw 失敗したかどうかなんてBOOLで返せよ なんでてめぇのオナニー例外処理なんてこっちでうけてやんなきゃならねーんだよw
>>633 標準がそうなんだから仕方ない
自分でなんとかするんだ
>>635 たぶんそうなんだろうが、高々2MBスタック使っただけで落ちるんだったか
環境とか書いてないから何とも言えん。 VC++とかで1MBがデフォルトじゃなかったか
デフォルトは1MBくらいじゃないか? 正確には覚えてないが
VC++2008のをdumpbin /headers でみるとこうなってる。 これって、16進数なんだっけ? 100000 size of stack reserve 1000 size of stack commit 100000 size of heap reserve 1000 size of heap commit ヒープの数字は使ってないよねこれ?
>>632 ということでスタックオーバーフローだね。
32bit * 256 * 1024で1MBをスタックに取ろうとしたから。
リンカのオプションでスタックサイズを広げるか
でかい配列をスタックに取らないかどっちかだね。
スタックに取らない様にするには、グローバルにするかstaticをつけるかmalloc等でヒープを使うかだね。
heap使ってもこの場合同じだね
644 :
530 :2010/01/11(月) 18:28:46
皆さん何度も本当にありがとうございます。 static変数にしたら、ローカル変数で宣言できました。 また試しに配列をD[100][100]と小さくしても動きました。 問題が解決した上、ちょっと理解も深まって本当に感謝です。
別にC++だからってinit使ってもいいんだぞ、Googleなんかは実際そうしてるんだし
>>644 staticはよしてmalocにしたほうが良いよ。
>>645 Googleは例外使わないルールだから仕方がない
>>646 なぜ malloc() の方がいいのか?これだけの条件では static / malloc() の差はないでしょうに。
>>633 エラー処理に興味ないなら何もしなきゃいいんだよ。
650 :
530 :2010/01/11(月) 19:47:44
>>646 そうなのですか? よろしければどうか理由を教えてください。
>>643 さんのレスは
「mallocを使ってヒープ領域に配列を確保しようとしてもローカル変数のスタック領域と同じようにオーバーフローする」
という意味かと思ったのですが、違うのでしょうか?
>>650 ローカルのstaticはスタック上に取るのではなくグローバル上に取る。
たとえば、関数が再帰呼び出しされた場合や、マルチスレッドで再入したときに領域が重なってトラブルの元になる。
今回のようにメモリ不足からという理由で使用するのは不適切。
ヒープも有限だからオーバーフローにはなるがスタックよりも取れる領域は広い。
>>645 まあそれは、1組織のルールだし。
>>647 の言うとおり例外を禁止してるけど、グーぐるのコーディングルールには、新規プロジェクトにおいて例外はメリットがあると書いている。
しかし、既存コードが例外に対応していないから禁止していると書いてるね。
そういう事情で使ってないんで例外を否定しているわけじゃないね。
653 :
530 :2010/01/11(月) 20:11:15
>>651 ちょっと調べてみましたが、確かにヒープ領域のほうが基本的に確保できる領域が大きいようですね。
今のところ再帰やマルチスレッドを実装する予定はないのですが、
今後それらを実装する場合や、データがもっと大きくなりそうな場合に検討してみます。
丁寧にありがとうございました。
Googleのコーディング規約は前時代的だが、あれを採用しても別に悪くはないとは思う メリットとデメリットの天秤を考えて選べばいい
struct Functor { template<class T> operator()(T arg) {}; }; 上のような関数オブジェクトにテンプレート引数を渡す場合、どう書けば言いのでしょうか? Functor<t>()(a) でもFunctor()<t>(a)でもないみたいだし。
Functor(a) なんのためのファンクタとoperator()なのかって話ですよね…
int num; Functor func; func.operator()<int>(num); でも普通は↓ func(num);
>>656 すみません。例の書き方が悪かったですね。
>>657 なるほど、そう書くんでしたか。ありがとうございます
newに失敗したらNULLを返す方法を教えて。
返ってくるのは 0 がいいってか
#define new new(std::nothrow)
>>659 VCなら_set_new_handler()でできそう。
ちょっとぐぐったら、NULLを返すVC6で例外を投げるって例しか
なかったけど、newでNULLを返すには、NULLをreturnするハンドラを設定すればいいのかな?
newする前にNULL入れておいて、コンストラクタで例外発生させたら ゴミアドレスが返るんだっけ?
コンストラクタで例外起きたら代入実行されないだろ
じゃあその方法でいいか。面倒になった。
>>659 std::nothrow つけるか、自分で throw () 付きの operator new 作って使う。
そして同時に、コンストラクタからは例外が発生しないことを保証する。
>>667 std::nothrow つけるってどうすれば良いの??
二次元配列を内包するクラスを作成しているのですが vector<vector<T>>で実装すると中間要素に空白を持つことが出来ないので (配列の最大列数*指定行)+指定列をキーとするmapを用いて実装しようと思います このとき、行と列のそれぞれ最大要素数を求めるには力業で検索していくほか無いのでしょうか?
>>672 > vector<vector<T>>で実装すると中間要素に空白を持つことが出来ないので
ここ、意味が分からん。
中間要素って何?空白って何?
例えば vector<int> array(10) という配列があったとき 途中の要素に0ではなく要素無し(空白)というのを実装したいと言うことです
>>674 なら vector<map<int, T> > とか map<int, map<int, T> > とかでいいだろ。
最大要素数とか要らん。
676 :
デフォルトの名無しさん :2010/01/12(火) 11:29:14
はじめまして。 C言語でジャンケンの後出しプログラムを作成したいのですが、 どのような風にすれば作れるのでしょうか? 相手のプログラムは状態遷移を使ってくる強敵です。 よろしくお願いします。 ジャンケン回数は10000回です。
fork()して次に相手が出す手の割合を調べた後に、 一番勝率良い奴を出すという戦略で十分じゃね?
678 :
デフォルトの名無しさん :2010/01/12(火) 11:42:25
具体的にはどんな感じにすれば良いですか?
>>678 とりあえずコード書け。わかんないとこだけ聞け。
680 :
デフォルトの名無しさん :2010/01/12(火) 11:54:45
int ko4(int n){ int ko_no_te ; int last_oya_no_te ; float rnd ; /* 状態遷移確率(親の手がグーであれば,グーを出す確率 1/5, チョキは,1/5, パーは,3/5) */ /* 状態遷移確率(親の手がチョキであれば,グーを出す確率 3/5, チョキは,1/5, パーは,1/5) */ /* 状態遷移確率(親の手ががパーであれば,グーを出す確率 1/5, チョキは,1/5, パーは,1/5) */ float ko_no_te_trans_table[3][3] = {{1.0/5,1.0/5,3.0/5}, {1.0/5,1.0/5,3.0/5}, {1.0/5,3.0/5,1.0/5}} ; if(n==0) /* スタートは,相手の手の履歴がないので乱数で状態を決定 */ /* 乱数発生 */ ko_no_te = (int)(rand()/(1.0 + RAND_MAX) * 3) % 3;
681 :
デフォルトの名無しさん :2010/01/12(火) 11:55:43
else{ last_oya_no_te = oyanote[n-1] ; /* 1までの乱数を発生させ */ rnd = (float)rand()/(1.0 + RAND_MAX) ; /* 状態遷移確率と照合し */ if (ko_no_te_trans_table[last_oya_no_te][GU] > rnd) ko_no_te = GU ; else if((ko_no_te_trans_table[last_oya_no_te][GU]+ko_no_te_trans_table[last_oya_no_te][CHOKI]) > rnd) ko_no_te = CHOKI ; else ko_no_te = PA ; } return(ko_no_te); }
>>682 int *p; じゃなくて student *p; でしょ
685 :
デフォルトの名無しさん :2010/01/12(火) 15:32:18
最下段のソースを改変して、自分の環境に合わせてlame.exeのパスを
C:\Program Files\mp3\LAME\lame.exeに。コマンドラインのオプションを
lame.exe -t -q 0 -b 80 --resample 44100にしたいと思っています。そこで1行目を
#define LAME_EXE "C:\\Program Files\\mp3\\LAME\\lame.exe"
に。8行目を
strcat(cmd, " -t -q 0 -b 80 --resample 44100");
に替えてみたのですが、「音声の変換に失敗しました」とエラーが出て失敗してしまいます
C++はサッパリちゃんなので、どなたか御教示いただけませんでしょうか。宜しくお願いします
ttp://anonymousriver.hp.infoseek.co.jp/lame_wrapper/lame_wrapper.c
>>685 puts(cmd) で出力されたものをコマンドプロンプトに貼りつけて実行してみればいいよ
>>687 同じ。つか、403はアクセス許可をしてないッてことだから
相手側が何か設定ミスったか、不都合があって接続をさせないようにしている。
>>688 ありがとう、belution.com 閉鎖の件があり、少々不安に感じていました。
690 :
デフォルトの名無しさん :2010/01/12(火) 17:09:24
return system(cmd);の後に、puts(cmd);入れてみたり return system(cmd);をputs(cmd);に入れ替えましたが うまくいきません。そういうことではないのかな? 本当に無知ですいません
要は、cmdの中身を直接コマンドラインで打ってちゃんと動くのかってことだよ。 そこで動かなきゃsystemで呼んだって同じだろう?
692 :
685 :2010/01/12(火) 17:19:55
>>690 はコンソール画面が一瞬で閉じてしまって
結果が分からないということです
「音声の変換に失敗しました」はどうやって見たの? 最初からコマンドプロンプトで実行するか、(VC++なら)Ctrl+F5で実行してみては?
694 :
685 :2010/01/12(火) 17:24:20
>>691 単にコマンドプロンプトから
lame.exe -t -q 0 -b 80 --resample 44100 入力ファイル名 出力ファイル名
とした場合は正常に動きます。cmdの中身については
私には確認する術が分かりません
いやだから、puts(cmdしたプログラムをコマンドプロンプトから実行するんだよ
そもそもデバッグできないとプログラムは書けないぞ デバッグのほとんどは、そのcmd等の変数の中身を確認することだぞ
>C:\\Program Files\\mp3\\LAME\\lame.exe 途中にブランクが含まれるパスには要注意。 system関数は単純に最初のブランクまでをコマンドとみなす。 サンプルのにはブランクが入ってないだろ。
>>697 ご指摘いただいた件で検索したところ、下記のページがヒットしました
#define LAME_EXE "C:\\"Program Files"\\mp3\\LAME\\lame.exe"とか
#define LAME_EXE "\"C:\\Program Files\\mp3\\LAME\\lame.exe\""
などを試して、駄目ならスペースが不要な所にlame.exeを置いてみます
それでは時間がかかりますが、検証してみます。皆様ありがとうございます
ttp://okwave.jp/qa/q1965931.html
>>686 の通りやってたら空白が問題って一発でわかったのになw
>>699 普通にコマンドプロンプトからの実行方法がわからないor知らないでは?
VCから入って、まともなコンパイル(Makefile含む)を知らないとね。
ついでに、685にアドバイス。
コンソール画面が一瞬で閉じない方法として、
「デバックなしで実行」を使うと、コンソールが閉じずに終了するぞ!!
701 :
デフォルトの名無しさん :2010/01/12(火) 18:27:29
質問です。よろしければ教えてください。 テキストデータを配列に収めるために以下のようなプログラムを作成しましたが コンパイルで←で示した部分にエラー判定が出てしまいます 打開策をご教授していただけるととても助かります。 while(getline(fin,c_name[i],',')){ getline(fin,a_name[i],','); getline(fin,c_num[i][0],',');← getline(fin,c_num[i][1]);← (*total_num)+=(c_num[i][0]-c_num[i][1]); for(int j=0;j<c_num[i][1];j++){ getline(fin,n_num[i][j]);← i++; } } c_name[]とa_name[]はstring型でc_num[][]とn_num[]はint型です。 他に必要な情報があれば書きます。 テキストデータは下記のような感じのものが入っています。 name1,name2,123,4 1 2 3 4
getlineとは? 標準関数じゃないよね?
getlineはC++の関数として習ったものですが、 細かくどういったものなのかはわかりません…ごめんなさい…
705 :
702 :2010/01/12(火) 18:41:08
ごめん、標準関数だった 最近俺ボケてるようだ getlineの定義は basic_istream<charT,traits>& getline(basic_istream<charT,traits>& is, basic_string<charT,traits,Allocator>& str, charT delim); わかりやすく書くと istream& getline(istream&, string&, char); なので、第2引数は string でなければなりません
>>705 つまり、int型の配列をgetlineに突っ込んだのが原因ということですね!
ありがとうございました!
int型にはちがう方法でファイルを読み込むように試してみます
std::vectorとstd::dequeはどちらも可変長配列ですが特徴というか使い分けの目安のようなものはあるのでしょうか?
>>707 vectorは一本でかい配列を取る。だから、&v[0]のようなアクセスができる。
dequeは一本とるかもしれないしとらないかもしれない。上記のようなアクセスは出来ないけど、メモリ効率は多少マシかも。
dequeって連続領域を保証してたっけ?
ライブラリの実装を見れば分かるが、連続してる訳がない。
厳密に言うなら&v[0]は使えるが、0番目の要素にしか使えないので意味が無い。
もっと厳密に言えば、ブロックサイズまでは&v[0]で得たアドレスを使えるが、不幸
で分かりにくいバグの元。
>>708 が言いたいのは、vectorなら&v[0]で得たポインタをある程度は配列のように
使える(再配置が起きるような操作をしない限り)、ということだろうから、その意
を汲むなら
>>709 がダウト。とは言っても、&v[0]も不幸なバグの元だが、再配置を
理解した上で、決してうっかりしないような使い方を徹底するなら大丈夫。
で、
>>707 の質問に戻ると、dequeはバッファを複数ブロックに分けて、マッピング
情報を内部に保持して一つのバッファのように使うのが一般的な実装。
なので、
・push_backも「push_frontも」基本的には軽い
・内部バッファのサイズ変動にそこそこ強い
・vectorのように内部バッファのポインタを得てそのまま使うのは無理
というのが基本的な特徴。
一方vectorは、
・push_backは内部バッファが溢れない限りは一番軽い
・内部バッファのサイズ変動に弱い
・内部バッファのポインタを取り出して使える(危険性をきっちり理解した上で)
といったところ。
つーか、どういう実装になってるかを知ってた方が、コンテナの特性を掴むには早い。
listとかもそうだけど。
vectorにはそもそもpush_frontが存在しないことも付け加えておく
再配置が気になる時はreserveを使うといい 固定サイズでいいならboost::arrayもいい
あまりにあまりな基礎的質問で申し訳ないのだけど。 PostMessage(hWnd , WM_APP+10 , ローカル変数 , ローカル変数) したときウィンドウ(hWnd)が「ローカル変数なんかとっくに壊れてるだろ、だらず!」 とか怒るんですが 対策はローカル変数じゃなくてグローバルで何とかするしかないのでしょうか
>>714 newするなりmallocするなり、staticにするなり、好きなのをどうぞ。
>>714 ローカル変数のアドレスを流し込むつもりだと何であれ無理なんだが、
場当たり的な解決法だと、先にLPARAM型とWPARAM型を宣言して変換して流し込む。かな??
その他だとSTATIC変数にすると一応できるかも。
717 :
716 :2010/01/13(水) 18:54:14
おっとかぶった。orz
718 :
714 :2010/01/13(水) 19:05:03
malloc! 実体をhWndに持たせればなんとかなる・・・か? もう少し試してみます。多謝。
>>714 インスタンスのポインタを渡すのも楽だな
見やすく書くことを心がけよう そうすれば間違いも見つけやすくなる
vector<vector<T> >をメンバにもつクラスがあるのですが 配列の要素数が多くなってきたりTのサイズが大きいものだったりすることを考えると vector<T>のポインタを保持させてvector< *(vector<T>) >とした方が再配置が起こるようなとき有利になるのでしょうか?
>>723 ふつうのOSで再配置は起きない。
そのように変更しても、そのクラスのサイズはふつう変わらない。
>>723 それやばいぞ
サイズをswap技法などで縮小した時にvectorのデストラクタが呼ばれない
boost::ptr_vectorに入れとけ
724は勘違いしてた。忘れてくれ。
std::vector<boost::shared_ptr<std::vector<boost::shared_ptr<T> > > >でどうか しかし、再配置がネックになると予想できる状況なら vector以外のコンテナを検討した方がいいんじゃね。
まぁ実際、アホみたいに再配置が多発するコードか厳しいリアルタイムアプリじゃなきゃ 問題にはならないと思うけどな ゲームですら大抵は問題にならないかと
c++0xの内容見てたらwkwkしてきたんでc++0xでちょっと遊びたいんですけど、windowsでフリーでc++0xが使えるコンパイラってありますか?
gcc4.5
gcc4.5もVS2010もどっちも中途半端な実装だから気をつけろ
サンクスです とりあえず総合環境っぽいvs2010つかってみますわ
インストールしたけど起動すら出来ない(^p^)
template <class T>class Foo{/*〜*/}; を継承して template <class T>class FooImple : public Foo<T>{/*〜*/}; としてこのテンプレート引数Tをclass Hogeでのみ使用して 他では実体化できないようにするということは可能でしょうか?
class FooImple : public Foo<Hoge>{/*〜*/}; ではいけないんかね?
class Hoge { private: template <class T> class Foo ・・・ };
ああ、それでよかったんだ 何難しく考えてたんだろうorz ありがとうございました
>>739 っていうかね、" \n"がchar配列何個分かわかる?
2と思うかもしれないが、文字列として展開されると長さ4の要素数が必要。'[空白]\r\n\0'
つまり、コンストラクタにおいて、確保したバッファは溢れている。
\nが1バイトでもアウトな件
>>739 memcpy(a, b, strlen(b)); みたいなパターンってたまに見るけど
誰かが広めてるのかね。
まったく意味がないよな。
そもそも文字列にmemcpyを使うなと
>>742 え!?おれもやってるんだけど
どうすりゃいいんだ?
イコール代入でもすんのか?
>>744 一部にstr系よりセキュアになるって説があるけど、
俺が働いてるような底辺なところだと、使い方間違って、
よけい危なくなってる。
>>745 長さをstrlen()でとってると、strcpy()使うのとぜんぜん変わらないだろ。
>>742 は+1するの忘れてた。
>>747 ぜんぜん変わらないということはない
ゼロ終端するかしないかが違う
メインフレームか何かのスペース埋めされた固定長バッファに
文字列を貼り付けてるコードなんじゃないの
見てないけどw
>>748 長さをコピー元からstrlen()+1でとってたらまったく同じ。
ああ+1してるのか
>>742 だけ見てレスしてたよ
ハレルヤとか叫ぶぐらいなら menverとか書いてんじゃねーよ
>>751 完全うろ覚えで書いてました.すみません
>>740 '\n' が "\r\n" に展開されるのはiostreamレベルだから
" \n" をコピーするにはヌル文字も含めて3バイトあれば充分。
まあC++ならstd::string使えってことで
755 :
デフォルトの名無しさん :2010/01/16(土) 18:13:36
C言語だとファイルポインタに標準ストリームを代入して使えたじゃん。 FILE *fp = stdout; fputs("Pikachu", fp); C++ の std::istream とか std::ostream とかのインスタンスではできないの?
>>755 std::cout, std::cin
MFCでstd::stringやstd::vector使うのって邪道ですか? それからシリアライズの時の例外処理ってMFCで定義している例外マクロを使ってるんですが C++の例外処理に変えるってできないでしょうか? TRY { Serialize(ar); } CATCH_ALL(e) { AfxMessageBox( "save error!"); } END_CATCH_ALL;
void Deleter(Hoge *p) { delete p; } void Deleter(const Hoge *p){ delete p; } これってどっちでもおkですか? 個人的にはオブジェクトの内容を破壊するのでconstじゃない方がいいのかなと思うんですが コンパイラ的にはどっちでもいいようなので・・・
760 :
デフォルトの名無しさん :2010/01/16(土) 20:50:25
質問です。よろしければ教えてください。 細い物体を、画素をずらして除去するという以下のようなプログラムを作成しましたが 画面全体がずれてしまいます。 imgNの配列に入っている画素の部分だけずらすにどのように書けば良いのでしょうか? 打開策をご教授していただけるととても助かります。 C言語(ライブラリとしてOpenCVを使用しています) ↓
761 :
デフォルトの名無しさん :2010/01/16(土) 20:51:47
// 細い物体の除去処理 for(y=0; y < img->height; y++){ for(x=0; x < img->width; x++){ tmpp[0] = imgN->imageData[img->widthStep * y + x*3]; // B tmpp[1] = imgN->imageData[img->widthStep * y + x*3 + 1]; // G tmpp[2] = imgN->imageData[img->widthStep * y + x*3 + 2]; // R tmppp[0] = imgS->imageData[img->widthStep * y + x*3]; // B tmppp[1] = imgS->imageData[img->widthStep * y + x*3 + 1]; // G tmppp[2] = imgS->imageData[img->widthStep * y + x*3 + 2]; // R
>>759 へー、constでもdeleteできるんだ。
デストラクタって、const付じゃなくても呼び出しOKなんだな。
763 :
デフォルトの名無しさん :2010/01/16(土) 20:52:43
// 閾値処理 if (tmpp[2]==255 && tmpp[1]==255 && tmpp[0]==255) { if (tmppp[2]==0 && tmppp[1]==0 && tmppp[0]==0) { img2->imageData[img->widthStep * (y) + (x)*3] = img->imageData[img->widthStep * (y) + (x-30)*3]; img2->imageData[img->widthStep * (y) + (x)*3 + 1] = img->imageData[img->widthStep * (y) + (x-30)*3 + 1]; img2->imageData[img->widthStep * (y) + (x)*3 + 2] = img->imageData[img->widthStep * (y) + (x-30)*3 + 2]; } else { img2->imageData[img->widthStep * (y) + (x)*3] = img->imageData[img->widthStep * (y) + (x+30)*3]; img2->imageData[img->widthStep * (y) + (x)*3 + 1] = img->imageData[img->widthStep * (y) + (x+30)*3 + 1]; img2->imageData[img->widthStep * (y) + (x)*3 + 2] = img->imageData[img->widthStep * (y) + (x+30)*3 + 2]; } }
764 :
デフォルトの名無しさん :2010/01/16(土) 20:55:01
else { img2->imageData[img->widthStep * (y) + (x)*3] = img- >imageData[img->widthStep * (y) + (x)*3]; img2->imageData[img->widthStep * (y) + (x)*3 + 1] = img- >imageData[img->widthStep * (y) + (x)*3 + 1]; img2->imageData[img->widthStep * (y) + (x)*3 + 2] = img- >imageData[img->widthStep * (y) + (x)*3 + 2]; } } }
765 :
デフォルトの名無しさん :2010/01/16(土) 21:14:42
自作scanf(myscanf)の作成で void myscanf(const char *fmt, ...){ int j, argc = 0; while (*fmt){ if (*fmt == '%'){ fmt++; argc++; switch (*fmt){ case 'd': j = *((int *)((char *)&fmt + argc * sizeof(void *))); read_int(j); break; } } else { ... } fmt++; } } myscanf("%d", &n); で数値を入力 これを出力するとおかしな数値が出るんだがどこが問題?
>>765 だらだらしたコードを貼る、お前の神経が問題だ、もうこなくていいよ
ソース貼っても貼らなくても文句言われる。 どうすりゃいいの。
なぜva_listを使わないの?
なるべく短くまとめて1レスに収まらなければcodepad まともな返事が来なくてもへこたれない
その腐ってる関数をどうして作ろうと思ったのかはおいておいても argcをインクリメントするタイミングがおかしいな
>>767 プログラミングやめればいいんじゃない?
・・・とまでは言わないけど、
小学生の作文じゃないんだから、長ければいいとおもうのは間違い。
エッセンスを抽出したまえ
>>767 コード貼らないと問題が見えないが、長文のコードは読みづらい。
アップローダがあれば色々解決。後は解るな?
今度からバカのために
/********************************************/
codepad
ttp://codepad.org/ 長いソースを貼るときはここへ!
/********************************************/
これをテンプレに加えようぜ
インデントのスペースを で置換して貼ればすむことじゃないか。
>>771 上に貼ってるのはそこまで長くないだろ。
778 :
デフォルトの名無しさん :2010/01/16(土) 22:49:31
779 :
デフォルトの名無しさん :2010/01/16(土) 23:30:17
ゆとりはその程度でも長く感じるんですよ
>>779 いやエッセンスを抽出できる能力がないやつは…(ryってことだ
>>778 あなたが要求したファイルは存在しません。
あなたが要求したファイルは削除されました。
783 :
758 :2010/01/17(日) 14:22:55
>>758 標準ライブラリを使うのが邪道なわけがない。
MFCの例外について詳しくは知らないけど、普通の C++ 例外との兼ね合いとか
MSDN に載ってるんじゃないかね?
786 :
758 :2010/01/17(日) 17:40:51
質問です 構造体のテストとして下のようなプログラムを作ったのですが、 セグメンテーション違反が出て動作しません。 Initの中身をそのままmainに入れると動くのですが原因は何でしょうか
#include <stdio.h> #include <stdlib.h> #define N 4 typedef struct { int *data; int len; } Number; void Init(Number); int main(void) { Number a; int i; Init(a); a.data[0] = 0; a.data[1] = 1; for(i = 0;i<N;i++) printf("%d",a.data[i]); printf("\n"); return 0; } void Init(Number a) { a.len = N; a.data = (int*) malloc( N * sizeof(int)); int i; for(i=0;i<N;i++) a.data[i] = 0; }
>>788 値渡しだからだ
Init(a);
してもaは全く変化しない
Init(&a);
で宣言は
void Init(Number *);
みたいにしないとだめだな
当然なかみもそれに合わせて少し変える
×void Init(Number); ○void Init(Number*); こうじゃないのか?あと、0初期化するならcalloc使えば?
みなさんレスありがとうございます。かなり基本的な所の間違いでしたね。。 言われたとおりポインタを渡してInit内で参照させれば同じ動作しました。 callocも勉強になりました。
void Init(Number& a);
ポインタのnullチェックが省けるのはいいんだけど、 Init(a) を見ても、中身が変化してると気づかないからその書き方は嫌い
C言語なんじゃない? Init関数内の変数iの宣言位置が問題になるけどね
>>794 見た目で中身が変化してるとわかるっていうけどInit(const Number*)だったら中身変わらないじゃん
結局のところ本当に見た目で中身が変わったかどうかは判断できないんだから、そんな区別の仕方は無意味だよ
typedef Number* pNumber; pNumber pNmalloc(size_t); void pNfree(void);
#include <stdio.h> #include <math.h> rotate(double a[2][3], double b[3][3], double c[2][3]); int main() { int i, j; double A[2][3] = { {3, 1, 4},{2, 7, 1}, }; double B[3][3] = { {cos(30), sin(30), 0},{-sin(30), cos(30), 0},{0, 0, 1}, }; double C[2][3]; rotate(A,B,C); for (i=0; i<2; i++){ for (j=0; j<3; j++){ printf("%7.4f ",C[i][j]); } printf("\n"); } } rotate(double a[2][3], double b[3][3], double c[2][3]) { int i, j, k; for (i = 0; i<2; i++) { for (j = 0; j<3; j++) { for (k = 0; k<3; k++) { c[i][j] += a[i][k] * b[k][j]; } }} return 0; }
上のように行列の積の計算をしてみたのですが、 おかしい値が出てきてしまいます。 どこ原因なのでしょう?
>>798 おーい
double B[3][3] = { {cos(30), sin(30), 0},{-sin(30), cos(30), 0},{0, 0, 1}, };
初期化式の中に関数書いたらだめじゃん
もしC++なら、cが初期化されてないと言っておこう
double C[2][3] = { {0}, {0}, }; これでいいはず
みなさんレスありがとうございます。 double C[2][3] = { {0}, {0}, }; としたらうまくいきました。
顔みたいだなそれ
しかし初期化子中に関数を書けるのはC++からなんだな Cだとだめと叱られた
806 :
デフォルトの名無しさん :2010/01/18(月) 04:15:43
*this への代入ってなんなんですか? 「ゲームプログラマになる前に覚えておきたい技術」 P314より 補間関数 void Vector2::setInterpolatoin( Vector2& a, Vector2& ab, Vector2& ac, double u, double v){ *this = a; // a Vector2 tmp; tmp = ab; tmp *= u; // u(b-a) *this += tmp; // a + u(b-a) tmp = ac; tmp *= v; // v(c-a) *this += tmp; // a + u(b-a) + v(c-a) }
なんなんですかと言われても自分自身への代入ですとしか言いようが無いのだが
>>806 自分への代入。
Vector2 obj;
obj.setInterpolatoin(〜略〜);
と呼び出したときの*thisは、objになる。
*this = a; と this->operator=(a); は等価。
「オブジェクトの値」のコピーな 勿論自分に代入したって自分のアドレスとかが変わるわけではない
初心者な質問なのですが、質問があります。 継承元のクラスのポインタに、継承クラスのインスタンスを持たせることが出来ますが、 メモリの確保とかはどうなっているのでしょうか? サイズが大分違うのに。 newした時に確保されるからそんなの関係ねえのでしょうか?
>>811 > 継承元のクラスのポインタに、継承クラスのインスタンスを持たせる
この「ポインタにインスタンスを持たせる」という書き方に、
ポインタ周りをまだ理解しきれていないことが表れている気がします。
正確には「ポインタにインスタンスのアドレス値(居場所)を持たせる」んです。
ここを完全にイメージできれば、その疑問は浮かびようがないはずです。
>>811 気になるならソースが公開されてる malloc/free の実装でも見るといい。
>>812 「ポインタにインスタンスを持たせる」で合ってるだろ。
強いて言うなら「ポインタ変数にインスタンスへのポインタを持たせる」ぐらいだ。
ここで「アドレス」を持ち出すほうがおかしいわ。
>>813 わかってる人がそう言うなら、まったく問題ないよ。
でもこの質問者はそうじゃないという話。
「ポインタにインスタンスを持たせる」って言い回しは訳分からんわな
>>814 はぁ?
> 正確には「ポインタにインスタンスのアドレス値(居場所)を持たせる」んです。
こんなこと言っちゃう自分はわかってるつもりなの?
>>816 なんか謎のベクトルで噛み付いてくるあなたが恐いです。
2万回くらい深呼吸してから、また話しかけて下さい。
> 正確には「ポインタにインスタンスのアドレス値(居場所)を持たせる」んです。 これの何がおかしいんだろう C/C++のポインタなら、アドレスを持ち出すのは完全に正しいと思うが
デバッグ中FindNextFileの行でF10押したら暴走する・・・なんぞこれ
ファイルハンドル以外のハンドルで回してたりNULLのポインタで回してた・・・
プログラムの中からexeを実行する時、標準ライブラリではsystem関数を使うと思います。 しかし、system関数を使ってexeを実行すると、コマンドプロンプトが出て鬱陶しいです。 何もウインドウが出ないようにするにはどうすればいいのでしょうか?環境はwindows7です。
824 :
デフォルトの名無しさん :2010/01/18(月) 18:53:00
>>824 プログラムを実行する側の環境次第っていう事ですか?
スコープ演算子を使ってコンストラクタを指すときに、 無名空間を明示的に指定する場合と省略する場合でのちがいについての質問です。 class A { public: A(); }; class B { void function() { ※ } };
editbin /SUBSYSTEM:WINDOWS hoge.exe
828 :
826 :2010/01/18(月) 19:04:04
※の部分に、以下の8つのパターンを試した場合、 なんで(3-1)はコンパイルがとおり、(3-2)はだめなのでしょうか? ((4-1)(4-2)も同様に) (1-1) A a = A(); //OK (1-2) A* a = new A(); //OK (2-1) A a = ::A(); //OK (2-2) A* a = new ::A(); //OK (3-1) A a = A::A(); //OK (3-2) A* a = new A::A(); //error C2061: 構文エラー : 識別子 '{ctor}' (4-1) A a = ::A::A();//OK (4-2) A* a = new ::A::A();//error C2061: 構文エラー : 識別子 '{ctor}'
829 :
826 :2010/01/18(月) 19:05:03
クラスと名前空間による階層?のようなものは、以下のようになると思います。 no name space | | A A() | | B B() ---- function() | | ただし、コンストラクタのみ特別ルールのようなものがあり、 コンストラクタを定義するときのように、 クラス名::クラス名(...) と、スコープ演算子::を使ってもそのカレントの下の階層を見るのではなく、 これでコンストラクタを示す、と理解していたのですが全然ちがうでしょうか?
>>831 systemの存在自体は標準関数。
ただ、引数に何を与えるとどうなるかということが実装依存であるというだけのこと。
あと、827のやり方は、hoge.exeをコマンドプロンプトを使わないプログラムにする。
systemで起動する先のプログラムも自分が作っているのでもないと意味ない。
相手のプログラムをいじれないなら、Windows APIのCreateProcessでCREATE_NO_WINDOWを指定するなど。
えーと。 ビットマップ画像ファイルをhTreeWndのアイコンに設定するためには ・・・・・・・・・orz 環境。C言語でWINAPIいじくる BMP画像を開いて、バッファに流し込んでー ビットマップオブジェクト作るときのDCは・・・ こんがらがってきた。CreateCompatipleDCなのかCreateCompatipleBitmapなのかさっぱりだ
うげ、wisdom! ・・・これに書いてあったとかどんだけ調査不足。 ビットマップオブジェクト頑張って作ってきます、ありがとう
>828 new 演算子のところに書くのはコンストラクタじゃなくて型だから。
>>832 なるほど。
CreateProcessを調べてたらShellExecuteというのが出てきて、こっちの方が簡単そうだったので、これを使ったらできました。
ありがとうございました。
838 :
836 :2010/01/18(月) 23:05:23
と思ったんだけどちょい違うっぽい。
gcc version 4.3.4 20090804 (release) 1 (GCC)
gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
だと全部通っちゃう。
Comeau C++ (
http://www.comeaucomputing.com/tryitout/ で試せる)だと、(3-1),(3-2),(4-1),(4-2) がエラー。
そして現行規格上はこの挙動が正しいと思われる。
> 14882:2003 3.4.3.1p1a
> If the nested-name-specifier nominates a class C, and the name specified after the nested-name-specifier,
> when looked up in C, is the injected-class-name of C (clause 9), the name is instead considered to name the
> constructor of class C. Such a constructor name shall be used only in the declarator-id of a constructor definition
> that appears outside of the class definition. [Example:
> struct A { A(); };
> struct B: public A { B(); };
> A::A() { }
> B::B() { }
> B::A ba; // object of type A
> A::A a; // error, A::A is not a type name
.> end example]
A::A の形は型名ではなくコンストラクタ名として扱われるが、そのようなコンストラクタ名はクラス定義外での
コンストラクタ定義でのみ用いられる、となっている。
ただしこれ 2003 年版で記述が変更されているところだったりする。
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#147
>>828 >>838 俺が見ているのはJIS X 3014:2006なんだけど、5.1 一次式のところで、こんな記述がある。
> 《クラス名》 :: 《クラス名》という形式を用い,その二つの《クラス名》が同じクラスを参照する形式をコンストラクタ(12.1)の記法とする。
そして、12.1 コンストラクタにはこういう記述がある。
> コンストラクタは,そのクラス型のオブジェクトの初期化を行う。コンストラクタは,名前をもたないので,
> 名前検索によってコンストラクタが見つかることはない。しかし,関数記法(5.2.3)を使った明示的型変換のときには,
> コンストラクタが呼び出されてオブジェクトを初期化する。
ちなみに5.3.3 明示的型変換(関数的記法)は,
hoge(foo, bar)のような一時オブジェクトを作成する式。1引数以外でもここに該当する。
これらから、3-1と4-1がコンパイルできるのは仕様通りとだと思う。
一方、3-2と4-2はそのような記述がないのでエラーになるのが正しいのだろう。
>>836 ありがとうございます。
つかすごいすね、分かっちゃうんですね。
そんな資料見たこともないです。
Exampleのコードを見る限り、class-name::class-name names the constructor when both class-name refer to the same class.
はやっぱり基本中の掟なんですね。だからB::Aはコンストラクタにあらず、と。
で、A::Aはコンストラクタとして認識はされるけど、
それがコンストラクタの定義以外のとこで使われているからご法度ということでしょうか・・・。
な〜るほど・・・
>>839 おお!なんだかすっごくつかめそうな気が!ただ今宵はこれまでに致しとうございます。
明日また正座してよんで見ます。
comctrl32.DLL・・・・・・notFound orz 各種ライブラリの入ったDLLのデフォルト置き場所みたいなのってわかるものなのでしょうか
大抵はsystemおよびsystem32じゃねえの?
class A{ int id; } というクラスがあって さらにclass Aを継承したclass B、class Cがあります。 それぞれ==演算子をオーバーロードしてidが同じ値であればtureとしたいのですが A *pB = new B; A *pC = new C; (*pB)==(*pC)とした場合、BとCは比較出来てしまうのでしょうか?
comctrlでPC内全検索してみてもNotFound・・・だと・・・ ちょっと他の手立て探してみます。イメージリスト使えないって致命的じゃないだろうか
comctl32のことだな system32にあるよ
:y=-( ゚д゚)・∵;; ↑目から出た鱗 耄碌してた・・・orz 本当にありがとうございますッ!
>>844 普通の関数と同じだよ
(*pB) == (*pC);というのは(*pB).operator == (*pC);と同じ
operator == (const A &)がvirtualじゃなければA::operator == (const A &)が呼ばれるし、
viartualならB::operator == (const A &)が呼ばれる(ただしB::operator == (const A &)が定義されてれば)
メンバが定義されてなくてグローバルにoperator == (const A &, const A &)が定義されてるなら::operator == (lhs, rhs);が呼ばれる
一回operator == をis_eqに置換してみれば理解しやすいだろう
849 :
デフォルトの名無しさん :2010/01/19(火) 16:04:14
仮想関数は基底クラスのポインターに派生クラスを代入して使わない限り オーバーヘッドは仮想関数ではない関数と同じですか?
静的に解決するコードならそうなんじゃね
ShellExecuteで外部のexeを起動し、そのexeが終了するのを待ってから次の処理にいきたいのですが、どうすればいいのでしょうか?
>>849 同じにできることもあるが、違うことになるほうが圧倒的に多いはず。
気になるなら実測して確認するべし。
>839 関数記法(5.2.3)を使った明示的型変換=5.2.3 Explicit type conversion (functional notation)だと simple-type-specifier になってるので A::A が型名にならないならやっぱり 3-1, 4-1 も通らないんじゃない? >851 ShellExecute 諦めて CreateProcess して WaitForSingleObject。詳細はぐぐれ。
854 :
851 :2010/01/20(水) 03:23:44
template classの派生クラスをfriendに指定する場合、基底クラスをtemplate friend にしても効果が無いようなんですが、派生クラスを全てfriendにしていくしかないのでしょうか? template<class T> class A { protected: T x; template<class T1> friend class A; public: template<class SRC> void copy(SRC& r) { x = r.x; }; }; template<class T> class B : public A<T> 省略 { A<int> a; B<short> b; a.copy(b); //Aの派生型だけどBにはfriendの効果がない }
vc2008eeではコンパイルできたが。 そのコードでコンパイルエラーになる環境とエラーメッセージをコピペしてくれ。
friendはされないよ
>>855 bはA<short>の派生であって、A<int>の派生じゃないと思うんだが
template<class T> class A { protected: T x; friend class A; public: template<T2> void copy(const A<T2>& r) { x = r.x; } }; こんな事をしたいのだろうか
>>858 templateクラスでtemplateパラメータに縛られずに全ての
派生型に対してprotectedメンバにアクセスする方法は無いって
ことですかね。
>>859 それでは派生型でprotectedメンバは使用できないようです。
取り合えずこんな方法しか思いつきませんでした。
template<class T>
typename T::protected_type& RefMember(T& r) { return r.x; };
template<class T>
class A {
protected:
T x;
template<class T1> friend class A;
public:
template<class SRC>
void copy(SRC& r) {
x = r.x;
};
};
失敗・・・ template<class T> typename T::protected_type& RefMember(T& r) { return r.x; }; template<class T> class A { protected: typedef protected_type T; T x; template<class T1> typename T1::protected_type& RefMember(T1& r)}; public: template<class SRC> void copy(SRC& r) { x = RefMember(r); // Aの派生のxも使用できる }; };
>>849 基底でも派生でも仮想関数にはオーバーヘッドがあるよ。
ただし、最適化オーバーヘッドをなくせる場合がある。例えば
Hoge* a=new DerivedHoge();
a->func(); //aはDerivedHogeと明確なので、funcが仮想関数の場合でもオーバーヘッドが無くなる用に最適化される。
friendは継承しない
IronPythonってC++でも使えますか?
もう少し具体的に
使えません
868 :
デフォルトの名無しさん :2010/01/23(土) 16:24:56
質問です。 Java から C++ で作った DLL を呼んで、モードレスダイアログを表示しようとしていますがうまくいきません。 ソースコードは以下の通りです。 JNIEXPORT void JNICALL Java_Dummy_openNativeDialog (JNIEnv * env, jclass obj, jbyteArray className, jbyteArray titleName){ jbyte * cls_name = env->GetByteArrayElements(className, 0); jbyte * wnd_name = env->GetByteArrayElements(titleName, 0); HWND hwnd = FindWindow((LPCSTR)cls_name, (LPCSTR)wnd_name); HWND hDialog = CreateDialog(hInitDll, MAKEINTRESOURCE(IDD_DIALOG1), hwnd, NULL); if (hDialog != NULL){ ShowWindow(hDialog, SW_SHOW); } MessageBox( HWND_DESKTOP, "hogehoge", "hoge", MB_OK | MB_ICONEXCLAMATION ); } hInitDll は DllMain で取得しています。hwnd は正しく取得できてるみたいです。 CreateDialog 自体は成功しているようで、ShowWindow まで処理は行っています。 (どうも、ShowWindow は返り値 false を返しているようです。) MessageBox で表示するモーダルダイアログは表示されるのですが、、、、
VC2008eeだと>861で通った。 >855だとa.copy(b)の部分で、r.xはprotectedでアクセスできないとエラーが出る。
>>870 friendのテンプレート引数はTじゃなくてT1
>>872 template<class T1> friend class A;
この部分のこと?
T1になってますけど。
874 :
デフォルトの名無しさん :2010/01/23(土) 19:14:41
質問です。 関数の引数として、「複数のインタフェースクラス」を継承していること を要求したいのですが、テンプレートなどでうまく表現する方法はあるでしょうか? foo(IBar1 *p1, IBar2 *p2); としてp1,p2の両方に同じインスタンスを渡すというような ルール縛りでは無い方法を知りたいです。
875 :
872 :2010/01/23(土) 19:23:24
>>874 同じインスタンスを渡さないでほしいというなら、アドレスチェックでいくらかは解消される気が。
そういう話じゃないとか?
877 :
876 :2010/01/23(土) 19:47:52
やばい、誤読した。
>>876 は忘れてくれ。。。ORZ
>>874 インターフェースの数があんまり無いなら、関数内で何らかのキャストで要求型に一度変換してみるのがいいと思う。
結果はコンパイルエラーかバッドキャスト(だっけ?)になるから、一応要求には答えられると思う。
綺麗ではないけどね。
それらのインターフェースクラスを継承した1つのインターフェースクラスを挟むのが最適なんじゃね? 他の言語でもそれがそのまま出来そうなのは思いつかないなぁ
MFCダイアログアプリで、Javaアプレットを操作しようとしています アプレット上のボタンをアプリでクリックしたいのですが、うまくいきません アプレットウィンドウ、およびボタンのウィンドウハンドルは正しく取得しています アプレットを SetForegroundWindow() してから PostMessage(ボタンのウィンドウハンドル, BM_CLICK, 0, 0); とやってみたところ、フォーカスは当該ボタンに移動しますが変化ありません 根本的に考えが間違っているのでしょうか?
885 :
デフォルトの名無しさん :2010/01/23(土) 22:49:21
C言語で3行2列の文字列を表示するプログラムを作ったのですが int main() { char a[3][3] = { "ab" , "cd" , "ef" }; printf("%s\n%s\n%s\n",a[0],a[1],a[2]); return 0; } 実行結果 ab cd ef サイズの宣言でa[3][2]にすると 実行結果 abcdef abcd ef となってしまう理由がわかりません。教えて頂けないでしょうか。
>>885 a[3][3] の場合は、a のアドレスには
'a', 'b', 0x00, 'c', 'd', 0x00, 'e', 'f', 0x00
というデータが設定されるが、a[3][2] の場合は
'a', 'b', 'c', 'd', 'e', 'f'
となり文字列のデリミタが存在しない
'f' の次のデータがたまたま 0x00 の場合は
>>885 の実行結果となる
887 :
883 :2010/01/23(土) 23:36:21
>>884 WM_LBUTTONDOWN と WM_LBUTTONUP を送ってみましたが
変化なしです
実際にクリックしたところを Spy++ で見てみると、WM_PARENTNOTIFY というメッセージが
送られているようで、これと同じメッセージを送ればいいのかもしれません
もう少しいろいろやってみます
888 :
デフォルトの名無しさん :2010/01/23(土) 23:42:24
>>886 文字列のデリミタですか…初めて聞きましたw
まだまだ勉強不足のようですね。恥ずかしいです。
ご丁寧にありがとうございました。
C言語では文字列の終端を示すためにNULL文字 '\0' を使う 正しく表示されないのはNULL文字を格納する領域がなく バッファオーバーランした為
892 :
デフォルトの名無しさん :2010/01/24(日) 03:12:19
グローバル変数は全部0で初期化されると聞いたんですが それと同じようにbool型は全部falseになるのでしょうか? あと、構造体のメンバ変数も0全部初期化されるのですか?
恥ずかしげもなく「エンゼロ」とか言っちゃう人種か
>>890 >NULL文字と表記するのはやめといてほしいな。
MSDN の一部にそういう嘘表記があるんだよな。バカかと思った。
null character -> NUL文字 NULLを使うなってのはいいんだけど だからって何でnullじゃなくNULなんだ ASCII?C/C++とASCIIは関係ないよな
NULL文字 に一致する日本語のページ 約 597,000 件 NUL文字 に一致する日本語のページ 約 103,000 件
>>897 そんなん信用できるか。
規格書をだせ!
NULはNULLの略称 ただそれだけ
ヌルってドイツ語だったか
unix系が /dev/null で dos/windowsが nul 出力を捨てるつもりで NULL というファイルを作ったことがあるはず。
nil が好きです
>>899 なんでやねん
ASCIIコードでNULは'\0'と同義という意味もあるぞ
NULはNull Characterのこと Cでは問題になるからヌル文字をNULLとは表記しないだけ
読み方は「ナル」
ヌルでもOK
JIS規格だと「ナル文字」と訳されているみたいだな
sum を「スム」って読まないように、null は「ナル」ってばっちゃが言ってた。
じっちゃはヌルって言ってた
抜かずヌルハチ
80〜90年代くらいのCの普及期だとヌルと書いてる書籍が多かった気がする。 最近はナルみたいね。
ナルとかナルシストみたいでキモイ。ヌルだろJK
なるぽ
>>896 制御コードの表記は伝統的に3文字ないし2文字だから。
sumはスムと読むこともあるぜ
コギト
sumがサムならnulはナル summがスムならnullはヌル
知り合いのインド人はナルと読んでるし、知り合いのアメリカ人はヌルと読んでる。 アメリカ人に言わせると、ヌルもナルもどうでもいいだろ とのことだった。 そんなことよりお前ら全員イントネーション直せボケ だそうです。
「ばっちゃが言ってた」は底の浅い発言である確率がなぜか異常に高い
適当にいってるのをわざと出してるんだからさ。
間違えたらわざとでしたと言えばみんな信じてくれるし恥ずかしくない
間違ってるのに指摘されるまでは俺うまいこと言ったみたいな思いが レスを通してひしひしと伝わってくるので非常にイタい 同類だから共感できるのさ
ばっちゃとか言う奴は大抵それだな
二分探索木を作って通りがけ順で走査を行うプログラムを組んだんですが 走査を再帰的に行うことはできるのですが 非再帰的に組むことがうまくできません どうすればできるでしょうか?
>>926 自分でスタックを作って上げ下げしながらループまわせばできると思うよ。
928 :
デフォルトの名無しさん :2010/01/25(月) 03:20:46
スレ違いならすいません 大学の課題でC言語によるサブセットパスカルコンパイラを作成しています. 最近MacOS 10.5からMacOS 10.6にアップデートしたところ, 以前動いていたプログラムが動かなくなりました. どうやらstrncpyでおかしなことになってるみたいなんですが全く原因がわからなくて困ってます. 長くなりますが,以下にコードの一部を載せます typedef struct pid{ char proc_id[ID_MAX_LEN+1]; ID *param_id; ID *id_root; struct pid *next; }PID; PID *pidp; if((pidp = (PID *)malloc(sizeof(PID))) == NULL){ fprintf(stderr,"malloc error! 1\n"); return 1; } strncpy(pidp->proc_id,"main", ID_MAX_LEN+1); gcc 4.2.1です.以前動いていたgccのバージョンは分からないです. gdbで以下のようなエラー(?)が出ます. 141 strncpy(pidp->proc_id,"main", ID_MAX_LEN+1); (gdb) __inline_strncpy_chk (__dest=0x100130 "", __src=0x3d76 "main", __len=9) at secure/_string.h:116 116 return __builtin___strncpy_chk (__dest, __src, __len, __darwin_obsz(__dest)); 長々と申し訳ありません
>>928 http://www9.plala.or.jp/sgwr-t/lib/strncpy.html >A s2 の長さが n より少ない場合には残りの文字を '\0' で埋めます。
n に配列の長さ以上の値が指定されていても n 文字分を\0で埋める。
>typedef struct pid{
> char proc_id[ID_MAX_LEN+1];
(中略)
>strncpy(pidp->proc_id,"main", ID_MAX_LEN+1);
配列の長さをオーバーしてない?
エラーにならないとか停止しないで動いてるってのは
バグがないこととイコールではないよ。
クラスの相互参照状態についてなのですが ■ClassA.h class ClassB; class ClassA { public: void funcA(); ClassB *b; }; ■ClassB.h #include "ClassA.h" class ClassB : public ClassA { public: void funcB() {} }; ■ClassA.cpp #include "ClassA.h" void ClassA::funcA() { b->funcB(); } このような構成にすると >error C2027: 認識できない型 'ClassB' が使われています。 と言われてコンパイルエラーになってしまいます。 ClassBのメンバ関数を使わない限りはコンパイルできるようなのですが、 メンバ関数を使いたい場合どのように解決するのが良いのでしょうか? 環境はVisual C++ 2008 Express Editionです。宜しくお願いします。
>>930 ■ClassA.cpp
#include "ClassA.h"
#include "ClassB.h"
void ClassA::funcA()
{
b->funcB();
}
>>931 試してみたら実際のプロジェクトの方も含めて上手くいきました
cpp側で確実に宣言が終わってから定義するように書けば良かったんですね…
助かりました。どうもありがとうございます!
933 :
デフォルトの名無しさん :2010/01/25(月) 17:38:53
スンマセン、どなたかお助けください。 現在、学校の課題で自販機っぽいプログラムをC言語組んでいるのですが、 ループさせるところで、悩んでいます。 このソースで走らせると char c; で定義した変数の数値(ココでは文字です)がリセットされず、 一度登録した変数を保持したまま延々とループし続けます。 変数Cで定義した文字で分岐させ、変数Cの数値をリセット→入力受付時に一旦止まる、 ということをさせたい訳ですが どのようにしたら宜しいでしょうか? do{の下に変数Cの宣言を持ってきてもダメでした・・・・ 今もっている知識を総動員して書いたソースが以下です。
934 :
789 :2010/01/25(月) 17:42:47
main(){ short x; /*商品Aの代金を変数xに定義*/ x=100; short y; /*商品Bの代金を変数yに定義*/ y=100; short z; /*商品Cの代金を変数zに定義*/ z=120; short t; /*投入金額の合計を変数tに定義*/ t=0; char c; /*キーボード入力受付用*/ do{ printf("\x1b[2J"); printf("<<<<<<<< Welcome >>>>>>>\n"); printf("<A/B/C/R/E/[1=1000円投入/2=500円投入/3=100円投入/4=50円投入/5=10円投入]>\n"); /*ABCはそのまま商品名を表す。*/ /*Rは返却(Return)、Eはプログラム終了(End)を表す。*/ /*1000/500/100/50/10は投入するお金を表す*/ /*ワンタッチで指定額を入れられるように*/
935 :
789 :2010/01/25(月) 17:44:23
printf("現在の投入金額は%d円です。\n",t); printf("以下の商品が購入可能\です。\n"); printf("ABC\n"); if (t<100){ printf("×××\n"); } else if (t>=100 && t<120){ printf("〇〇×\n"); } else{ printf("〇〇〇\n"); } printf("==>"); /*ここで入力を受け付ける*/ scanf("%[abcre12345]",&c); if (c== 's') break; else switch (c){
936 :
デフォルトの名無しさん :2010/01/25(月) 17:45:56
case 'a' :if (t<100){ printf("商品Aは%d円です。お金が足りません。",x);break; } else{ printf("商品Aは%d円です。ありがとうございました。\n",x); t=t-x;break; } case 'b' :if (t<100){ printf("商品Bは%d円です。お金が足りません",y);break; } else{ printf("商品Bは%d円です。ありがとうございました。\n",y); t=t-y;break; }
scanfか。 改行がバッファに残ってるからそれをクリアしないとな。 scanfの書式に含めた上で、(環境依存だが)fflush()とかでクリアすれば行けるんじゃないかな。
938 :
デフォルトの名無しさん :2010/01/25(月) 17:49:31
case 'c' :if (t<120){ printf("商品Cは%d円です。お金が足りません",z);break; } else{ printf("商品Cは%d円です。ありがとうございました。\n",z); t=t-z;break; } case 'r':if (t>0){ printf("投入金額%d円をお返しします。\n",t); t=0;break; } else{ printf("投入金額はありません。\n");break; } case '1':printf("1000円投入されました。\n"); t=t+1000;break; case '2':printf("500円投入されました。\n"); t=t+500;break; case '3':printf("100円投入されました。\n"); t=t+100;break; case '4':printf("50円投入されました。\n"); t=t+50;break; case '5':printf("10円投入されました。\n"); t=t+10;break; default:printf("\a");break; } }while(1); }
939 :
デフォルトの名無しさん :2010/01/25(月) 17:51:00
スンマセン記入漏れです。 コンパイラ環境はcygwinでやっとります。
940 :
デフォルトの名無しさん :2010/01/25(月) 17:55:59
>.937 バッファ上の数値クリアですか 頑張って調べてみます。
941 :
928 :2010/01/25(月) 21:49:40
>>929 ありがとうございます.
別のところでおかしかったみたいでなんとか正しく動きました.
ただ配列はオーバーしていないと思うんですが.
gdbで
__inline~
の文はなぜ出るんでしょうか?他のプログラムでもstr系でいくつか出ます.
942 :
933-940 :2010/01/25(月) 22:04:09
>>937 様
今頑張って調べていますが、
cygwinでコンパイルしているので、
fflush()ではエラーが出るみたいです。
>scanfか。
>改行がバッファに残ってるからそれをクリアしないとな。
>scanfの書式に含めた上で、(環境依存だが)fflush()とかでクリアすれば行けるんじゃないかな。
どなたか、fflush()を使用せずに、変数の値を改行まで含め、
クリア(又はNULL値)代入出来る方法を教えてください。
>>942 エラーってコンパイルエラー?
エラーの内容は?
fflush(stdin);
↑こんなんでいいんじゃね?
>>942 int moji;
while((moji=getchar())!=EOF && moji!='\n');
>>928 ,941
この場合は問題ないけど、ひじょーに危ういコードなので警告してるの
かなあ。ふつう、strncpy()の第3パラメータに渡すのは、「書き込み先
バッファサイズ-1」なので。
コピーする文字列が"main"って決まってるならstrcpy()でいいし、バッ
ファ長を指定して安全に行くならstrncpy()じゃなくてstrlcpy()を使う。
普通、fflushでキー入力バッファはクリアできないよ ただエラーも出ないと思うが・・・ よく見てないけど、普通に fgets で読んで、sscanf すれば?
削除の責任をノードに負わせて、リストからノードを削除するのをO(1)にしたいんだけど これってstd::listでは無理ですか?自分でリスト作るしかないですかね?
>>947 std::list::iterator が、そのまんまノードになると思うんだが。
スタティックライブラリを作る場合、 複数のクラスや関数を一つにまとめてしまっても、 そのライブラリを使うアプリケーション側のビルドでは 使っていないクラスや関数は絶対にリンクされないものでしょうか? それとも、関連するクラスや関数ごとに大まかに分けて 複数のライブラリにしておいたほうがよいのでしょうか?
基本はライブラリ内のオブジェクトファイル単位でリンク コンパイラによっては関数単位で参照されていないものを外すこともできる
>>950 ありがとうございます。
ということはやっぱり複数のライブラリに分けておくほうがよいのでしょうね。
リンカの動作は規格で定めるものじゃないんだからわからんとしか… 気になるなら分けておけばいいじゃん
環境依存OKなスレだから、規格で決まっていないことを質問しても問題は無い
環境依存の質問がダメって言ったつもりはなかったんだが まぁすまんかった
DLLが公開してる関数のようにEXEから関数を公開する事はできますか?
>>955 関数を公開することはできる。やり方はDLLの場合と同じ。
ただし、DLLとして読み込むのは難しいと思う。できる方法を自分は知らない。
>>952-954 申し訳ありませんでした。
規格によってリンク時の動作が決まっているものではない
ということを知らなかったのです。
ちなみに、VC6やVC2005やVC2008のリンカだと
使っていないものはリンク時に外してくれるものなのでしょうか?
「便利クラス&関数群」みたいなライブラリを作ろうかと思ったのですが。
だからobjファイルごとだって。 どこからも参照されてないobjはリンクされないが、一か所でも使われてるとobj全部リンクされる。 関連の無いものはそれぞれ別のc/c++ファイルにしておけばいいよ
補足しておくと、libはobjファイルを集めたもの。 1個の.Cファイルをコンパイルしてobjを作り、それをlibにしたら常に全部リンクされる。 関数一つ一つばらしておけば、使ってるやつだけリンクされる。
>>958-959 そういうことでしたか。
基本的にはクラスごとにソースは分けてあるので、
ライブラリ自体は1つにまとめてビルドしてしまっても、
アプリケーションが使っていないクラスは
リンク時に捨ててくれるということですね。
配列&文字列は、参照私できないの?
できるぞ #include <iostream> void foo(int (&a)[10]) { a[0] = 42; } int main() { int a[10]; foo(a); std::cout << a[0] << std::endl; }
要素数固定なのか、うむポインタにしよう
可変にできないこともない #include <iostream> template <int N> void foo(int (&a)[N]) { a[0] = 42; }; int main() { int a[10]; foo(a); std::cout << a[0] << std::endl; }
>>956 難しいですか
DLLにコールバック関数を持たせてアプリケーションを拡張できるように・・・というのをやろうとしてるんですが
そうなるとAPIを提供する仲介用DLLと拡張用DLLを両方用意しないと駄目みたいですね
レスどうもでした
>>965 アプリケーションを拡張できるように
アプリケーション側が
決まった関数名 を エクスポートする DLL を LoadLibaray で取り込む→GetProcAddress でDLL側の関数保持
状況に応じて その DLL 内関数を呼び出す
こういう構造を容易しておいて
拡張を記述する側は
アプリケーション側の呼び出しルールに応じた 関数を書けばOK
こういう造りが多いんじゃね?
>>965 EXE内で定義した関数を、関数へのポインタとしてDLL内の関数へ渡すのはできるよ。
難しいと書いたのはEXEファイルをLoadLibraryしたりLIBでリンクしたりということ。俺の勘違いだったらすまない。
横槍すまない。
>>964 すげー。以下のようなコードを書いたら通ってしまった。
スタティック配列始まったな。
template<class T,size_t N>
void Init(T (&Array)[N]){
T Val(0);
for(size_t i=0;i<N;i++){
Array[i] = Val;
}
}
969 :
933-940 :2010/01/27(水) 18:35:14
先日は色々ご教授ありがとうございました。 色々調べまくった結果、 scanf("%[abcre12345]",&c); この部分を scanf("%c",&c); こうすることで何とか解決することが出来ました。 ありがとうございました。 これで何とかなりそうです。
>>966 ,967
レスサンクスです
EXE側のオブジェクトを操作するのに操作用のAPIをDLLで提供しなければいけないかなと思ったんですが、なんとか拡張用DLLだけでできそうです
レスをまとめるとこんな感じですかね
//--Main側--
class Hoge
{
public:
Hoge(void) { /* DLLからHogeUpdateをロード */ }
void Update(void);
void SetX(int x) { m_x = x; }
int GetX(void) { return m_x; }
private:
int m_x;
void (*m_HogeUpdate)(void *handle, HogeFunc *hogeFunc); // コールバック用の関数ポインタ
};
//公開する関数
void HogeSetX(void *handle, int x) { ((Hoge *)handle)->SetX(x); }
int HogeGetX(void *handle) { return ((Hoge *)handle)->GetX(); }
struct HogeFunc { void (*SetX)(void *handle, int x); int (*GetX)(void *handle); };
//拡張用関数をコール
void Hoge::Update(void) { HogeFunc hogeFunc = { HogeSetX, HogeGetX }; m_HogeUpdate(this, &hogeFunc); }
//--DLL側--
//公開する関数
void HogeUpdate(void *handle, HogeFunc *hogeFunc) { /* 拡張によって異なる。handleとhogeFuncでオブジェクトを操作 */ }
リストのつなぎ換えがしたくてこういうコードを書いたのですが std::listのsplice関数ってこんな感じで自分自身に使っても大丈夫なんでしょうか ↓2番目と3番目の要素を交換するプログラム typedef list<int> LI; LI l; for(int i=0;i<4;++i){l.push_back(i);} LI::iterator i1=++l.begin(); LI::iterator i2=++(++l.begin()); l.splice(i1,l,i2); copy(l.begin(),l.end(),ostream_iterator<int>(cout," "));
>>959 あれ?リンカは賢くて必要にして十分なobjをリンクしてくれるものと思っていましたが、違いましたか。
>972 良く読め。 「1個の.Cファイルをコンパイルしてobjを作り、それをlibにしたら」
>>967 GetProcAddress(NULL, "func");
調べてみたところMSDNには書いてないけどこれでEXEから公開した関数にアクセスできるみたいですね
正しい使い方なのかわかりませんが・・・
自前のスタティックライブラリを作成したのですが やはりnamespaceを宣言しておいた方がいいのでしょうか?
vector<class A> vec;で宣言したクラスAのメンバへのアクセスの仕方を教えてください
vec[0].member
>>978 まず、何らかのAをpush_backする。またはリサイズで確保する。
配列的なindexアクセスか、vectorのbackメンバで要素にアクセス。
ドット演算子でAのメンバにアクセス。
vec[0].A_Method();
vec.back().A_Method();
という流れじゃない?
981 :
980 :2010/01/28(木) 23:48:46
おっと、被った。
>>979 ,980,981 さん
ありがとうございます.
>>976 NULLの代わりにGetModuleHandle(NULL)を使えば心配要らない。
>>977 それだけの情報じゃなんとも言えん。好きにしろ。
Handle foo(void) { static my::AutoPtr<Handle> resource(Load("resource-name"), Rereaser); return resource.get(); } これってアプリ終了時にちゃんと開放してくれますかね?
>>985 「ちゃんと開放」となるかどうかは知らないが、 resource のコンストラクタが成功すれば、
のデストラクタは main() 終了時や exit() 呼び出し時に呼び出されることになってる。
× rerease
○ release
× 開放 ○ 解放
次スレ誰か頼む
そういえば昔 ○開放 ×解放 な現場があったな…占有してる「場所を開け放つ」んだから開放だとか… えぇーって思ったけど
あの娘を解き放て!
あの娘は仮想メモリだぞ!
元ネタなに?
アシタカせっ記
ウメハラがぁ!!
捕まえてぇぇ!!!
ばーすとよんで
まだ入るぅぅ!!
ウメハラがぁっ!!!!・・・つっ近づいてぇっ!!!
ウメハラがぁ決めたぁぁーっ!!!!
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。