【初心者歓迎】C/C++室 Ver.65【環境依存OK】
c++でwin用アプリを作るときはやはりwin32apiを記述していくしかないのでしょうか ほかに良い方法はあるのでしょうか?
3 :
デフォルトの名無しさん :2009/04/10(金) 13:57:52
C#やWTLやATLやwinGUIライブラリ
>>2 MFCを使うとか、その手のライブラリを使えばWinAPIは明示的に記述する必要はないよ。
6 :
デフォルトの名無しさん :2009/04/10(金) 14:04:22
7 :
デフォルトの名無しさん :2009/04/10(金) 14:09:29
8 :
デフォルトの名無しさん :2009/04/10(金) 14:16:08
Ultimate++ はクロスプラットフォーム対応の統合開発環境である。
特徴として、新しいプロジェクトであること API がかなりすっきりしていることなどが挙げられる。
ウェブサイトに掲載されている wxWidgets との比較では、同様のプログラムを 1/3 程度のコードで実現している。
http://0xcc.net/pub/uu-2004-08/
9 :
デフォルトの名無しさん :2009/04/10(金) 14:20:25
10 :
デフォルトの名無しさん :2009/04/11(土) 09:12:08
シングルトンの書き方で質問させて下さい。 class Singleton { Singleton(){} ~Singleton(){} public: const Singleton* getInstance() const { static Singleton s; return &s; } }; こういう風に書くとコンパイルが通るのですが、 const Singleton& getInstance() const { のように参照を返すと、デストラクタがプライベートだとだめというエラーになります。 どうしてだめなのでしょうか?
なぜgetInstanceがインスタンスメソッドなんだろう。
12 :
デフォルトの名無しさん :2009/04/11(土) 10:01:48
すいません、Visual Studioからソースを移すときに、static付け忘れました。 static const Singleton* getInstance() const { です。 こうやっても、 C2248が出ます。
>>10 シングルトンなんか使おうとするからダメなんだ
と思っとけ。そして悔い改めよ。
14 :
デフォルトの名無しさん :2009/04/11(土) 10:49:25
>>13 みんな使ってるじゃないですか
一応デストラクタをパブリックにするとコンパイル通るんですが、普通シングルトンの
デストラクタってプライベートですよね?
パブリックにしても問題はないとも思うけど。
>>14 > みんな使ってるじゃないですか
あぁ初心者はすぐに手を出すからな。しかも問題に気づくのはずっと後だ。罠だよ罠。
16 :
デフォルトの名無しさん :2009/04/11(土) 11:35:18
じゃあC++を使えば使うほど、シングルトンじゃなくて、ただのグローバル変数を 使うことになると?
>>16 なんでそうなるの?
グローバル変数に問題があるのはわかってるのに、それをシングルトンにすれば
問題がなくなるとでも思ってるの?
18 :
デフォルトの名無しさん :2009/04/11(土) 11:59:49
なるほど、グローバル変数とかシングルトンとかなるべく使うなということですか。 でもシングルトン使ってるコード多いじゃないですか?
20 :
デフォルトの名無しさん :2009/04/11(土) 13:35:23
でもやっぱり気になるので、シングルトンでデストラクタをパブリックにした方がいいかどうか だけ教えてください。それとも、シングルトンの場合は必ずポインタ返しにして、メモリ確保は 静的にしておき、デストラクタは呼ばれないようにしておくべきなのでしょうか? (呼ばれないから、プライベートでもOK)
21 :
デフォルトの名無しさん :2009/04/11(土) 14:07:25
参照カウンタつけてfreeinstanceも書けばいいんじゃね
22 :
デフォルトの名無しさん :2009/04/11(土) 15:17:47
>>21 ありがとうです。
そうか、それを書いとけばいいですね。
シングルトンってさ、例えばマウスカーソルとか1つでなきゃ困るよ、 って時に1つであることの制御を簡単にするためのものって聞いたんだけど どんな使い方しようとしてんの?
static const Singleton& getInstance() {って書けばいけるんじゃね? なんで参照にする必要があるのか知らないけど
戻り値を参照でない変数で受けているとか、案外うっかりミスでは?
>>20 個人的には、いつも
>>24 の書き方 ( 参照返し ) にしてる。
インスタンスは、それを取得する関数内で静的に確保するから、NULL を返す意味がない。
取得関数をシングルトンクラスのメンバにするなら、コンストラクタとデストラクタ も private にしておく。
シングルトンクラスのマルチインスタンス化を許可すると、思わぬトラブルを招くから、こうしている。
あと、コンパイルエラー云々は、const の扱いが原因な気がする。
27 :
デフォルトの名無しさん :2009/04/11(土) 22:01:53
戻り値を参照でない、普通の変数で受けてたのが原因でした。参照にしたらデストラクタがプライベートでもちゃんと動きました。 あと、23>>とか24>>とか26>>とか、ありがとうございました。使い方はグローバル変数の代わりに使ってました。 勉強になりました。
// WinXP SP3、VC6 SP5 #define UNICODE #define _UNICODE #include <iostream> int wmain(void) { std::wcout << L"Test書き込み" << std::endl; return 0; } 結果、「Test」 としか表示されないんだけど、何が悪いの?
locale
サンクス。 #include <locale.h> _wsetlocale(LC_ALL, L""); でいけたけど、何でこんなことしなくちゃいけないの?
L"" はシステムの設定値(コントロールパネル)を取ってくる。 setlocale( LC_CTYPE, "Japanese" );
>>30 setlocaleしなかったときの"C" localeは最小限のことさえできれば十分という思想でできているから。
あと、VC6だと上手くいかないのかもしれないけど、本当はstd::wcout.imbue(std::locale(""))が好ましい。
コピーコンストラクタとoperator=って、 代入処理は同じものになるケースが多いのですが、 コピーコンストラクタの中で *this = rSrc; // rSrcは自クラス型の参照 とoperator=を呼んでそちらに処理をまとめてしまってもよいものなのでしょうか? それとも、通常は両方に同じ処理を入れておくものでしょうか?
ぎゃくぎゃく。 コピーコンストラクタ(とswap)を使ってoperator =を定義する。 class hoge { public: hoge(hoge const&); void swap(hoge& x); // *thisとxの中身を入れ替える。 hoge& opeartor =(hoge const& x) { hoge_t tmp(x); swap(tmp); return *this; } }; inline void hoge(hoge& lhs, hoge& rhs) {lhs.swap(rhs);} //おまけ
>>33 >>34 の言うように、理想的にはswapもつけて
>>34 のように書きたい。
でも現実にはめんどくさいことも多いので、どちらかに処理をまとめるだけで妥協する。
あんまり両関数に同じコードを書くのは好ましくない。 後に変更したりするのが二度手間になったり変更し忘れたり。
36 :
34 :2009/04/14(火) 21:36:16
今更だけど最後の関数、hoge→swapだったorz
swapにはthrow()を付けるべき。 更に言うとstd::swapの特殊化を書くべき。
>>37 まともな処理系ならADLもできるように書くから問題ない。
ただ、VCのDinkumwareだと、2008以降だったはずだが。
throw() なメンバ関数 swap() と、 ADL 用に同じ名前空間での throw() な inline フリー関数 swap() と、うっかり std::swap() された場合に備えて std::swap() の 特殊化も inline で定義しておけば、完璧?
あぁ inline なら throw() 要らないな。
ASCII表示の16進数をint型に変換したいのですが sscanfとstrtolはどちらを使った方が良いでしょうか?
俺ならsscanf
std::hex 一択
Aというクラスにint getA(int param)というgetメソッドがあったとします 引数によってget出来る内部情報を換えています Aは基本クラスで実際は多態的に利用するわけですが get関数を呼び出す側がパラメータの意味を知っていないといけない、と言う状態は やはりクラスAとその派生クラスの抽象度を下げてしまっているのでしょうか 派生によって引き出せる情報量が異なるため 情報ごとにget関数を作るのは出来ないのですがどうしたらよいでしょうか
>>44 抽象度と言うより、凝集度かな。たしか悪い方から2番目の。
オブザーバーパターン的に、情報を引き出したいクラスを相手に渡すとか。
あるいは、パラメータオブジェクトを作るかかなぁ。
c#とかjava的だとgenericsで固めたくなる雰囲気 abstract class Object<T>{ int getA(T param) } class Dog<Chain>{ int getA(Chain param) { ... } class Chain { ... } } class Horse<Bridle>{ int getA(Bridle param) { ... } class Bridle { ... } } 見たいな感じ しかし getA の意味が継承したサブクラスで無意味になるから面白くない
コンストラクタの中から他のクラスのオブジェクトへの参照をゲットするのが良くないことってありますか
以下のような例で、TOtherをTDerivedのインナークラス(入れ子のテンプレートクラス)に したいのですが、どう書けばよいでしょうか。 C++ってパズルみたいだわ。 /// 前方参照 template<class _T> class TDerived; // ---> TDerivedのインナークラスにしたい。記法調査中 template<class _T> class TOther { //...内容 TDerived<_T>* m_pDerived; }; // <--- TDerivedのインナークラスにしたい。記法調査中 template<class _T> class TDerived :public TBase< TOther<_T> > { //...内容 TOther<_T> m_Other; };
無理
この程度なら翻訳せずに読んだ方が間違いが無い 全く一文字も読めないならプログラム自体を諦めた方が今後のためにいい
>>52 うーん、プログラミングやるには英語は避けて通れないんですかねぇ・・・。
全く読めないわけじゃないですけど、日本語で書いてあっても難しいと思われるものが英語で書いてあるとつらいです。
>>53 いいや、避けて通れる。英語のを使わなければ良い。
>>53 この程度のインストールができないなら、英語が読めるかどうかに関わらずプログラミングを諦めるのが一番手っ取り早い。
だな
>51 >単にインクルードだけしてビルドするとリンクエラーが発生します。 GAlib 自体のビルドはやらずに自分のプログラムに組み込もうとして失敗している、という認識でいい? VC2008 だけど、galib247.zip を展開して makefile.vcpp のあるフォルダで nmake /f makefile.vcpp すると ga フォルダ以下に普通にライブラリがビルドできてるっぽいし、 nmake /f makefile.vcpp test でテストプログラムがビルドされて実行されるわけだが。 後は、自作プログラム側でライブラリ検索パスを指定して ga.lib をリンク対象にすればOK。
まぁ、プログラマは英語を読めないと厳しいのは事実だな。 もともと翻訳に強いマイクロソフト日本法人でさえ 自社開発ツールのマニュアルを完全に日本語化していないくらいだし。 そして日本の英語教育は絶望的な状況だから 日本がITで遅れてるのもさもありなんという気がする。
マニュアル類を読み書きするだけなら中学で習う英語で十分いける
だな
マニュアルは英語でもいいんだよ、別に。 もともと書いてある内容はたいしたことないから。 問題は技術書の類だ。 日本語に翻訳されるのは本国で出版された2年後とか。 マウスイヤーのIT産業じゃ化石だ。
技術書だって中学で習う文法で8割方読めるだろ
>>61 しかし和訳第一版を積んで放置してたら、和訳第二版が出てる件。
#include <stdio.h> int mein(void) { printf("Hello, world!\n"); return 0; } コンパイルは通るのですがリンクでエラーになります。
>>65 エントリーポイントを指定するか
デフォルトのエントリーポイントである main を使うかすればおk
>>62 中学英語で読めるなら、more effective C++ みたいな悲惨なことにはなってない。
読めることと翻訳できることは違う。
書いてある内容を理解できる人が翻訳しないとな
#define MYDEF 1 #define MYDEF 1 みたいなときって、警告すらでないのですが、有効な文法なのでしょうか? さすがに値が異なると警告が出るのですが・・・
無駄ってだけで、 有効ってわけぢゃないな
>>71 正しい。 全く同じ#defineの再定義は有効。
だな
75 :
デフォルトの名無しさん :2009/04/20(月) 09:26:52
あるソース(Linux用のtar.gzファイル)をダウンロードしてg++でコンパイルして sudo make installしたところまではよかったのですが、そのあと実行しようとすると、 ライブラリが見つからないといわれます。 そのライブラリは/usr/local/lib/以下にインストールされているので、 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib すると見つかるようになるのですが、こういう情報をmakeしたバイナリの方に 書いておくことは出来ないのでしょうか? 置かれる場所は決まっている場合、いちいち環境側で設定するよりもMakeされる バイナリ側に書いておいたほうが楽かなと思ったのですが。。。
>>76 勿論、makefileに書けばいいことですね。gccなら、-Lでライブラリサーチパスを設定できます。
それ以上の質問は、makeスレかgccスレでどうぞ。
makefileの話じゃないし、それどころかC/C++に限定された話でも無い binaryにshared libraryのpathを埋め込まないのはdynamic linker/loaderに任せるため 後はLinux板で聞け
あーなるほど、バイナリに埋め込むと言う話か。非常識過ぎて想定できなかったよ。
79 :
デフォルトの名無しさん :2009/04/20(月) 12:03:20
>>78 どういうところが非常識なのか教えてください。
ライブラリを特別な場所(/opt/MyCompany/lib/とか)にインストールしつつ、バイナリから使用するには
ライブラリの場所をバイナリに埋め込むのが最善じゃないかと思ったんですけど。
-rpathを知らないだけだろ
81 :
デフォルトの名無しさん :2009/04/20(月) 12:42:39
そうそうrpathね。 アリガト。
class A{ int x; struct{int f(){return x;}}B; public: int f(){return B.f();} A():x(0){}; } なして return x; が "err invaliduse of nonstatic data member 'A::x'" に成るか論理的に教えて
ビルドしたプログラムを実行したら「vector subscript out of range」と出て落ちました。 このエラーメッセージだけでは、どの添え字アクセスで落ちたのか特定できません。 効率よくエラー箇所を特定するには、どんな方法がありますか?
デバッガ使えよ
コンパイラがAのインスタンスの生存期間と子ども構造体のインスタンスのそれが違うと考えるから。 もしAの外でBのインスタンスを作成すると、return x; で何を返せばいいのかわからなくなってしまう。 この時コンパイラは、実際にAの外でBが作成可能かどうかは区別しない。 だと思う。
#ifndef NDEBUG #define assert_sfx(x,m) asssert((x)<(m)) #else #define assert_sfx(x,m) x #endif int x[10]; for (i=0;i<11;++i) x[assert_sfx(i,10)] = i;
クラスの命名で若干悩んでます 名詞でそのものが表せる場合は良いのですが 「〜する」というものを体現するようなクラスの命名をどうしたらよいでしょうか 「例えばアプリケーション領域に描画する」クラスの場合 DrawなのかDrawingなのか DrawAppAreaなのかDrawingAppAreaなのかそれとももっと適切な命名法があるのか どのようにしたらよいのでしょうか
>>87 erをつけるとか。
Drawerは元々「引き出し」とか「たんす」っていう意味があるけど、気にしなくてもいいよね。
AppAreaDrawerとかでよいのでは FileReader, TextWriter, ImageViewer, WebBrowser
かぶった
91 :
デフォルトの名無しさん :2009/04/20(月) 23:03:35
std::ifstream ifs("hoge.txt"); string line; while (std::getline(ifs,line) && !line.empty()){ cout << line << endl; } ファイルを一行ずつ読み込んで処理しようとして上記のようなコードを書いたのですが、 cout << line << endl; の結果が何も表示されません。ファイルは存在して、オープンは 成功しています。なにかコード上で問題はありますか? ちなみにファイルはWindowsで作成し、改行コードは<LR><LF>です。 どうかよろしくお願いします。
>>91 コマンドプロンプト上から実行してみてはいかが?
93 :
デフォルトの名無しさん :2009/04/20(月) 23:25:13
>>92 そのとおりにやって、問題がわかりました。
getline(ifs,line)の前の、ファイルオープンが出来ていませんでした。
95 :
83 :2009/04/21(火) 00:24:19
レスthx
>>84 使い方がよくわからなくて使っていなかったのですが・・・使うべきですね。
>>86 添え字アクセスの度にチェックコード書くのはしんどいです。
vectorがああいうエラーを出すということは、そのチェックをoperator[]の中に閉じ込めることができないということですかね。
96 :
デフォルトの名無しさん :2009/04/21(火) 00:32:11
>>95 vector.at()使えば?
おれはつかわないけどさ。
それっぽいファイルで #define ベクターオブジェクト (printf("%d",__LINE__), ベクターオブジェクト) みたいに乗っ取ればええんじゃ? 面倒だからデバッガ使え
std::out_of_range 受け取っても添字がわからんだろう
99 :
デフォルトの名無しさん :2009/04/21(火) 00:38:08
VC++2008で、DB接続するコードを書いてます。 DBは今のところMySQLだけなのですが、mysql++というライブラリを使ってVC++2008でDB接続のコードを書く場合、 ADO.NETを使うべきなのでしょうか?
質問です。 授業でteratermを使って、emacsでプログラミングをしているのですが とりあえず、先生の用意したプログラムをコピペして起動してみろとのことで 普通にコピペして、コンパイルしようとしたのですが 警告: null 文字は無視されました という文章が何十行にも渡ってでて、コンパイルできません。 調べてもなかなか対処がわからず、過去ログでの質問は自己解決していたりでわかりません。 断片的な情報から、文字コードの問題かと設定をUFT-8からEUCなどに変えてみましたが UFT-8以外では文字化けしてしまいます。 とりあえず、インデントをしっかりTabに書き換えたりもしましたが、解決しませんでした。 どなたか、解決法を教えてください。 p.s.先生にメールで質問しましたが、すでに試した見当違いの方法しか言わないので、2chだけが頼りです ・・・あの人は日本語読めてないのか? orz
>>100 >p.s.先生にメールで質問しましたが、すでに試した見当違いの方法しか言わないので、2chだけが頼りです
>・・・あの人は日本語読めてないのか? orz
見当違いの方法について詳しく書けよ
可能性としては
1.terminal の文字コードを間違えている
2.日本語を使えないコンパイラ
が有力
なんかemacs lisp臭がするから あきらめた
>>101 すいません。
先生からの返答は
「tera termの設定から文字コードをUTF-8にすると文字化けは無くなります」
→まず標準がUFT-8なので文字化けしてないし、項目中の全ての文字コードで
コピペ&コンパイルをすでに試しています。
「(自分の使用している)Tera taerm pro ver.4.62はUFT-8に対応しているか確認してください」
→対応しています。てか、標準文字コードがUFT-8だとメールに明記してます。
「何が問題かわからないときは、パンチミスを防ぐためにもコピペが有効です」
→すでにコピペは何度も繰り返してます。コピペしてることもメールで書いてます。
むしろファイルの中身だけではなく、コマンドすらコピペして試しました。
・・・こんな感じです。
・鯖の文字コードは何? ・teratermは送信と受信の文字コードを設定できたと思うけど、両方ともUTF-8にしてある? ・コマンドコピペは動いたの? ・日本語使わなければコマンドもemacsも動く?
105 :
100 :2009/04/21(火) 08:09:48
>>104 >・鯖の文字コードは何?
わかりませんが、UFT-8以外では日本語が文字化けし、先生も確認してきていることから
UFT-8ではないかと思われます。
>・teratermは送信と受信の文字コードを設定できたと思うけど、両方ともUTF-8にしてある?
両方してみました。
>・コマンドコピペは動いたの?
コマンドコピペ(?)はよくわかりませんが、メニューバーから編集→貼り付けでやってます。
>・日本語使わなければコマンドもemacsも動く?
先ほど、プログラム内の日本語を全て修正してコンパイルしましたが、無理でした。
・・・警告は日本語で出ますしね。
あと、通常は学校のPCでtera termを使うので自宅から、というのが問題かもしれません。
今日あたり、学校で一度試してみたいと思います。
ただ、自宅から試した友人は全くエラーなしで軒並み成功しているので
・自分のPCの設定、環境の問題
・自分のIDのサーバーでの扱いがおかしい
じゃないかと勝手に思ってます。
学校で問題なければ前者。学校でもできなければ後者かと。
teratermの文字コードは良いとして、 コンパイルが通らない原因は、 コンパイルしているソースファイルの文字コードが問題なのでは。
nullが大量にあるならUTF-16でしょ。 emacsだと何て呼んでるか知らないけど。
108 :
100 :2009/04/21(火) 09:13:41
>>106 一応文字コード設定を変えてからコピペもしてみました。
UFT-8にしていないと、コピペした段階で日本語が文字化けするので
UFT-8が正しいと思うのですが・・・
>>107 すみません、よくわかりません。
文字コード設定の中にはUFT-16はありませんでした。
とりあえずemacsは糞だからviを使え
むしろcat > hoge.cでいい
111 :
100 :2009/04/21(火) 09:23:33
学校のサーバーを利用しているので、変えるのは無理かと・・・ いや、自分はよくわかってないんですが。 以前はmuleでした。
113 :
100 :2009/04/21(火) 09:34:14
>>112 何をしたらいいのか全くわかりません。
od 入力してもなにがなんだか。
まさかとは思うが、utf-16で保存したファイルを鯖にアップロードして悦に入っていたりしないよな。 つーか、どこがC/C++の質問なのかと。
まぁ、これ以上続ける前に、cat > foo.cを試してみろと。
最初はCの問題かと思って、Cで聞いたら環境依存逝けと言われたので。 cat > hoge.c , cat >foo.cやってみましたが、改行されて反応無し コマンドの意味と用法をしらないのでたぶん自分の使いかたが悪いのだと思います。
Uix/Linuxの初歩から勉強してきた方がいいと思うが…… catの標準入力に対して、簡単なソースを打ち込んで見ろってこった。 % cat > foo.c int main() {return 0;} ^D % gcc foo.c % ./a.out こう書いても意味が判らないなら諦めろ。
>>100 コピペした後からコンパイルするまでの手順は?
emacs上でコンパイルしてるのかとか、
シェルに抜けてcc打ってコンパイルしてるのかとか。
どっかの段階でUTF-16/32に変換されたソースをコンパイルしている可能性が高い。
>>117 なんとなくはわかりますが、うまくいきませんでした。
Linuxは個人的にやりたいとは思っているのですがまだ勉強はしてません。
今回は、Linuxを使ってプログラミングしろとのことで、Linuxはメインではなく
cd mv mkdir など本当に初歩の初歩しか教わっていない段階です。
むしろ使わせてるだけで、Linuxについて教える気は皆無のようです。
>>118 シェルに抜けて gcc -o 〜 でコンパイルしてます。
どの段階でuft-16/32に変換されるのかはさっぱり。
実際、上記のようにLinuxは初心者以前の問題なのでUFT-8や16だと
どうなるのかといったこともわかっておりません。
ただ、友達が同じやり方で成功しているので自分のPCの何かが悪いのかと。
そろそろ言ってもいいよな UFTじゃなくてUTF
121 :
100 :2009/04/21(火) 10:22:46
>>117 あ、a.outできました。
・・・なんなんですかね、これ?
122 :
100 :2009/04/21(火) 10:24:10
>>120 あ・・・さっき気づいてなおしたつもりだったのにまた無意識で・・・orz
emacsの設定が悪いかteratermの設定が悪いか。 こうなるともう、鼬害だな。
>>117 > catの標準入力に対して、簡単なソースを打ち込んで
ではなくて、コピペしてみろ、では?
それでエディタが問題かどうかはわかりそう。
最近になって Dll と Lib の作り方と使い方を勉強し始めました。 作り方は分かったんですが、どんな時にそれぞれを使うのかいまいち分かりません。 使い方や手順をみると Lib の方が楽そうで Dll の出番が無いように見えるのですが… こんな時に Dll もしくは Lib を使う・使う場合が多いというような 指針というか判断基準みたいなモノがあれば参考にしたいので聞かせてくれませんか
>>125 常に必要なものは Lib、参照をなるべく遅延したいなら Dll が向く。
例えば、プラグイン的なものは Dll にする。
応用として、機能を Dll に分割し、それらを並列にロードする事で、アプリケーション
の起動を短縮する方法も考えられる。
また、処理を Dll として分割しておくと、その部分のバグを修正した場合、Dll だけの差
し替えで済むという、メンテナンス上の利点もある。
でも、管理は Lib の方が圧倒的に楽なので、Lib で済めばそれにこした事はない。
>>126 何となく違いが分かったような気がします。
Dll は機能を分けられる分、修正がしやすい
Lib は一括でまとめられる分、保守がしやすい
と、いう感じでしょうか。
ありがとうございます。
Perlの処理が遅い部分をCでdllを作って高速化したことがあるな 2秒くらいかかった処理が一瞬で終わった
複数のプロセスで同じライブラリを使うようなら、DLLを検討する。理由は ・上にもある通り差し替えが楽 ・DLLファイルを共有するのでディスク効率がいい ・コードセグメントを共有するのでメモリ効率がいい(二回目以降のロードも速い) 短所は、DLLが増えてくると依存関係がぐちゃぐちゃになること。(いわゆるDLL地獄)
>>128-129 ありがとうございます
素人目には Dll も Lib も同じ処理速度に見えますが
Dll の方が早いんですね
いや、少なくとも128の事例はDLLでないと無理だと思うぞ。 LIBを使えるのは事実上、C/C++/アセンブリ言語くらい(それですべてとは言わないが)。 それと、プラグインのように事前にどういうものが来るか分からない場合もDLLでないと難しい。 なぜなら、LIBを組み込むには、ソースコードからビルドするとこから始めないといけないため。 Apacheなんかではそういう選択肢も可能だけど、 こっちはむしろApache本体と一体の実行ファイルになるので、 DLLの柔軟性を失う代わりに速くなるとされている。
DLL作成したことないんですが DLLを使ったプログラムで、プログラム本体とDLLのデバッグを 一緒にやる場合(たとえばVSでとか)ってどうやるの?
少なくとも、VSでは単独のEXEプログラムのデバッグと何も変わらない。 DLLの関数内にステップインすれば、該当する部分のソースファイルへ飛ぶし、 ブレイクポイントも自由に仕掛けられる。
134 :
13二 :2009/04/22(水) 00:27:44
ありがとうございます。へーーー、そうなんですか。 なんとなく、大変そうな感じがしたんですが、よく出来てるんですね。
もちろんDLLのデバッグ情報が残ってソースがある場合だね!わかるよーっ!
大抵の場合、スタブとドライバ用意するけどな
137 :
13二 :2009/04/22(水) 00:56:34
最近はJTAGデバッグ使ってますが、漢はフルICEでしょ、ね、
>>136 フルICEが使えて一人前でしょ
138 :
デフォルトの名無しさん :2009/04/22(水) 00:59:45
std::mapとstd::pairの違いを教えてください。たとえば、 std::pair<string,int>だと、単にstringとintを一緒にして保持できるだけ。 std::map<string,int>だと、stringとintを一緒に保持できるのに加えて、 stringがあれば、対応するintの値をO(N)の時間で得られる。 という理解でいいですか?
140 :
デフォルトの名無しさん :2009/04/22(水) 01:07:08
>>139 ありがとうございます。
でも両方ともコンテナじゃないんですか?
全然別物じゃないか
142 :
139 :2009/04/22(水) 01:08:25
map<string, int>は、大雑把に言えば、stringで比較する述語を指定したset<pair<string, int>>に、
operator []など使い勝手をよくしたものという感じ。
>>138 の1文1文は間違っていないけど、
pairとmapを並べられると理解しているのか怪しく感じてしまう。
144 :
デフォルトの名無しさん :2009/04/22(水) 03:20:06
>>143 ありがとうございます。寝てました
set<>は結局二分木ですよね?
map<a,b>も結局(a,b)のペアを二分木に入れたものだから、それをset<pair<string, int>>
と書いてくれたのですよね。
だからpairは要素数2個の配列と同じようなものだということでいいですかね。
>>144 まあそういうこと。
ちなみに、pairは2つだけど、好きな個数に設定できるのがtuple。
>>144 set や map の実装が二分木とは限らない。
それもふくめて、一連の解釈についてここで同意を得ることに何の意味があるのかわからん。
順序付け可能な点や、挿入や削除等の時に要求される計算量、iteratorや参照の有効条件等を考慮すると 平衡二分木以外の実装は考えられないけどね。 まあ普通は赤黒木だね。
>>100 >>116 とりあえず Linux はコマンドプロンプトで cat、gcc この2つだけ覚えてればいい。
TeraTerm で emacs 使うのはその後でいい。
コピペは $ cat >file.c [Enter]と打った後に貼り付けて、最後にCtrl+D
$ に戻るので、$ cat file.c で「カタカナひらがな漢字」が文字化けしてないか?
$ head file.c | od [Enter] の表示結果をここで待つ。
$を含めてコマンドを打つ姿が想像できる。
うむ、>117は%だしな。
対象のソースに nkf -g file.c してみようぜ
152 :
デフォルトの名無しさん :2009/04/22(水) 19:17:54
外部SDKのヘッダ・ライブラリをインクルードして関数を使おうとすると"未解決の外部シンボル・・・"が出てエラーになってしまいます 関数をマウスオーバーするとちゃんと型やら引数がポップアップされのになぜエラーになるのでしょうか?
何ちゃら.libをリンクしてないんじゃ?
154 :
デフォルトの名無しさん :2009/04/22(水) 19:27:43
リンク?パスを通すってこと?
ちがう。 スタティックリンクとかでぐぐれ。
libはディレクトリの指定をしたうえで個々のlibファイルを指定するんだぜ
157 :
デフォルトの名無しさん :2009/04/23(木) 11:40:33
extern "C"を忘れているとか。
158 :
デフォルトの名無しさん :2009/04/24(金) 23:36:42
以前 std::ifstream::seekg(ifstream::beg); std::ifstream::seekg(0, ifstream::beg); の違いについて質問したものです。上のやつはどっちでも同じ動きだったのですが、 以下のものは1つ目の引数が0のものでないと、ストリームの最後に移動できません。 std::ifstream::seekg(ifstream::end); std::ifstream::seekg(0, ifstream::end); このあと、自分で調べてたら解決したので、書いておきます。 Seekgの引数が1個のタイプは、バイトで場所を書かないとだめ。ifstream::endはただの数字の2 なので、上のような書き方をすると、2バイト目の場所に移動してしまう。 コンパイルエラーだしてほしかったよ。
GJ!
>>158 そりゃ引数1個のほうは型がpos_typeだからだ。
pos_typeの値は、tellgで得られるので、それと組み合わせて使われることが意図されているのだろう。
161 :
デフォルトの名無しさん :2009/04/25(土) 01:24:17
なるほど、そういうことですか。でも、 ifstream::seekg()という関数と、ifstream::endというのがあれば、 ifstream::seekg(ifstream::end); って書いてしまいたくなりません? しかも、(実装依存かもしれませんが) ifstream::seekg(ifstream::beg); はちゃんと動くし。 やっぱりちゃんと定義をみないとだめということですかね。
シーク関係はCのfseek, ftell, fgetpos, fsetposを模倣したように見える。 そう考えると、beg/cur/endだけを引数に取るものがなくても当然(Cになかったのだから)と思えてくる。 それがいいか悪いかはともかく。
質問です ある構造体Xがあったとして その構造体を主な対象として関数を作ったときに 関数名を void X_Print みたいにアンダーバーを使うのってあんまり良くないでしょうか? クラスを使いたくないもので・・・
クラスAとBがあって、BがA::GetVal()から複数の変数の値を取得しようと思います 派生クラスA'とB'、A''とB''が常に対になるとして GetVal()の返り値を 構造体にしてダウンキャストすることで渡すのとのと 配列やlistを利用して渡すのはどちらがよいでしょうか
>>164 ですが
A'→B'とA''→B''で渡したい値の数が異なる場合
がぬけてました
>>163 逆に問おう。何故それがよくないと思うのかね。
>>164 階層ごとにパラメータが異なるのなら、パラメータクラスを作るか設計を見直すべきかと。
>>164 意味がわからないけど、A::GetValが仮想関数なら
A::GetValの戻り値の型はA',A''::GetValの戻り値の実際の型の
基底クラスにすればFactory Methodになるんじゃないのかな?
名前が納得いかないけど。
C++で質問です。 class A { A(int n); //コンストラクタ } class B { private: A m_a(100); //Aのコンストラクタに定数100をセットしたメンバ変数のつもり } 上のようにしてクラスB内でメンバ変数を定義したつもりなのに、 どうもm_aという関数の宣言だと認識されてしまいます。 どうすれば正しく宣言出来るのでしょうか? ググろうにもシチュエーションが上手く表現出来なくてヒットしません。 よろしくお願いします。
そんな文法が無いから。 コンストラクタの初期化指定で初期化しろ。
171 :
168 :2009/04/25(土) 08:07:18
ありがとうございます。 Bのコンストラクタ内で初期化する事にします。
struct PersonData { int age; int sex; string name; } struct StudentData : PersonData { int id; string school_name; }; みたいにまとめて返したいということじゃないの? *PersonData返して、school_nameにアクセスしたいけどダウンキャストしないとムリ?って。 同じ型なら配列でもいいけど、返した配列をBで解釈するのはオブジェクト指向に反するような気もする。
Cに関して質問です。 構造体やポインタがなぜ必要なのかが良く分からないです。 大体の機能は入門書を読んで分かったんですが…
>>173 少しプログラムを書いてみれば解るようになる。
>>173 CにポインタがなかったらBASICみたいな不自由さを感じるよ
逆に言えばCはポインタがある事で思った通りにプログラムできる言語と
なっている
使い方を誤ると一見して何をしているか分からないコードになるけど
分からないなら今の君には必要ないということだから使う必要ないんじゃね
>>173 構造体は関数呼び出しやファイル操作の時に便利だなあ
関連するデータを一度に読み書き出来るし関数の引数が
少なくて済む=バグが出にくくなる
回答ありがとうございます
>>166 A'→B'ではパラメータa・b・cを
A''→B''ではa・b・d・eを渡したいと思うのですが
どういうクラス設計、受け渡し機構ならすっきりいくでしょうか・・・?
>>167 struct paramという構造体を用意して
param* A::GetVal(){〜〜};としてparamの派生系を渡すと
渡された側がparam*をダウンキャストしないと派生部分が扱えないから・・・ということなのですが
ダウンキャストはしないほうがいいとも言いますしどうなんでしょう?
class A{int a();int b();int c()} class AD:A{int d();int e();} class B{virtual void kureA(class A a){b_a=a.a();b_b=a.b();b_c=a.c();}} class BD:B{virtual void kureA(class AD a){b_a=a.a()〜b_e=a.e();}}
Cはポインタなかったら文字すらまともに扱えないぞ。
文字は扱えるだろう。文字列は無理だが。
配列の受け渡しも困難になるな。 ちょっと有用なプログラムを書くと ポインタのポインタとポインタの配列は頻繁に出てくるようになる。
ポインタを知らないでコンピュータを理解してるなんていえないから。 rubyといったお猿さん向け言語の存在は罪深いわ。
このタイミングでrubyをけなす意味は無いけどな。
プログラム言語とCPUの動作を別に学んで何が悪い
色々と回答ありがとうございます。ちょっとCを書いてみようかと思います。 業務で使うことはとりあえずはなさそうなのでちょっと練習したいんですが、 初心者向けのいい問題ってありますか?
>>186 例えばだな
長さの違う文字列を100個ほどランダムで生成して
それを長さでソートするとか
ただし配列はポインタ配列でポインタでソートすること
hello worldを以下の関数を使って書け。ただし関数はポインタ経由で呼び出すこと。 void h() { printf("h"); } void e() { printf("e"); } void l() { printf("l"); } void o() { printf("o"); } void w() { printf("w"); } void r() { printf("r"); } void d() { printf("d"); } void space() { printf(" "); } これが書けたらポインタの初心者は脱却したと思っていいんじゃないかな。
頑張ってやってみます。 ところで、標準入力から数字(例えば99)を得たい場合に関数を使うと思うんですが、 gets getchar fgets scanf の使い分けはどうすればいいでしょうか?
>>190 まず、getsとscanfは使わない。
以下に対して画面から9を入力すると何故か57が返ります… #include <stdio.h> main() { int b = 0; printf("1桁の数字を入力して下さい。\n"); b = getchar(); printf("%d\n", b); }
>>192 printf("%c\n", b); にすればいい。
それは、'9'の文字コードが表示されてる。
>>193 ありがとう。直りました。
でも変数bは最初にintで定義していて、getcharもintで返すって思ってます。
なぜprintfでint出力する%dが駄目なのでしょう?
ちなみにputcharは使わないほうがいいでしょうか?
>>194 なぜって言われても。
c = getchar(); で入力された文字の文字コードがcに入る。
printf("%d", c); で文字コードが表示される。
printf("%c", c); で文字コードの文字が表示される。
としか言いようがない。
putchar()でもいいよ。
>>192 getchar(), putchar(), "%c"は文字を扱う。
一方、"%d"は数値を扱う。
rubyとか使ってる奴もそういう疑問持つんだろうな そんなレベルの奴が作ったもん納入してもらいたくないわ 恐い恐いw
入力された数字を受け取って、それを出力するには、 どの関数を使うのが普通なんでしょうか? 教科書にはgetsやscanf,などが普通に使われていますが、実際は 使われていないんですよね。
>>198 使われてないね。
fegts(s, sizeof s, stdin);
で入力を受け付けて、変換関数を使う。
複雑な書式ならsscanf()あたり。
数値だけならatoi()とか。
エラーチェックをしっかりする必要があるなら strtol()とか。
gets(&buff) は、buff のサイズ以上のキー入力があるとオーバーフローするから使わない。 scanf("%s", &buff) も同じ理由。
>>200 scanf()はscanf("%100s", s)とすればバッファオーバーフローは防げるけど、
サイズを定数で埋め込まないといけないのがダサいな。
format文字列を動的に生成すればいい。
scanf系って %*s とか使えないんだっけ?
scanfのフォーマットには%*sはあるから使えるよ
%[...], %[^...]って結構凄そうなんだけど 使い方いまいち分らないんですけど。 どう使うのか教えてください
>>204 scanf()の"%*s"はprintf()の"%*s"とは意味が違う。
>>206 "%99[^\n]"として空白も含む文字列を取得するとか、使い道は色々ある。
>>208 "%99[^\n]" でなんで空白も含む文字列を取得出来るんですか?
トークン分割取り込みとか出来るんですか? たとえば
AAA BBB CCCC ZZZZ 3333\n
空白をトークンとして
AAA、BBB、CCCC、ZZZZ、3333 を取り込む
マッチする文字列範囲を取り込む
AAA*CCCC とした場合
AAA BBB CCCCを取り込む
とか出来るんですか?
>>209 何を言いたいのか判らん。
>"%99[^\n]" でなんで空白も含む文字列を取得出来るんですか?
除外文字セットで改行文字を指定しているから。
>トークン分割取り込みとか出来るんですか? たとえば
トークンを除外文字に指定すればいい。
>空白をトークンとして
"%[^ ]"でもいいけれど、それなら普通に"%s"でいい気もする。
>マッチする文字列範囲を取り込む
そんな器用なことはできない。
「C言語の切り札」という本の問題を読んだりしてるんですが、 どういう発想から変数や関数(およびその引数)、全体のロジックを 決めてるのかさっぱり分かりません。 なきたい…
合わない本はとっとと切り捨てろ 3,5,7,9...年経ったらまた読み返してみるといい
試験対策本なのか なら今回は諦めるんだな
Amazonの評価はよさげだけど 解らないなら、諦めて 本屋で立ち読みで自分のレベルにあった本をさがせば
#defineで定義されたものやテンプレートが変換された後、生成されたコードを確認する方法はあるのでしょうか? 使用環境はVS2005です
>>216 #defineは
>>217 の通り。
テンプレートはないと思う。 一応、テンプレート中でエラーになったときはどんなテンプレート引数で呼ばれたのか表示してくれたりはするけど。
GAlib(
ttp://lancet.mit.edu/ga/ )を使ったことある方がいたら教えてください。
GAPopulation::writeはちゃんと実装されてるのに、GAPopulation::readの実装が空なのはなぜなんでしょう?
ファイルへの書き込みはできるのに、読み込みができないのは不便で仕方ないです。
ファイルからの読み込みはどうやればいいのでしょうか?
220 :
デフォルトの名無しさん :2009/04/29(水) 18:29:41
C4996の警告が出て困ってます。 _SCL_SECURE_NO_WARNINGS を指定すれば出ないと書いてあるのですが、 #pragma warning(disable,4996) と書いても出ます。どうすればよいでしょうか。
急募:エスパー
222 :
デフォルトの名無しさん :2009/04/29(水) 18:35:15
変な書き方ですいません。コンパイラオプションを指定する方法を教えてください。
コンパイラは何をお使いで?
225 :
デフォルトの名無しさん :2009/04/29(水) 18:39:52
コンパイラというか、Visual Studio2008をつかってます。
>>224 見ると、
>#pragma warning(disable,4996)
#pragma warning(disable:4996)
カンマじゃなくてコロンみたいだが
228 :
デフォルトの名無しさん :2009/04/29(水) 19:10:38
指定方法を間違えてたんですね。
でもまだ出ます。警告のある呼び出しをやっている箇所のあるファイルごとに
Pragmaを書かないとだめそうです。
>>226 20代後半くらい。
プロジェクトのプロパティで指定すればいいでしょ。 全ファイルに効くよ。
230 :
デフォルトの名無しさん :2009/04/29(水) 19:27:14
プロジェクト→C/C++→プリプロセッサ→定義 とやればいいですか?
>230 その若さで自分で調べない病に罹患されているようでご愁傷様です。 プロジェクト→C/C++→詳細→指定の警告を無効にする、で 4996 を入力。
232 :
デフォルトの名無しさん :2009/04/29(水) 22:01:46
すいません。 どうもやり方が色々あるようなので、どれがいいのか知りたいと思って聞きました。 ありがとうございました。
233 :
デフォルトの名無しさん :2009/04/30(木) 00:16:50
head.hというヘッダファイルはあるでしょうか?
>>233 あるんじゃないでしょうか?
ちなみに私はさっき自分でつくりました
あなたの環境に有るかどうかはわかりません
作成済みのオブジェクトを初期化したいんですが、コンストラクタを後から呼び出すことはできないんでしょうか。 オブジェクトを破棄して新規作成するしかないんでしょうか。 また、シングルトンパターンを適用しているオブジェクトに対してはどのように初期化を行えばよいでしょうか。
コンストラクタと初期化関数とを別にするだけじゃダメなのか
なるほど。コンストラクタ内で初期化関数を呼ぶでも問題ないですかね。
いやん
オブジェクトの初期化は大抵コンストラクタでやっちゃう 遅らせたい場合は遅らせたい機能を別のクラスにしてコンポジションを使う 初期化関数なんてアンチパターンだよ
>>235 placement newでできる。
ところで、ふとおもったが、ローカル変数に対して呼び出すのはどうなんだろうな。
こんなの。
struct A
{ } ;
int main()
{
A a ;
a.~A() ;
new(&a) A() ;
}
スタックやヒープに入ってるのなら何の問題もないっしょ const 掛けた変数が何処にあるかでジッソウイゾンガドウタラコウタラと騒ぎ出す輩への釣餌になるかも知れんが
243 :
241 :2009/04/30(木) 13:31:01
うーん、PODでないかぎり、規格的には未定義だろうなこれは。
コンストラクトかけてるんだからPOD非POD関係ないんじゃね?
12.4.14 Once a destructor is invoked for an object, the object no longer exists; ってのが気になる 存在してないっていうのはどういう事なのか?
>>243 大丈夫みたいだよ。
規格の 3.8 Object Lifetime p7 の Example がこうなってる。
[Example:
struct C {
int i;
void f();
const C& operator=( const C& );
};
const C& C::operator=( const C& other)
{
if ( this != &other ) {
this->?C(); //lifetime of *this ends
new (this) C(other); // new object of type C created
f(); //well-defined
}
return *this;
}
C c1;
C c2;
c1 = c2; // well-defined
c1.f(); //well-defined; c1 refers to a new object of type C
?end example]
>>241 それならデストラクタも自動的に呼ばれるから使えそうな気がするけど。
再初期化なテクニックになるのかな。再初期化テンプレート関数ってのも面白いかもしれないな。
248 :
241 :2009/04/30(木) 13:59:22
うーん、規格だと、何にも言われてないんだよ、これが。
と思っていたら、こんな文面もあった。
>Once a destructor is invoked for an object, the object no longer exists; the behavior is undefined if the
>destructor is invoked for an object whose lifetime has ended (3.8). [Example: if the destructor for an automatic
>object is explicitly invoked, and the block is subsequently left in a manner that would ordinarily
>invoke implicit destruction of the object, the behavior is undefined.
うーん、
>>241 はwell-formedに思えてきた。
ただし、placement newをしている途中に例外を投げたら死ねる。
>>246 おっと、そんなものが。
大丈夫そうだね。
249 :
241 :2009/04/30(木) 14:03:41
>>245 その辺も気になったんだよね。あくまで妥当なオブジェクトが存在しなくなると言う意味だけならいいんだが。
オブジェクトを載せているメモリはどうなるのか。
デストラクタはそのオブジェクトのスコープの終わりに自動的に呼び出されるのであって、
その間、オブジェクトがどう扱われようと関係なく呼び出されるらしいが、
>and the block is subsequently left in a manner that would ordinarily
>invoke implicit destruction of the object
となっているから、メモリはスコープの終わりまで残るものと考えていいのか。
241 は、ひとりごとを繰り返す前にまず 3.8 Object Lifetime をじっくり読むべきだ。
251 :
241 :2009/04/30(木) 14:17:08
>>250 読み終わった。なるほど、大丈夫そうだ。
でも、
>>241 の有用な使い方は思いつかないな。
252 :
235 :2009/04/30(木) 14:38:18
自作ゲームを作っていてキャラクターが死亡した際に初期化してステージの最初からやり直す処理を作ってました。。
ゲーム作るんだったらコンストラクタとデストラクタは使わずに それぞれ別メソッド用意して明示的に呼び出したほうが後々楽だよ
>>252 それじゃ、ふつうに新しいオブジェクトを作ればいいとしか言えないな。
まだ話を続けたいなら >238
>>253 なんで「ゲーム作る」という条件でそんなところの方針が変わるんだ?
>255 そっちの本職だから。 他の分野のことは確定的に言えないし
>>256 パフォーマンスの問題?
リソースの問題? (狭いメモリ空間で断片化を極力避けたい とか)
>>256 別にあんたの身分はどうでもいいよ。
コンストラクタとデストラクタを使わないほうがいい理由って何なの?
一般的には >240 にもあるように初期化関数なんてバグの元でしかないんだが。
せっかくデストラクタで自動になった破棄まで明示的な関数呼び出しにするなんて
正気の沙汰とは思えない。
コンストラクタの実行順番が一番の原因かな あとは無理矢理再利用したいときが多々あるくらいで これらはメモリが足りないということを回避するために バッファはstaticで確保しておくことも関係するかも (デバッグの手間を省くため) まぁ余計な一言だったらしいから完全撤回して以後黙る
260 :
259 :2009/04/30(木) 15:08:35
ごめん一部訂正 実行順番というより実行タイミングだ それぞれグローバルに置いた時のね
data status(ini_value); if(status.dead) status = data(status.stage_value); みたいにするんじゃないかな
>>259-260 いろいろ突っ込みどころがあるような気がするけど、撤回して黙るってことなんで、もういいや。
241ってAのコンストラクタが例外投げたらどうなるの?
>>263 明示的なデストラクタ呼び出しによってすでに生存期間の終了したオブジェクトに対して
スコープアウトでのデストラクタ呼び出しが行われ、その結果として未定義動作に入る。
ですよね
>>252 死亡時にスコープから出るようにしてやればきれいさっぱりなくなるんじゃないか。
267 :
デフォルトの名無しさん :2009/04/30(木) 18:57:38
デザインパターンのオブザーバーバターンのC++のサンプルでわかりやすいのはないでしょうか? どうも説明を読んでも分かったような気にはなるのですが、いい例がなかなか見つからず、 ピンときません。どうかお願いします。
オブザーバなんてデザパタの中でも分かりやすい部類だと思うけど。
中心になるのは Observable のほうなんで、名前と実態がちょっとつながりにくいんだよな。
class ostream; これは何をしてるの?
>>270 ostream という名前のクラスを宣言している。
途中で送ってしまいました。 class ostream; template< class S, class T> class Hoge; template<class S, class T> ostream &operator << (ostream&, const Hoge<S, T>&); これは何をしてるのでしょうか?
<<演算子オーバーロードの宣言
これコンパイル通らないような?
C言語の可変引数の関数について質問があります。 void func1(char *format, ...) { func2(format) } void func2(char *format, ...) { va_list ap; va_start(ap, format);
276 :
デフォルトの名無しさん :2009/05/01(金) 02:17:59
書きかけで送信してしまってすみません。 C言語の可変引数の関数について質問があります。 以下のように可変引数の関数を入れ子にして、 func2()の中でvfprintfを実行するとSegmentationFaultになります。 何が問題なのでしょうか?よろしくお願いします。 void func2(char *format, ...) { va_list ap; va_start(ap, format); vfprintf(stdout, format, ap); va_end(ap); } void func1(char *format, ...) { va_list ap; va_start(ap, format); func2(format, ap); va_end(ap); } int main() { char *str = "test"; int i = 1000; func1("%s %i\n", str, i); return 0; }
>>276 これでいいだろ。
void func2(char *format, va_list ap)
{
vfprintf(stdout, format, ap);
}
278 :
デフォルトの名無しさん :2009/05/01(金) 04:55:19
>>268-269 observableが実数で、observerが関数の引数として渡されているような、そんなソース
(すごく分かりにくい)を渡されて、機能追加するように言われたのですが、ぜんぜん進捗が
ありません。
observableとなっている実数が変更されると、関数がよばれて再計算が行われるように
なっているようなのですが。
サンプルじゃなくてもいいので、Observerパターンがどういう場合に使われるのが教えてください。
ちなみに自分のデザインパターンの知識は、ストラテジーと、シングルトンくらいです。
MFCを使ってツール作成しています。 ダイアログバーをツールボックスのように使用しており、 メニューから該当ツールボックスの表示非表示をして、なおかつ該当メニューにチェックのONOFFを入れる 処理は完成しました。 ここで行き詰ったのですが、ダイアログバーの×ボタンを押した時に表示状態の整合性が取れなくなってしまいます。 これはどういうイベントに対する処理を入れるべきでしょうか?SPY++を使うと自分のPCがフリーズしてリセットボタンしか対応策なくなるので 使うのをやめてます。 また、メニューからの表示非表示はShowControlBar関数を使用してますが、 その関数使用することで×ボタン押下時と同じ処理が走ってしまうのではないかとも思ってます。 ググってみてもメッセージをフックするやらなんやら難しそうな事が書いてありますが、 ツール作成者なら誰でも躓きそうな問題だと思うのですが簡単に解決する方法はありますでしょうか? ×ボタン自体は残して機能させたいと考えています。 よろしくお願いします。
>>278 あるオブジェクトがあり、それは可変個の子オブジェクトを持っている。
加えてそれらのオブジェクトが持つ内部状態の計算は複雑なのでupdateメンバ関数で行うとする。
子の状態は親の状態に依存しているので、親オブジェクトの状態を変更したら
子オブジェクトの状態も変更しなければならない。
当然、親のupdateから子のupdateも呼び出させるようにするだろう。
これでObserverパターンの出来上がり。
ぶっちゃけ新聞配達パターン(登録&配信)に改名したほうがいいと思う。
>>278 Observerパターンの典型的な実装は次の通り。
(2.で通知するときにObservableを引数とすることもある)
1.Observable(監視可能なオブジェクト)にObserver(監視役)をAdd
2.Observableに変更があった場合、1.で追加したObserverに対して、Observable内から通知
実際のアプリで言うと、モデル(データの実体を持つオブジェクト)と
ビュー(データを表示するオブジェクト)がObservableとObserverの
関係になることが多いかな。
データが変更されたらビューに通知してもらい、ビューは変更された
データの内容に基づいて表示内容を更新する、という具合。
下記も参考に。
http://ja.wikipedia.org/wiki/Observer_パターン
283 :
276 :2009/05/01(金) 10:46:38
>>277 その方法は知っているのですが、入れ子にしたい場合に
どのようにすればいいのか分からないです。
va_arg()で1つずつfunc2NO
284 :
276 :2009/05/01(金) 10:59:42
>>277 その方法は知っているのですが、入れ子にしたい場合に
どのようにすればいいのか分からないです。
va_arg()で1つずつパラメータをfunc2の引数として
指定するしかないのでしょうか?
無理。
>>284 可変長引数の関数を別の可変長引数の関数から再利用したいなら
va_list を受け取るバージョンが必要。
それが要らないんなら標準に vfprintf() が存在する理由も無かっただろうね。
287 :
276 :2009/05/01(金) 11:48:03
やはりva_listを渡さないと駄目なんですね。 ちょっと経緯を話しますと、func2がC++のクラスメソッドとしてあって、 それをC言語からどう呼び出すんだ?というのが疑問でした。 もしfunc2もC言語の関数だったら直接呼ぶんですけど…。 無理やり入れ子でやるとしたらマクロ関数を噛ますしか思いつきません。 #define fnc1(format, ...) func2(format, __VA_ARGS__)
>>287 va_list を受け取るバージョンを追加すればいいじゃないか。
それが無理だとしても C でマクロ使うことに何か不満でもあるの?
ついでに、その __VA_ARGS__ の使い方だと fnc1("x") みたいに呼び出したときに
エラーになるよ。
289 :
276 :2009/05/01(金) 12:32:54
>>288 マクロ関数は引数の型があいまいなので、
個人的に使いたくないだけです。
>ついでに、その __VA_ARGS__ の使い方だと fnc1("x") みたいに呼び出したときに
>エラーになるよ。
そうなんですか?そうすると、、、
va_listを引数に持つメソッドを用意してもらって、
さらにそれをC言語で使うためのラッパー関数を作る、
それしか方法がなさそうですね。
>>289 可変長引数使うところで型があいまいとか、中途半端なところ気にするのね。
__VA_ARGS__ の話は「使い方」さえ修正すれば問題ないよ。
結局のところ最善の選択肢に落ち着いたみたいなんで、それでいいんだけど。
>287 >ちょっと経緯を話しますと、func2がC++のクラスメソッドとしてあって、 >それをC言語からどう呼び出すんだ?というのが疑問でした。 C++で可変長引数関数を定義しようというのがそもそも間違ってない?
基本的にはそうなんだろうけど、 C が混ざるような現場では printf() 互換の 書式指定が使えたほうがいいことはあるかもしれない。
ちょいと相談。bsearch()の使い方の問題なんだが、このような構造体と比較関数を用意して、 -- typedef struct { char item_id[ITEM_ID_LENGTH]; someType someMember; }; int CompareItemId(const void * a, const void * b) { return strcmp((char *) a, ((ITEM_t *) b)->item_id); } -- このように呼び出すのって、keyと各要素の型が違うけど合法なんだろうか。 -- ITEM_t * pnt = (ITEM_t *) bsearch("item name", itemTable, numItem, sizeof(ITEM_t), CompareItemId); -- 実は移植する羽目になったこのソース、bsearch()の前にソートしていないと言う異常品。 移植前に本当に動いてたのか些か疑問なのだが、案外入力は運用でソート済みのデータしか与えてなかったのかもしれない。 移植に当たっては(明文化されていない)運用制限はなくさないといけないのでqsort()を掛けるのだけど、 qsort()ではこの比較関数を使うわけにはいかないしねぇ。
>>293 問題ない。
比較関数の第1引数が bsearch() に渡されたキーで、第2引数が配列要素を指すって決まってる。
7.20.5.1 The bsearch function
void *bsearch(const void *key, const void *base,
size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
...
The comparison function pointed to by compar is called with two arguments that point
to the key object and to an array element, in that order.
295 :
293 :2009/05/01(金) 13:32:54
>>294 情報THX。
んじゃ、お昼食べたらqsort()用の比較関数作るとするよ。
>>294 おそらくほとんどの処理系において
typedef struct {
char item_id[ITEM_ID_LENGTH];
someType someMember;
}ITEM_t;
ITEM_t a;
のとき(型は違うが)アドレスは &a == a.item_id になるから大丈夫なだけであって
本来は第一引数の型は ITEM_t * でなければならない
298 :
294 :2009/05/01(金) 14:04:51
>>296-297 何を根拠にそんなことを言うのかね?
294 で引用した箇所より少し後にある配列に対する要件は以下のとおり。
The array
shall consist of: all the elements that compare less than, all the elements that compare
equal to, and all the elements that compare greater than the key object, in that order.
んで、それに添えられた「注釈」にこうある。
In practice, the entire array is sorted according to the comparison function.
要件を単純なソート済みというものよりも緩くして、引数の順番に対する規定も合わせて、
>293 のような使い方を意図的に認めていると考えられる。
リンクされたドキュメントを見ると Linux ではダメなのかもわからんけど、 C99 準拠と
書いておきながら要件が厳しくなってるのはおかしい。
>>298 これの動作結果はどうなりますか?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct{
int id;
char name[100];
}ITEM_t;
int compare_id(const void *a, const void *b){
ITEM_t *x=(ITEM_t*)a, *y=(ITEM_t*)b;
return x->id-y->id;
}
int compare_name(const void *a, const void *b){
ITEM_t *x=(ITEM_t*)a, *y=(ITEM_t*)b;
return strcmp(x->name, y->name);
}
int main(void){
ITEM_t data[]={{4,"apple"},{1,"banana"},{3,"grape"},{2,"cherry"},{5,"orange"}};
ITEM_t key={5, "banana"}, *p;
qsort(data, 5, sizeof(ITEM_t), compare_id);
p=bsearch(&key, data, 5, sizeof(ITEM_t), compare_id);
if(p) printf("%d %s\n", p->id, p->name);
qsort(data, 5, sizeof(ITEM_t), compare_name);
p=bsearch(&key, data, 5, sizeof(ITEM_t), compare_name);
if(p) printf("%d %s\n", p->id, p->name);
return 0;
}
300 :
293 :2009/05/01(金) 14:35:13
間抜けがいる……
>>299 正しい結果が得られるわけのないコードの動作結果を聞いてどうするの?
>>298 >>293 のままだと
>>293 の構造体
typedef struct {
char item_id[ITEM_ID_LENGTH];
someType someMember;
}ITEM_t;
を次のように変数の宣言順序を変更すると正しく動作しなくなる
typedef struct {
someType someMember;
char item_id[ITEM_ID_LENGTH];
}ITEM_t;
ってのがいいたかった
302 :
299 :2009/05/01(金) 14:39:34
303 :
299 :2009/05/01(金) 14:51:34
>>299 のコードは正しい
が、何に対しての話か間違ってた
スマン
304 :
デフォルトの名無しさん :2009/05/01(金) 15:04:21
コピーコンストラクタをインライン指定で定義するのって、なにか意味がありますか?
>>304 インライン指定自体に余り意味がありません。
>>301 >295は別の関数を用意すると言っているのだから大丈夫だろ。
>>299 ↓こんなん出たけど、これが何か?
5 orange
1 banana
>>301 C99 規格に沿った実装の範囲であればそんなことにはならないはずなんだけど、
何を根拠にそんなことを言うの?
>>304 他の関数と同じ。コピーコンストラクタだからって何も変わらない。
308 :
299 :2009/05/01(金) 15:24:18
309 :
デフォルトの名無しさん :2009/05/01(金) 23:46:39
使いたい関数の引数の型がchar *型なんです そして自分はstring型を使いたいのですが、string型はconst char *型と 認識されてその関数に渡せません 何か解決する方法があるでしょうか?
その関数がchar *を変更しないことが明らかなら、string::c_str()をconst_castして渡す。 変更するならstringを使うべきではない。
>>309 俺だったらc_str()をstrlen()+1でnewかけてそれを関数に渡した後
帰ってきたらdeleteするな
返す必要がないならauto_ptrという手もあるし
あ、でも呼び出し先の関数は変更できないのか
>>312 auto_ptrはnew[]したメモリを正しく解放できない。
315 :
デフォルトの名無しさん :2009/05/02(土) 00:10:30
やっぱり中身を変えるならstringを使うべきではないんでしょうか stringが便利なのでできればstringで統一したかったんですが・・・
boost::shared_arrayという手があるな
vector<char>でも十分な気がする。
その使いたい関数ってのがC標準のstrなんとか系だとしたら、 大抵はstringで同じ事をする方法がC++に用意されてるからそんな物使うな
319 :
デフォルトの名無しさん :2009/05/02(土) 00:20:28
皆さんいろいろ助言ありがとうございました 大変ためになりました
Trick Library 'dagger'のxstring.hを使うのが手軽
321 :
デフォルトの名無しさん :2009/05/02(土) 00:37:25
std::vector<int> vec; // vecに色々とpush_back() std::list<int> li; std::copy(forward_iterator(li), vec.begin(), vec.size()); ベクタからリストに要素をコピーしようとしてこう書いたのですが、コンパイルできません。 どうしてでしょうか?
std::copy(vec.begin(), vec.end(), back_inserter(li));
323 :
デフォルトの名無しさん :2009/05/02(土) 01:02:06
324 :
デフォルトの名無しさん :2009/05/02(土) 01:15:36
上で質問したものです。 std::list<int>の中にユニークな数字が入っている時に、与えられた数字を検索する場合、 イテレータを使ってForループを見つかるまでまわして検索するよりも、std::find()を 使ったほうが速い(手元のノートブックだと3倍くらい)ような結果になるのですが、 なにか間違ってるでしょうか? 重ね重ねすいません。
forの方が途中で見つかっても打ち切らずに最後まで回すようなアホコードになってると推測
326 :
デフォルトの名無しさん :2009/05/02(土) 01:35:17
for (int i = 0; i < 2000; ++i){ #if 1 std::list<int>::iterator p = std::find(li.begin(), li.end(), i); #else for (std::list<int>::iterator p = li.begin(); p != li.end(); ++p){ if (*p == i){break;} } #endif } 測定したのはこんな感じのコードなんですけど、、、アホなコードにはなってないですよね?
STLの実装にも依存するけどfindアルゴリズムの方が 最適化に都合いいからじゃね?
例えば for (std::list<int>::iterator p = li.begin(), end = li.end(); p != end; ++p){ のようにすると、毎回list::end()を参照するコストが無くなる(std::find()はそうなっている)が これが原因かどうかは知らん。
>>321-322 std::list<int> li(vec.begin(), vec.end());
または
std::list<int> li;
li.assign(vec.begin(), vec.end());
今Cを勉強中なのですが cout cin のcってなんの言葉の略なんですか?
俺もながらく console の略じゃないかと思ってきたが、 >The header <iostream> declares objects that associate objects with the standard C streams provided for >by the functions declared in <cstdio> (27.8.2). って書いてあるんで、実はそのまま C なのかもしれない。
標準入出力、エラー出力っていう概念はC由来のものだから という意味のstandard C streamsなのかな?
禿がそう言うんならしょうがないな。
337 :
330 :2009/05/02(土) 13:55:25
>>331 C++でした・・
普通に間違えた^^;
>>334 "character"が一番しっくり来ますね
みなさんありがとうございました
338 :
デフォルトの名無しさん :2009/05/02(土) 14:14:01
Visual C++ 2008 にて、 TCHAR の文字列の長さを取得する際に _tcslen を使用しています Unicode 文字セットを使う環境の場合は、正常に文字数が取得できますが マルチバイト文字セットを使う環境では、strlen の動作になるので 文字数ではなく、全角文字を2バイトとするバイト数取得になってしまいます TCHAR から環境に依存せず文字数を取得する関数、マクロなどは SDKで提供されていますでしょうか? よろしくお願いします
>>338 たぶん無いと思う。
ネットとかでジェネリックテキスト(TCHARとか)使えって薦めてる人をよく見るけど、
WCHARとか_wcs系を使ってワイド文字だけ対応のほうがいいと思う。
_MBCS で文字数と言ったら、バイト数。だから問題なく正しい。
342 :
338 :2009/05/02(土) 14:31:56
レスありがとうございます 取りあえず、マルチバイト環境の場合は wchar_t に変換してから文字数取得するようにしてみます ありがとうございました
大学のC言語プログラミングの講義で、講義資料の例題には [A] for (int i = 0; i < n; i++) のように書いてあるのですが、友達に聞いたらこれはC++やJavaの 書き方で、Cでは [B] for (i = 0; i < n; i++) みたいに書かなくてはいけないということでした。これは大学の先生が 間違ってるということでしょうか。確かにいくつかの本をみても[A] みたいな書き方はしていませんし、コンパイラもエラーを出します。
gcc なら C99 のオプション付ければ [A] の記述も通る
>>343 Aみたいな書き方はC99という比較的新しいC言語の規格によるものです。
でもまだサポートしていないコンパイラも多いので、多くの人は昔ながら
の書き方で書いています。
授業の資料にコンパイルの仕方が書いてありませんか?
もう 10 年になるのにな。現実は厳しいぜ。
学生時代、授業ではFortran77を習ったけど、当時としては新しすぎて
参考書が少なくて苦労したことを思い出した。
まあ、がんばって勉強してくれ
>>343
中括弧で包んだ時にインデント付けない良い記述方法があれば変体しなくて済むのにね { int i = 0; for(;i<n;++i){ } }
350 :
343 :2009/05/02(土) 15:30:21
ありがとうございます。授業第1回目の資料をよく読むと、 gcc -std=c99 のようにせよと書いてありました。お騒がせしてすみません。 ただ手元にはLSI-C86試食版というコンパイラしかなくて、 これではうまくいかないようです。
うわ、LSI-Cってまだあったんだ… 大学ではgccを使ってるみたいだから、MinGWかCygwinにしてgccを いれた方がいいと思うよ。
352 :
デフォルトの名無しさん :2009/05/02(土) 16:01:40
定数を定義をするときに#defineではなくconstを使ったほうがいいと 聞いたので、整数は const int STR_MAX = 256; とこのように定義したんですが、文字列を定義するときはどうするのが 一番良いですか? #defineを使うのが一番ですか?
文字列へのポインタの定数か、文字配列の定数だな。
文字列の一部を置き換えようと、 char *p = "test"; *(p+1) = '*'; //or p[1]='*'; のようにしたら実行時エラー(?)になって代入のところで止まってしまいます。 char p[] = "test"; *(p+1) = '*'; //or p[1]='*' のように配列で宣言すると正常に動作するようです。 文字列(のアドレス)で初期化したポインタでは操作はできないのでしょうか? 環境はWindowsVista、MinGWで、C++でコンパイルしています。
>>353 をよめ
(const) char *p = "test";
これは定文作成
char p[] = "test";
これは配列作成、初期化
>>354 文字列リテラルの書き換えは未定義動作なので、
そのような操作をしてはダメ
>>355-356 ご回答、ありがとうございます。
なるほど、データの確保方法が違うためなんですね。
未定義動作になっているということでスッキリしました。
配列のほうで作成するようにします。
関数の引数でもらったポインタについて、どちらで作られたデータか
を判別する方法はあるんでしょうか?
>>357 書き換えちゃいけないやつは const を付ける。
付いてなければ書き換えていい。
Effective C++ では char *p = "Any"; のように コンパイラが勝手に const はずししてしまう変換を「死の変換」と呼んでいた。 ところで、こういう初歩的な問題で苦悩する初心者を見るにつけ やはり K&R はバイブルだと感じる。 K&Rではちゃんとこの問題について注意が喚起されている。 (5.5 文字ポインタと関数 p.127-128 あたり)
char *p = "Any"; をコンパイルエラーにしないC、つまりK&Rがアホってことだろ
VC と BCC ではエラーにならんなぁ。
さらに理想に走ってデフォルトでconstにしてmutable指定するようにするべき
エラーになるほうがおかしいからw
>>360 だって、昔のCは実際に書き換えできるのが当然だったんだから。
そもそもK&Rの時代にはconstなんて無かったし。
導入されたのは最初にANSIドラフトが発表されてから。
constなんて無意味
・K&Rの時代 文字列リテラルは書き換え可能。const自体無し。 ・C89以降 文字列リテラルは書き換え不可領域に置くことが許される。 過去の資産との互換性から、強制const化は見送り。 ・C++ 何故か、強制const化しなかった。 void*からのキャスト等は強制されるようになったのに。
const つけてないのに勝手にconstあるように解釈するのが欠陥だよな const char* p = "Any"; と char *p = "Any"; は違う動作をして当然だよな
少なくとも K&R 第2版では文字列定数は書き換え不可(不定)になってる。 三日もあれば読める本なんだから、読んで損はない。
Windowsは実行時に文字列定数を書き込み禁止にできるのがせめてもの救いだな。
370 :
354 :2009/05/02(土) 18:18:15
皆さんのレスをもとにいろいろググったりして、より理解を深めることができました。 1990年くらいにプログラミング言語Cは読んだのですが、それ以来ゆるい言語しか 使わずふやけたプログラムばかり書いていたので、すっかり忘れてしまってます。 もう一度初心に帰って基本から学びなおそうと思います。 皆さんありがとうございました。
今、 char *p = "test"; *(p+1) = '*'; //or p[1]='*'; がOKな環境ってあるのか?
あまりにも文字列リテラルを非constなポインタに代入するコードが多くて、
許可するしかなかったんだろ。今更愚痴っても仕方ねえよ。
>>367 その認識は間違っている。
コンパイラが暗黙のうちにconstを外すキャストをしていると見るべき。
本来constだったポインタに書き込んだら、どうなろうと自己責任。
訂正 ×非constなポインタ ○非constなcharへのポインタ
char _p[] = "Any"; char *p = _p; というのを裏でこっそりやるのは無理だったのかな
>>368 K&Rは初版と第2版で全然違う。
第2版は、ANSIドラフト後に改定されたもので、C89とほぼ一致するが
初版はまったく違う。
「K&RのC」とは、初版の時代の「標準規格が無かった時代のC」を指す。
376 :
デフォルトの名無しさん :2009/05/02(土) 20:08:12
しかしなぜか今回だけは初心者にやさしいこのスレの住人たち。
>>376 ここは初心者歓迎スレだぞ
初心者に優しくない基地はこのスレでは荒らし
どっか別のスレで基地ろだ
typedef struct { unsigned Data1:8*3; unsigned Data2:8*3; unsigned Data3:8*3; unsigned Data4:8*3; } TestStrct; TestStrct TestSt; このときのsizeof(TestSt)の数値を12と期待したのですが16になりました。 12になる書き方はありますか? 環境はVC2008+XPです。
要約すると、K&Rの第二版を読んどけって話だな。
ビットフィールドを使う時点で、「全てが処理系依存」ぐらいと考えるべきだね。
>>378 アラインされてるんじゃないの?
VC2008ならやってみてないけど __declspec(align(8))
で行けそうな気がするけど
alignなんてしたら期待値が16だろ
少なくともC、C++の規格上は無理^^v
> __declspec(align(8)) typedef struct __declspec(align(8)) { 省略 と試してみましたが結果は変わりませんでした。 諦めて1バイトづつ読み込んで計算することにします。 ありがとうございました。
むしろ32bit読み込んで24bitのandを取れ。 どうせx86限定で、データのエンディアン等に依存しているんだろうから。
ここでunionだろ
intで書き込んだものをcharで読み出したりするのは不正行為です^^
#pragma pack(1)でもだめ?
だめだな
1,2,4バイトアクセスにしないとpuddingだろ。プリンはおいしいよな お前らもプリン好きだろ
詰め物はPADだろ
bool findFlag = true; で warning C4800: 'BOOL' : ブール値を 'true' または 'false' に強制的に設定します (警告の処理) が出るんですがどういうことですか?
boolかtrueがなんか細工されてるっぽいな とりあえず何のコンパイラでのコンパイラ書け
VC++9です。 すいません警告行は findFlag = fileFind.FindNextFile(); からでした。どういうことですか?
BOOL型をbool型へ強制的に変換するぞ意味分かってやっとんのかゴルァ ということです。
>>392 boolかtrueが#defineされてないか確認してごらん。C++では#defineされてなくても使える。
>>394 リターン値がboolじゃなくてBOOLだな > FindNextFile()
forやwhileのループ構文中で、switchで条件判断してループ抜けようとすると、 breakがswitch内にとらわれてしまうので、gotoでループ構文直後にジャンプするしかないですか。
>>398 gotoにするか、switchをifにするか。
ありがとうございます。
丸ごと関数にしてreturnで抜ける
C++ではマルチスレッドは危険なので 禁止だそうなのですが、マルチスレッドの代替ってありますか? 会社の偉い役職のアーキテクト?とかいう人がそういってました
マルチプロセスマルチタスク
>>403 > C++ではマルチスレッドは危険
ということはない。マルチスレッドの塊にようなJava本体だってC++で書かれてんだぞ。
その言葉は、正確には「能力の低いプログラマにC++でマルチスレッドプログラムを書かせると危険」だろう。
つまり > C++ではマルチスレッドは危険なので # (日本語の不自由なお前たちに)C++ではマルチスレッド(を使うプログラムを書かせるの)は危険なので
そのえらい一級建築士だっけ?に代わりになにつかえばいいですかー? って聞いて来い。上でOK出なければなに選んでも無駄になるだろ。
>>405 > 正確には「能力の低いプログラマにC++でマルチスレッドプログラムを書かせると危険」
「重要な部分とそうでない部分を切分けて設計できるアーキテクトが居ないと
危険」とも言えるな。
お前らは、C++でミッションクリティカルのマルチスレッドを十分書ける能力アル?
ミッションクリティカルとか言われると、どんな言語つかっても無理。
>>403 マルチスレッドを理解してないとどんな言語を使っても危険。
Windowsなら重複I/Oでマルチスレッドを使わずに並列処理ができるよ。
わざわざ危険って言うほどのものか? 変数のアクセス順序を気にするだけじゃん
412のような奴が危険極まりないマルチスレッドプログラムを書く
最低限「アトミックな操作」とは何かだけでも覚えておけ
あと出来たらデッドロック、スタベーション、レース状態は覚えよう
Javaだとマルチスレッド対応のコレクションクラスがあるから そういうことを気にする必要がありません。 C++は危険極まりない言語ですね。
同期の取れるコレクションクラスは確かに簡単な例では使えるけど、複数コレ クションの整合性を保とうと思うとあまり嬉しくない。 C++ だとロックオブジェクトをスコープ宣言して割と簡単かつ明示的に排他で きるんで重宝してる。ロックオブジェクトは一発めはスピンロックで、取れな かったらキューにいれるとかさ。 synchronized は重いんだよね。AtomicInteger 辺りを使うといいんだっけか。
Javaはライブラリが全部やってくれるからデッドロックなんて絶対に起こらない! とか自信満々に抜かす輩が蔓延ってるからなぁ
Javaのマルチスレッドも、糞だろwwww
JavaはC++の2〜3倍は重いんだから、その位の安全性は 備えてて当然
Erlang の並列処理に比べたらまったくだめだな。 Javaでも危険すぎる。 C++は話にならない。
けどやらなくちゃいけないんだろ?
>>422 が良いこと言った
安全な道を進めないことを嘆いても何も始まらない
それがじんせー
____ / \ /\ キリッ . / (ー) (ー)\ / ⌒(__人__)⌒ \ Javaはライブラリが全部やってくれるからデッドロックなんて絶対に起こらない! | |r┬-| | \ `ー'´ / ノ \ /´ ヽ ___ / \ /ノ \ u. \ !? / (●) (●) \ | (__人__) u. | クスクス> \ u.` ⌒´ / ノ \ /´ ヽ ____ <クスクス / \!?? / u ノ \ / u (●) \ | (__人__)| \ u .` ⌒/ ノ \
真性基地外が来るなんて....
>>424 、基地スレへ戻れ。
ここはお前の来る所じゃないぞ
変数を多数の関数で使いまわすことが可能な場合は極力辿って見に行った方がいいんでしょうか? それとも可能な限り変数を使いたい関数ごとに変数を導き出す処理を書いて独立性を強くしたほうがいいんでしょうか? いつも同じ値になる変数をメインの部分で一回だけ計算してそれを参照して関数内で使ってるんですが、関数の再利用とかしたことないんです これ重要ですか?どうすればいいですか?
いつも同じになる値ならあらかじめ計算して定数にしろよ
参照した時に同じ値の時をだけを抜き出して無駄のないように参照するようにしてるんです。 がちがちにいろいろなところを参照するよりは多少計算がダブっても独立性を強くしたほうがいいと思いますか?
>>428 簡単に書くとこんな感じでいいんじゃないか?
int hoge(int index){
static int table[N];
if(!table[index]) table[index]=calc(index);
return table[index];
}
言ってることが全然わからないが、計算の無駄を省きたいなら 関数内で計算結果をstatic変数に置いておいて、変更がなければそのまま返すようにすればいいと思う
>>428 その計算がそうとうな負荷にならない限り
余計な小細工はしないほうがいい
呼び出される回数だとか実行時間は
プロファイラを使えば大体分かる
やっぱりそこですかね。 自分なんかコード書く時行数の節約とかメモリの節約とかが先に来るんですが、再利用性が異常に低いというか なんか他のところでも使える気がしないんです。 やはり相当重い計算がダブることが無い限りは何度も同じコードを書くべきですよね でもなんか同じ部分を抜きだして関数にまとめてしまって結局いつのまにか関数どうしが網の目のようになって独立できないんです もっと細かく関数を1目的づつに分割して、ブロックを組み合わせるようなプログラミングができるようようにはやくなりたいです
>>432 何度も同じコードを書くのはできる限りやめておけw
共通処理を独立した関数にするってのは一般的にはいいことだけど、 プログラムセンスの無い人がやると、却ってスパゲティになるね。 複数の呼び元とのつじつまを合わせるために、その関数が10個ちかい 引数の数になったりとか
C++でクラスのメンバ関数について class Base0{ protected: int bs0; public: Base0(int b0=0){bs0 = b0;} //←ここのところ" } " か " }; " か void showBs(); }; 解説書に特にことわりもなく、"};"の例が出てきて、 試しにコンパイルしたらエラーもでなかったからどっちでもよさそうだけど なんか違うの? その本はほとんどのところは "}" だけど、一部"};"になってる
おそらくは校正漏れ この場合、実質同じ意味
>>436 "この場合"というのは厳密には
" } " と " }; "は区別されてるって事?
区別されるとすればどの場合?
・・・って聞こうと思ったけど
>>435 の最後の行のことか
厳密には空文が認識されてるけど ブロックを閉じるところで}と書こうが};と書こうが実質同じ意味
下記の結果が20のはずが10になっています。何が間違っていますか。 #include <stdio.h> class Test { private: int value; public: Test(void); void getValue(int*); void printValue(void); }; Test::Test(void) { value = 10; } void Test::getValue(int* x) { x = &value; } void Test::printValue(void) { printf("value: %d\n", value); } int main(void) { Test test; int* value; test.getValue(value); *value = 20; test.printValue(); }
↑ 初期化してない。それに値私。 test.getValue(value);
getValueはsetValueの間違いじゃないの?
なるほど。 該当行を↓にそれぞれ差し替えれば意図したとおりになると思うよ。 void getValue(int**); void Test::getValue(int** x) *x = &value; test.getValue(&value);
ダブルポインタ禁止
int* getValue(void); int* Test::getValue(void) { return &value; } value = test.getValue(); *value = 20; こうじゃね?
関数の引数にconstを付けると関数内で値の変更ができないのはわかったんですが 引数がポインタの場合は何がconstになるんですか?アドレスを変更できないんですか?アドレスの指定先の変数値が変更できないんですか?
前者
しかもconstの付け方によって変わる
>>446 いろいろと書き方があるので場合による
void myputs(const char *p); // void myputs(char const * p);
void myputs(const char * const p); // void myputs(char const * const p);
void myputs(char * const p);
>>446 C++プライマー買おうね?全部載ってるよ?
thx 引数に*じゃなくてクラスとか配列の場合もアドレスってことですよね ちょうど次買うのプライマーとエフェクティブどっちにしようかと思ってたんですプライマー先に買うことにしますどうもです!
#include <stdio.h> int main(){ int a; char b,c,d; c = 'z'; printf("10個の英字を入力してください\n"); for(a = 0; a < 10; a++) { b = getchar(); if (c > b){ c = b; } } printf("一番最初にくるアルファベットは%cです。\n", c); return 0; } これを実効するとうまくいかないのですが、何がだめなのでしょうか? このソースが載っていた本にgetcharはラインバッファ処理を採用しているのでなんとやら〜 と書いてあったのですが、それ関係なんでしょうか? ちなみにgetcharをgetcheに変えてconioというヘッダファイルをインクルードするとうまくいきました
if (c < b)
変数がどのように初期化されるのか教えてください。 以下のように、各変数を明示的に初期化しないで出力してみたところ、 # include <stdio.h> int global_var; static int global_static_var; int main(){ int local_var; static int local_static_var; printf("%d\n", global_var); printf("%d\n", global_static_var); printf("%d\n", local_var); printf("%d\n", local_static_var); } 出力結果は、 0 0 11277776 0 でした。 これは関数内の自動変数以外では、自動的に0で初期化してくれると考えていいのでしょうか? Javaの場合はintに限らず全ての型においてフィールドは自動的に初期化されるのが仕様で定められているので明示的な初期化の記述は不要です。 Cの初期化にも仕様が定まってるのでしょうか?あるいは処理系依存ですか?
意味のない実験だよな もし local_var も 0 になったら、どういう推論をしたんだろうか
未定であると言っている以上、未定以外の意味ずけをしてどうする? たまたま10000回0でも、次の1回が0以外でも、誰にも文句言えないぞ
グローバル変数は仕様上0で初期化される。BSSでぐぐれ ただしJavaのように厳格では無いから環境によっては確かではない。
BSS領域は知らんかった、しかし、あてにするなと書いてあるなw
>>453 それだと結果がzとなって失敗してしまいます
まあ元のままだと結果すらでないのですが・・・
どちらにしろ実効すると5回までしかforループが続かないし
なにが原因なんだろう
>>459 世の中にはな、0クリアすると1.0になる実数表現もあったりするね。
>>460 改行が残っててそれを読み込むから。
b = getchar();
の後に
fflush(stdin);
をするとか。(ただし、全ての環境で正しく動く保証はない)
fflushとか…
fflushを入力ストリームに使うと未定義動作だからよろしくない
じゃ while(getc() != EOF);
>460 enter読み取ったとか。 'a'〜'z'でなかったら読み直しにしたら? あとCAPS入って大文字で入力された場合は考慮しなくていいの?
>>462 >>466 ありがとうございます
たしかに改行も読み取ったことが原因のようでした
大文字読み取った場合の処理や例外の文字が入力されたときの処理はあとで付け加えときます
Win32APIを使って数値計算のプログラムを書いています。 時間のかかる計算中にウインドウをフリーズさせたくないので、計算の1ステップごとに メッセージ処理をさせることにしました。 ところが、計算中にウインドウを閉じるとプロセスが終了しないで残ってしまいます。 どうすればいいですか? よろしくお願いします。 WndProc() { case BUTTON_ID1: calculation(); //ボタン1が押されたら計算開始。 } WinMain() { while(GetMessage) { TranslateMessage; DispatchMessage; } } calculation() { for(長いループ) { //計算の1ステップ GetMessage; TranslateMessage; DispatchMessage; } }
それはアホの所業じゃ ちゃんとWinMainのメッセージるぷで処理しろよ。
>>469 すみません、メッセージるぷで何の処理をするんですか?
そういうのは、PeekMessageを使うか UIスレッドとは別のスレッドで計算するのが常道じゃないかね。
すみません。マルチスレッドは恐ろしい物らしいので使いたくないのです。 ですから、計算の1ステップごとにメッセージ処理をさせることにしたんです。
case BUTTON_ID1: SendMessage(hwnd,CAL_CONTINUE, ,);break; case CAL_QUIT:{後始末} break; case CAL_CONTINUE: if(calculation())SendMessage(hwnd,CAL_CONTINUE, ,);else SendMessage(hwnd,CAL_QUIT, ,);break;
C++だとシグナルも使えないし困ったもんだ
>473 この場合は calculation() を1ステップだけ計算するように書き換えた上で、 ということですよね? これはcalculation()を大幅に書き換えないといけないのでできたらやりたくありません。 Application.DoEventsメソッドのように数行適当な場所に付け足すだけでメッセージ処理を行ってくれるような方法はないのでしょうか?
だからそれはDoEvent内部でPeekMessageを使ったループを動かしてるんだっての
>>475 てめーの概念コードの通りならforの初期化に渡す変数をparamに持たして回すだけじゃねーの?
>477 すみません、例えでfor文1つで書きましたが、calculation()内はもっと複雑なんです。 1ステップだけ計算する関数にするにはかなり改造が必要そうです。 実を言うとこのような数値計算するコンソールアプリケーションがたくさんあって、 それを全部windowsで動くようにしないといけないんです。 できるだけもとのコードをいじらないで移植したいです。 >471 >476 PeekMessageを使った場合というのはこのような感じでいいのでしょうか? ボタンを押したときに開始させるにはどうすればいいですか? WinMain内にもメッセージループをもうひとつ作るのでしょうか? WndProc() { } WinMain() { calculation(); } calculation() { for(長いループ) { //計算の1ステップ PeekMessage(&msg) if(msg.message==WM_QUIT){return 0;}else{DispatchMessage(&msg)}; } }
480 :
478 :2009/05/05(火) 09:22:31
>479 なんかいろいろ間違ってましたね、、 結局こんな感じでいいのでしょうか? WndProc() { case BUTTON_ID1: calculation(); } WinMain() { while(GetMessage){TranslateMessage;DispatchMessage;} } calculation() { for(長いループ) { //計算の1ステップ if(PeekMessage(&msg)){ GetMessage;if(msg.message==WM_QUIT){return 0;}else{DispatchMessage(&msg)};} } }
>482 ああぁ、調べてみたけど難しいです。フラグを使って抜けるというのはこうで良いのでしょうか? BOOL run; WndProc() { case BUTTON_ID1: calculation(); } WinMain() { run=TRUE; while(GetMessage){if(run==FALSE){return msg.wParam;};TranslateMessage;DispatchMessage;} } calculation() { for(長いループ) { //計算の1ステップ if(PeekMessage(&msg)){ GetMessage;if(msg.message==WM_QUIT){run=FALSE; return 0;}else{DispatchMessage(&msg)};} } }
素直に別スレッドにした方が よほど楽だと思うのだが
今回に限ってはマルチスレッド信者の方が正道に近いな。
別スレッドにしても calculation を綺麗に終わらせるには フラグ(みたいな処理)になるんじゃないの?
スレッドを渡らなくても 「中間ステートを切り出せない程に複雑でメッセージ処理が滞る程処理に時間がかかる関数」に 再投入を防ぐフラグは必要だろう?
元々がコンソールアプリなのにWinMainというところが間違ってるんじゃないか? コンソールアプリとしてコンパイルすれば?
こういうのは一般的にマルチスレッドに「しなければならない」状況。 > マルチスレッドは恐ろしい物らしいので使いたくないのです。 などと言って逃げて、マルチスレッドにすればすぐ済むのにシングルスレッド にこだわって無駄に複雑化させるのは馬鹿の所業。 それでもどうしてもマルチスレッドが使いたくないなら、プログラムを 計算用のコンソールアプリと進行状況表示用GUIアプリの2つに分けて、 計算アプリは単に進行状況を標準出力に出力、進行状況アプリは計算アプリ をサブプロセスで起動してその標準出力をイベントで拾い、画面表示 すればいいんじゃない? いや、計算アプリにウィンドウメッセージを投げてもらった方が楽か? (WIN32APIはよく知らんので)
GUIと数値計算の並列化なんて、同期すべき箇所なんて簡単に把握できるでそ
なんでもかんでもマルチスレッドにする馬鹿よりはマシかな
たまたま己より先を行く愚者と比して勝利したからといって調子に乗るなマルチスレッド信者って事で
文字列sの末尾の数字を消そうと、 s.erase( s.find_last_not_of( "1234567890" ) + 1 ); としているんですが、sが数字だけだったら s.erase( s.npos + 1 ); が行われていると思うんです。 この時予定通りsは""になるんですが、npos + 1が0になることは決まってるんですかね。。。
>>493 ググってみたら、-1とはかぎらないって書いてるページもあるね。
495 :
494 :2009/05/05(火) 21:29:11
nposが。
ぜんっぜん決まってないので依存するな怖いから。
規格だと static const size_type npos = -1; ってなってるね。
unsignedなんだけどね。
unsigned で -1と決まってるなら、+1したら0だけど、本当に-1?
なんで-1なんだろうな。 アンダーフローした時の挙動は決まっていないが、決まっていないと言うことは、 別にエラーにしなければならないというわけでもないからな。 とはいえ、現行ではconstexprがあるわけじゃないので、 static const size_type npos = std::numeric_limits<size_type>::max() ; とはできないしな。 なんでnumeric_limitsは関数にしたんだか。
>>499 >unsigned で -1と決まってるなら、+1したら0
そうとは限らない。
21.3にbasic_stringの定義が書かれてるけど、そこではハッキリ static const size_type npos = -1; と決められている。 で、size_typeというのはAllocator::size_typeのtypedefになっていて、 Allocatorはbasic_stringのテンプレートパラメータとして指定するアロケータ で、20.1.5でアロケータの要件としてsize_typeはunsigned integral typeであるべしと要求されてる だから規格に違反した自作アロケータがsize_typeに変な型を指定したりしてなければ多分大丈夫
503 :
501 :2009/05/06(水) 02:01:58
-1のところじゃなくて、+1したら0になるというところね。
>>501 確実に決まってるよ
unsigned整数は2^nを法とする演算に従わなければならないと決められてる(nは表現可能なビット数)
3.9.1のパラグラフ4参照
しかしね、それはオーバーフローの場合であって、アンダーフローの場合には何とも言えないぜ。 注41にも、オーバーフローしないとしか書かれてない。
「オーバーフローの場合」なんて3.9.1-4のどこにも書いてないし、 そもそも負の方向にはみ出すこともオーバーフローの一種だ アンダーフローという言葉は全然違う意味を指す(浮動小数点数が小さくなりすぎて表現できなくなること) といっても納得しなそうだから順番に説明する まず-1というのはint型のリテラルだ(厳密にはリテラル1に単項-演算子を適用したint型の結果) それがsize_typeの初期化に使われるから、-1がsize_typeに変換される この時何が起こるかは4.7で規定されていて、変換元と2^nを法として合同な、 変換先で表現できる最小の値に変換されると決まっている。 つまり、-1は2^n-1に変換されて、nposは2^n-1で初期化される で、これに1を足すことを考えると、 (2^n-1)+1は2^nだが、これはsize_typeでは表現できないので 2^nを法として合同で表現可能な値、つまり0になる これは505で言う所の正真正銘の「オーバーフロー」だから文句はないだろう かくしてunsignedの-1に+1すると0になることは間違いなく規格で保証されている よろしいか
507 :
デフォルトの名無しさん :2009/05/06(水) 05:05:14
自分のソースじゃないのですが、C++のクラスがあってその内部にdoubleとかを持っているのですが、 それがprivate:でもpublic:でもなくprotected:に置かれてます。これって何か意味があるのでしょうか?
>>506 よろしくない。
-1をunsingedな整数に代入した時点で、その値は不定、
不定な値に1を足しても、不定なままであることに変わりはない。
>変換先で表現できる最小の値に変換されると決まっている
がどうして、
>つまり、-1は2^n-1に変換されて
になるんだ? unsinged型の表現できる最小値は0だぞ。
-1を代入してどうなるかは実装の問題なんだよ。
まさか、整数は2の補数で表現されなければならないと規定されている、と思っているんじゃないだろうな?
>>507 派生クラスからアクセッサを経由せずに操作したい理由があるのだろう。
>>507 ただ単に外から見えなくしたいだけでしょ。
vectorやlistなどのSTLの実装は データメンバはprivateではないのが殆ど。 というかprivateにある実装を見たこと無い。publicな実装もある。 まあ理由は、stackなどで使うためだと想像されるが。
512 :
デフォルトの名無しさん :2009/05/06(水) 09:49:41
横からすみません、宜しくおながいします。
gcc バージョン 4.2.4
wgetを、外部プログラムとして、起動したくてこのようにしましたら
poppen: Invalid argument
となります、引数が無効、poppenへの引数の与え方がまずいといっているのですが、manを見ても何処が間違っているのかわかりません、ご教示願います。
#include <stdio.h>
#include <stdlib.h>
#define BUFSIZE 256
int main(void)
{
FILE* p = popen("wget", "
http://www.foo.com/ ");
char buf[BUFSIZE];
if( p == NULL ) {
perror("poppen");
exit(EXIT_FAILURE);
}
while((fgets(buf, BUFSIZE, p)) != NULL){
printf("%s", buf);
}
pclose(p);
return 0;
}
>>513 よく読め。
>manを見ても何処が間違っているのかわかりません
>>512 popenの第2引数は読み書きのモード指定で、第1引数はコマンドだけ
ではなくコマンドライン全体とmanにわかりやすく書いてある。
今回の場合は
popen("wget
http://www.foo.com ", "r")
みたいになるんじゃないかな。
つか、manが読めないってバカ?
>>508 > -1をunsingedな整数に代入した時点で、その値は不定、
だったらnposが-1ってのはガセかね。
517 :
デフォルトの名無しさん :2009/05/06(水) 10:47:16
>>511 > まあ理由は、stackなどで使うためだと想像されるが。
これはどういう意味ですか?
継承して使うためってことじゃ?
超初心者の質問なんですけど 課題で、2数の四則演算機能しかない電卓のプログラミングがでたんですけど、さっぱり出来ません 35+468 と入力したら、 35+468=503 とでる感じです。 C言語でemacsを使ってます。 誰か親切な方がいらしたら、よろしくお願いします。
>>519 #include <stdio.h>
int main()
{
int a, b;
char op;
scanf("%d%c%d", &a, &op, &b);
if (op == '+')
printf("%d + %d = %d\n", a, b, a + b);
else if (op == '-')
printf("%d - %d = %d\n", a, b, a - b);
else if (op == '*')
printf("%d * %d = %d\n", a, b, a * b);
else if (op == '/')
printf("%d / %d = %f\n", a, b, (double)a / b);
return 0;
}
>>508 もしかして、「〜を法として合同」の意味がわからないのかな?
でなけりゃ、「-1と2^nを法として合同な変換先で表現できる最小の値」が0だなんて恥ずかしいことは言えないよな?
>まさか、整数は2の補数で表現されなければならないと規定されている、と思っているんじゃないだろうな?
内部表現なんかぜんぜん関係ないぞ?1の補数だろうとバイアス表現だろうと同じこと
表してる数についての問題なんだから
「法として合同」でぐぐって、意味を理解してからもう一度規格を読み直すんだ
>>516 騙されんなよ
規格にハッキリきっぱり「static const size_type npos = -1; 」と書いてあるし
それがsize_typeの最大値になることも保証されてるし
+1すると0になることも完璧に保証されている
>>508 あとこれ
>-1をunsingedな整数に代入した時点で、その値は不定、
そこまで自信満々に言うなら、その根拠が規格のどこの記述にあるか教えて下さい
Chapter3と4を読んだ限り不定どころか紛れなく明確に決まっているように読めたが
何か見落としてるのかもしれない
自分がよくあ買ってないものは全て不定ということでわかっています。
Cの頃からあるunsingedの特徴なのにな
>>522 前々から疑問に思ってたところなんで、明確ならすっきりするんでそのURLを教えてくれないか。
527 :
508 :2009/05/06(水) 13:04:13
>>522 "shall obey the laws of arithmetic modulo 2n"
むー、そうかもしれんなぁ。
0.9...9.... = 1 は同意するとして 9+1=10 99+1=100 ... ...9...9+1=...0...0=0 (0が無限に続くので,表現として"...00000..."となる) って感じになって ...9...9=-1 よって ...999.999...=-1+1=0 って導いているサイトがどこかにあったんだけど忘れた
999999… + 1 = 0 ってねーよ
MFCを使い、MSペイントの多角形描画のようなラバーバンドで折れ線を書く機能を作ってます。 現在、 1. OnLButtonDown内で、MoveToにより、始点を決める 2. OnMouseMove()内で、直前のラバーバンドを背景色でLineToすることで消し、新しいラバーバンドを描画色でLineToする ということをやっているのですが、これだと線が重なった場合、以前に書かれた直線が、2.の「直前のラバーバンドを背景色でLineToする」によって消えてしまってうまくいかず、うまく解決する方法が思いつきません。 よろしくお願いします。
安易にXOR使うか、描画済み(Line入り)の背景を保存してそっちから書き戻す
全ての線を引き直す、でもいいか
>>529 小数点より左を有限の桁数とすればいいんじゃないかな。
例えば4桁とするなら
9999+1=10000=0(オーバーフロー桁は切り捨て)という世界で考える。(BCD4桁のCPU?)
-1=0-1=9999+1-1=9999
あるいは
0=9999+1=9999+0.999999....=9999.999...として
-1=0-1=9999.999...-0..999....=9999
先生! あの、僕、unsignedに-1を代入することを不思議に思ってたんですけど
int を unsigned(または,その逆)に代入する時の変換測って決まってるんですか?
unsigned ui = -2;
int i = ui;
その変換測が
>>527 なんですか?
>>533 CPUもメモリもカツカツという状況でもないなら、
1.絵を描く機能(LineTo/MoveTo)
2.絵を描くための情報(マウスイベントによる座標取得結果)
3.絵の描画結果(デバイスコンテキストの情報)
は分けて管理した方が良いですよ。
MFCなら上記のような、イベントドリブンのDocument-Viewアーキテクチャの
ソフトウェアの練習を勉強するにはちょうど良いです。
画像を読み込む処理を行おうとしています。 struct IMAGE * img; readImage(filename,img); とし、readImage中で、 img = GFunc_AllocImage(width,height,depth); としましたが、処理終了後のimgの値がNULLになってしまいます。 GFunc_AllocImageは以下のようになっています。また、readimage,GFunc_AllocImageともにDLLからの関数です。 DLLAPI IMAGE* WINAPI GFunc_AllocImage(int width, int height, int depth) { IMAGE* img; int bpp; if(width<0 || height<0) return NULL; if(depth!=8 && depth!=24) return NULL; if((img= (IMAGE*)malloc(sizeof(IMAGE)) ) == NULL) return NULL; bpp=depth/8; img->pixels = malloc(sizeof(BYTE)*bpp*width*height); if(img->pixels==NULL) { free(img); return NULL; } img->width=width; img->height=height; img->depth=depth; return img; }; デバッグしてみたところ、GFunc_AllocImage内では正しくmallocされているようです。 どのようにすればGFunc_AllocImageが生成したIMAGE構造体をimgに渡すことができるでしょうか。
readImageでimgを値渡ししてるから?
IMAGE構造体をポインタで定義しているので、imgをそのまま渡せば、 readimageがimgのアドレスを取得できると思うのですが・・・ また、&imgとしてreadFileにimgを渡したところ、IMAGE**からIMAGE*に変換できません とエラーになりました。あと、わかりにくい表現でしたが、 ”処理終了後のimgの値”とはGFunc_AllocImage終了後の値です。 変な書き方ですいません。
>>541 >”処理終了後のimgの値”とはGFunc_AllocImage終了後の値です。
ってGFunc_AllocImage関数の戻り値がってこと?
>>539 のGFunc_AllocImage内では正しくmallocは
この二つのmalloc戻り値はNULLではなかったということ?
if((img= (IMAGE*)malloc(sizeof(IMAGE)) ) == NULL) return NULL;
img->pixels = malloc(sizeof(BYTE)*bpp*width*height);
ごめんなさい。 >>”処理終了後のimgの値”とはGFunc_AllocImage終了後の値です。 は、visualstudioデバッガの使い方を間違えた為の勘違いでした。 GFunc_AllocImageの返値を受けたimgは正しくメモリを割り当てられていました。 問題は、readImageに渡したimg変数に対し、 関数の終了後メモリが割り当てられていないことです。 プログラムの元ネタの本を読み直したのですが、同readImage関数に渡すIMAGE構造体 が、ダブルポインタになっていることに気づきました。自分で勝手にシングルポインタを引数とする 関数に変更していたことがエラーの原因だったようです。 疑問なのですが、なぜ直接シングルポインタを入れてはいけないのでしょうか? IMAGE構造体の配列を作るわけでもないのに、わざわざimgをダブルポインタで宣言し、 readImage(filename,&img)としなければならない理由が分かりません。
typedef IMAGE* IMGHANDLE; int x = 0; readInt(x); void readInt(int v) { v = 5; } IMGHANDLE x = 0; readImage(x); void readImage(IMGHANDLE v) { v = GFunc_AllocImage(); } 上も下も同じ事
なるほど。 元の変数がポインタか否かにかかわらず、 関数の引数としてその変数を使う場合には、明示的に&を使わなければ 変数を値渡ししたと見なされてしまい、関数終了後に変数の中身は消えてしまう、 と言うことでしょうか。理解できました。ソースを書き直してみます。 ありがとうございました!
>>545 書き直しの前にこれ解ける?
int *p;
funcp(?){???}
int *pのp値を設定したいとき?の部分どう記述する。
int i = 100;
funci(?){???}
int iのi値を他の値に変更したい時?の部分どう記述する。
わかんないわかんない こわいよこわいよ2重ポインタ怖いよ 怖い怖い 助けて
>>546 言い忘れてた。書いた本人の俺、解けないんだ,orz
>>546 int *p;
funcp(int** p, int x){
*p=(int*)malloc(sizeof(int) );
**p= x;
}
使うとき、
funcp(&p, x);
int i = 100;
funci(int* i, int x){*i = x;};
使うとき、
funci(&i, x)
でしょうか。
試してみたところ、
>>549 は違っており、
void funcp(int** p,int x)
{
*p= (int*)malloc(sizeof(int*));
**p= x;
}
が正解でした。やっとダブルポインタが理解できました。
お付き合い頂いて、本当にありがとうございました。
違う。sizeof(int)が正解
552 :
デフォルトの名無しさん :2009/05/06(水) 22:39:03
namespace XXX { static void func() {} } という記述で、staticがあるのとないのとでは、何か違いがありますか?
外からexternで見えるか見えないか。
554 :
デフォルトの名無しさん :2009/05/06(水) 22:49:49
#include <iostream> namespace XXX { void func() {} } extern void XXX::func(); int main() { func(); return 0; } 見えません。
XXXだから駄目だな。 100% FREEEE XXXにしとき。
>>554 もちろん4行目までと5行目以降は違う翻訳単位だろうな?
namespcce XXX { /*extern*/ void func(); } int main() { XXX::func(); }
>>537 unsigend への変換で、元の値が範囲外のときの結果は決まってる。
>527 は規格中のその規定に関する記述の一部。
ただし sigend への変換では、元の値が範囲外のときの結果は実装依存。
>>454 0 で初期化されることが標準規格で決まっている。
>>461 関係ない。
そういう表現を使う環境では未初期化の静的な実数を bss には置けないというだけで、
0 (或いはこれを変換した結果の 0.0 やヌルポインタ)で初期化されることに変わりは無い。
>>561 だから0初期化を当てにするなってことだろ。
>>564 規格に則ってない環境なんてザラ。
>>454 ANSI-Cに則った処理系なら main 関数に入る前にイニシャライズ
されるけれど、単に"C言語"と言ったらその限りではない。
InitializerをリンクせずにROM容量を削るのはよくあること。
562の言うように、明示的に自分で初期化するソースは移植性も高い。
こういうのはパソコンの人はあまり気にしてないみたい。
>>565 自分の経験を一般論のように見せかけて変な主張をするのはやめてください。
ましてや初心者歓迎スレで。
明示的な初期化が望ましい理由は、単に >564 のような心配無しに読めるから。
それだけのこと。
未初期化変数のデフォルトの初期値についての規則は >561 のとおり。
>>565 デタラメ書いたら規格票を楯に反論させていただきますよ?
double a=0;って書けばどこでも安全だろ
そうです規格に沿ってないような糞コンパイラは使うなと反論します
まあコンパイラでなくてリンカの話でしたけどね。
>>569 あそこまで言明するなら、もっと正確に言うべきである。あれではうそになる。
初期化されるのは。
・すべての初期化していない静的に確保される変数は.bssセクションに入っていて、0で初期化される。
中身は
・初期値を持たない大域変数
・初期値が0の大域変数
・初期値を持たない静的局所変数
・初期値が0の静的局所変数
ローカル変数は関係ない。その他メモリー等を確保する領域も関係ない。
>>571 内部表現のことを言ってるなら違う可能性はある
ポインタに0を代入した場合等のことを言ってるなら問題ない
>>571 NULLならば0は真
0ならばNULLは真とは限らない
プロトタイプに従って整数拡張させるから大抵問題ないけど、型情報のない可変引数ではまずいってばっちゃが言ってた
>>575 何を根拠にそんなことを言うのかね?
>577 の検索結果のトップにある記事を引用しているようだが、その記事は
C/C++ の規格と ELF での .bss の定義とがまったく別のスコープで行われている
ことを見落とし、2つのスコープを混同した上で、間違った結論を出している。
ELF での .bss の定義に C/C++ 変数の初期化の有無なんて関係ないし、
逆に C/C++ の規格は ELF の .bss なんて知ったこっちゃ無い。具体的には、
ELF の .bss の定義にある「ゼロで初期化」と、 C/C++ での「ゼロで初期化」は
それぞれ意味が違う。(前者はメモリ領域の全ビットをゼロにすること。後者は
C/C++ で "= 0" と書いた場合と同じ初期化をすること。)
これらを正しく(効率よく)結びつけるのがコンパイラの仕事。たとえば gcc では
3.3 あたりで "= 0" と明示的に初期化された変数も .bss に配置されるように
変更された(以前は .data に配置されていた)。これは C/C++ 規格でも ELF でも
規定されていない部分の動作であり、コンパイラの実装が自由に選んでいい。
また、各型の「ゼロ」の内部表現を知っているコンパイラにしかできない選択でもある。
整理すると、
・ゼロ初期化の規格上の定義とその実装の議論
・規格上の初期化がそうはならない環境も良くある事と、そんなの糞と言う平行線
の2つの話が
>>577 のリンクにより微妙にごっちゃになっておりますが、
頑張ってついて行きましょう。
VC2008EEのデバッガを使ってデバッグ中、 値が見れない(デバッグのウィンドウに表示されない)変数があるんですけど、なぜなんでしょう? その変数はforの{}内で宣言した変数なんですけど関係ありますかね?
582 :
581 :2009/05/08(金) 01:43:52
すみませんスレ違いでした。 別スレできいてきます。
584 :
583 :2009/05/08(金) 01:46:14
うわ。リロードし忘れた。ごめん。
>>577 なぜ規格の話をしたがっていたのに見知らぬ他人のサイトなんぞ見なきゃいけないんだ
しかもgoogle検索リンク貼り付けるとかアホもいい加減に
終わった話を蒸し返したくなるほど、特定されたのが悔しかったってこと?
588 :
デフォルトの名無しさん :2009/05/09(土) 12:36:14
C++ファイルを2つに分けて設計しています ファイル1にオブジェクト、ファイル2にexternオブジェクト(同じオブジェクトを参照したい)を作成しました ファイル2でオブジェクトを削除するとファイル1のオブジェクトも削除されますか? また、ファイル3でexternオブジェクトをもうひとつ作って削除するとファイル2のオブジェクトはどうなりますか?
>>588 C++でexternは禁止だぼけ
198日ROMってろ春日
なぜ198日なんだ
591 :
デフォルトの名無しさん :2009/05/09(土) 14:34:39
Visual C++ 2008 にて、 小数点以下を絡めた計算を行う際に、 double を使用した場合に、丸め誤差が発生してしまいました。 C++ にて巨大な数値を厳密に計算する場合、どのような型を使うのでしょうか? .NET の Decimal、Java の BigDecimal のような型はあるのでしょうか? よろしくお願いします。
追記ですが、C++/CLI は利用しないつもいです。。。
>>591 十進法ベースの浮動小数点数が使いたければ、
ほかのライブラリを使うか自分で計算するかしかない。
ちなみに、一応WindowsにもDECIMAL構造体とその計算をする関数(VarDecAddなど)が一通り揃っていて、
これは.NETのDecimalと同精度。
>>594 DECIMAL を実際に使ってみました。
代入や計算が他の型のように、直感的にはできないですが(関数経由のため)
それらを気にしなければ、厳密な計算でも使えそうな感じです。
必要に応じてラッパークラスを作ってしまうのも手ですね。
レスありがとうございました。
>>589 勤労感謝の日かっ!?
…とマジレスしてみる
最近ようやく VC++6.0 から VC++2008 に移行したんですが(遅すぎ><) これまでの資産を引き継いで以下のような文字列を扱うクラスを含むコードを ビルドするとコンパイルエラーになってしまいます ↓(ソースはめちゃくちゃ簡略化しています)
599 :
598 :2009/05/09(土) 18:19:24
class string { public: ... operator char* ( ) { return ( str ); } char operator [ ] ( unsigned int i ) { return ( str [ i ] ); } bool operator < ( string& s ) { return ( strcmp ( str, s.str ) < 0 ); } ... private: ... char *str; ... }; int main ( ) { ... string str1 ( "abcde" ), string str2 ( "fghij" ); char ch; ch = str1 [ 2 ]; // ←(1)コレがダメ strcpy ( str2, str1 ); if ( str1 < str2 ) { // ←(2)コレがダメ ... } ... }
600 :
598 :2009/05/09(土) 18:19:50
(2)が失敗するのはおかしいと思うが? stringとstringの比較なのにchar*が優先されるわけがない 多分曖昧になるのはstringとchar*を比較しようとしたときだろうから、 bool operator< ( string&, char* )とbool operator< ( char*, string& )を用意してやれば解決すると思う operator[]の方はunsignedのせいで[]の中身の変換が必要になるから曖昧になる その証拠に「ch = str1[2u];」では曖昧にならない 特に必要がないならunsignedを取ればいい でも本当はoperator char*を普通のメンバ関数に置き換えたほうがいいと思う
603 :
598 :2009/05/09(土) 19:30:43
>>601 ああごめんなさい間違えてました
ソースコードを読み返してみたら
確かに string と char* の比較でした
そうか
グローバルで比較演算子を両方の場合についてオーバーロードすれば良いのですね
ありがとうございます
unsigned については実際は size_t を使っているんですが
これがいけなかったんですね
キャスト演算子についてはおっしゃる通り今では極力使用しない方が
良いことは分かっているんですが
ライブラリを作ったのがかなり昔のことで
ソースコードを書き換えるのがめんどくさくて今に至っています
とにかく解決できて良かったです
ありがとうございました
604 :
533 :2009/05/09(土) 21:29:07
>>534-535 XORでやろうとしたのですが、線を重ねて描画した際に線が消えてしまうため、
後者の方法で実現しました。
>>538 1. ViewクラスのOnDrawに描画機能をまとめる
2. ,3. Documentクラスに持たせる
って感じにしました。
Document-Viewアーキテクチャで書かれたの良いソースって落っこちてないんですかね^^;
ありがとうございました。m(_ _)m。
606 :
604 :2009/05/09(土) 22:57:21
VC++ 2005 CLR windowsフォームアプリケーションで 外部アプリを起動できる機能を実装しようと思っていますがうまくいきません。 どなたかアドバイスをよろしくお願いします。 (2)のメモリ診断ツールを実行しようとすると以下のエラーとなってしまいます。 Win32Exceptionはハンドルされませんでした。 指定されたファイルがみつかりません。 (1)のメモ帳は正常に起動できたのですが、なぜ(2)のメモリ診断ツールでエラーが出てしまうのでしょうか? プログラムを作ろうと思っていますが、うまくできません。どなたかアドバイスください。 # 次の書き込みへ・・
607 :
606 :2009/05/09(土) 22:58:49
# 606書き込み時誤って604としてしまいました。 # 606の続き・・ (1) // フォーム上のButtonをクリックすると「メモ帳」を起動する。 private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { Diagnostics::Process::Start("C:\\Windows\\System32\\notepad.exe"); } (2) // フォーム上のButtonをクリックすると「メモリ診断ツール」を起動する。 private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { Diagnostics::Process::Start("C:\\Windows\\System32\\MdSched.exe"); } 試しにVB .NETで以下のプログラムを実行したところ正常に動作できました。 Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Process.Start("C:\Windows\System32\MdSched.exe") End Sub お手数をおかけしますが、何が原因で正常に動作できないのかご教示願います。 環境: OS Windows Vista Ultimate SP1 Visual Studio 2005 SP2
>>606-607 Windowsが64ビット版だなんてことはない?
そうだとすれば、VB.NETのプログラムではAny CPUで64ビットプロセスとして実行されてうまくいき、
C++のは32ビットプロセスとして実行され、System32がSysWOW64にリダイレクトされて
うまくいかないと説明できるんだけど。
notepad.exeだと上手くいくのは、System32とSysWOW64の両方に存在するため。
ようするにC++でもx64ビルドすればいい(C++でAny CPUは厳しいからパス)。
あるいはWow64DisableWow64FsRedirectionと書こうとしたが、
Process::Startには効かなかった。systemでは通用したけど。
610 :
606 :2009/05/10(日) 04:59:15
>608 参考にさせて頂きます。 >609 うおーありがとうございます。Windows Vista 64ビット使ってます。(誤記多いし、情報不足ですみません。) 構成マネージャでx64設定に変えてリビルドしたところ正常に動くようになりました。 デフォルトのインストール設定では、「x64 コンパイラおよびツール」がないようなので、 コンパイル設定を変えるのに苦労しました・・。 まだまだ609様の書き込み内容を理解できませんので、理解できるよう精進したいと思います。 ありがとうございました。
上流工程ばっかりやってると こういうスレは見ててなんだか楽しいなw
newで作ったクラスの中の自分をdeleteする処理を書いたんですが、その後ろに処理を書くとエラーで止まります その行で終わるようにするとエラー出ないんですが、これ問題ありますか?関数の戻り値とかどこへ行ってどうなるんでしょうか
deleteした後はメンバ変数を使ってはならない。もう存在してないから。
自分自身をデリートすることは安全なんですか?
delete *this; は普通にやるじゃん すぐ return すればいいだけで
そうなのか。イメージできないけどわかったthx
delete this;ではなくて?
あ、ごめん delete this
620 :
デフォルトの名無しさん :2009/05/12(火) 11:36:51
C++でネットワーク関係のコードを書くときACEというフレームワークを使ってる人っていますか? 自分は簡単なHTTPDくらいならCで書ける(と思ってる)のですが、C++ではどう書くのか方法を探してます。 よろしくお願いします。
COMではdelete thisは普通に使うよ 参照数0になったときに自分をメモリから削除するときは必ずやってる
Cでファイルの読み込みを勉強中なのですが、ネットでサンプルを調べると char buff[1024]; fp = fopen("file.txt", "r"); fgets(buff, 1024, fp); fclose(fp); のようなコードが多く見つかりました。 一応動作はするのですが、もしファイルサイズが予め想定した大きさ(1024バイト)以上だった場合にどのように対処するのが一般的なのでしょうか? 環境はWinXP それと出来れば勉強のために特別なライブラリ等は使用しない方法が望ましいです。 よろしくお願いいたします。
>>622 ファイルサイズってのは行の長さのこと?
どう処理するかは、処理の内容で適当にきめればいいよ。
>>622 fgets()は一行読み込みの関数なので、想定以上に長い行をどうしても一回で読み込みたい場合は使えない。
普通は、そんな長い行のことは考えなくていいと思う。
勿論、ファイル全体を一気に読み込みたい場合はfgets()は使えないと言うことになるが、
普通は1行単位で処理すれば充分だろう。
625 :
デフォルトの名無しさん :2009/05/12(火) 19:46:13
#include <iostream> #include <boost/shared_ptr.hpp> class Test { public: Test(const Test& orig) { std::cout << "Test: copy constructor" << std::endl; } Test(const boost::shared_ptr<Test>& orig) { std::cout << "Test: copy constructor& const boost" << std::endl; } Test(const boost::shared_ptr<Test> orig) { std::cout << "Test: copy constructor const boost" << std::endl; } Test() {std::cout << "Test: constructor" << std::endl;} ~Test() {std::cout << "Test: destructor" << std::endl;} private: int resource; }; int main() { const boost::shared_ptr<Test> pT(new Test()); boost::shared_ptr<Test> pT2(pT);★ return 0; } このソースで、★を付けた箇所はコピーコンストラクタが呼ばれると思ってたのですが、 コピーコンストラクタを色々と書いてみても呼び出されません。 ★の箇所ではどういうコンストラクタが呼ばれているのでしょうか?
new Test() でつくったポインタ引き回してるだけだからどのコンストラクタもよばねーよ 強いて言うならshared_ptrのが
627 :
デフォルトの名無しさん :2009/05/12(火) 22:37:08
ありがとうございます。わかりました。 boost::shared_ptr<Test> pT2(pT); だと、スマポの宣言してるだけだけど、 Test pT3(pT); とか書けば、スマポ引数のコピーコンストラクタが呼ばれるということですね。
>>627 上と下でpTの型が変わってる。
なんか分かってなさそう。
629 :
デフォルトの名無しさん :2009/05/12(火) 22:58:27
静的記憶領域の変数って外部関数への引数として渡さなくても 外部関数の中で使えるんですか?
>>629 アドレスとかを渡すってこと?問題なくできるよ
ポートが開いているかどうか調べるにはどうすればいいんですか? MFCもあるんですが。一番簡単にファイルのダウンロードとかも全部カスタマイズできて ネットにデータを送信受信する基本は何を使えばいいんですか?
ソケット勉強すれば?
出てきたありがと
ソースコードが長くなったので、クラスを作ってソースファイルを分けようと思うのですが 他のクラスの関数にインスタンス化しないでアクセスする方法ってありますか?
俺なら設計を見直す
>>635 ヘッダ作って#includeすりゃいいじゃん
static関数
継承
>ソースコードが長くなったので、クラスを作ってソースファイルを分けよう とても嫌な予感。
俺の部下なら、百叩きの刑
>ソースコードが長くなったので、クラスを作ってソースファイルを分けよう ソースファイルを分けたいのかソースコードを分けたいのかどっちなんだ むしろエディタ上で折りたためるようなのないのかと
よろしい、ならばリファクタリングだ
644 :
デフォルトの名無しさん :2009/05/16(土) 00:43:47
長さ32の0と1の列を入力して、そのビット列の表わす実数値(IEEE規格754に従う)を出力するプログラムを作る場合、実数値のデータ型はdouble型とfloat型のどっちがいいんでしょう?
>>644 floatの精度は24bitだからfloatでは情報落ちする。よってdoubleを使う。
なんでdoubleとfloatの"どちらか"って決めたのかによる どこまで望まれる動作なのか?ってこと 2^100とか3.1^-100とか+INFとかNaNとか-0とか+0…なんかもIEEE 754で表せれるけど,人が読む表現としてどこまで望んでるの?
647 :
デフォルトの名無しさん :2009/05/16(土) 01:07:34
infとnan以外の時に計算結果を保持した内部のビット列が入力したビット列と一致することが求められていて、その要求を満たすためには、精度の高いデータ型のほうがいいのかなあと思ったんですけど・・・
>644を見ると、32bitのビット列をIEEE754として解釈するだけだと思ったのだが、 >647を読むとなんだか違うように思える…。
LocalFree()ってなんですか?
>>647 いまいちやりたいことがわからん。
何のビット列をどうしたいの?
>>647 正直ビット列に直す必要すらないかと
「計算結果を保持した内部のビット列が」っつってるけど,そもそもビット列のケーサンなんて高度なことする必要性がどこから出てきたの?
"0"と"1"から成る文字列を実数値のなんちゃら表現にするんだから,先にどんな表現にするか決めないと.
異なるアーキテクチャ間でバイナリデータのやりとりをするときに 整合性をとるため浮動小数点数を IEEE754 形式に合わせたいのだとエスパー
いやまー,完全にプログラミング演習とか,プログラム実習とかそういう授業なんだろうけどさ
gccのマクロスイッチについてです VisualStudioでは、プリプロセッサーの種別で適時、マクロを定義できますが linuxでカーネルのバージョン毎に、インクルードするファイルパスを変えたい場合 どのように、記述すればいいのでしょうか? Makefileを作成して、そこで指示するのが普通なのでしょうか?
定石は知らないが、俺がやるとしたら-DKERNEL_VER=`uname -r` Linux板のカーネル総合スレで聞いたほうが詳しい人いそうだが・・・ 向こうの流れを見た感じだと、もしかして向こうから来たのか?
656 :
デフォルトの名無しさん :2009/05/17(日) 13:51:00
>>649 >LocalFree()ってなんですか?
LocalAlloc, LocalReAllocと一緒に使うWin32のmalloc,realloc,freeみたいな
メモリ管理の関数。
658 :
デフォルトの名無しさん :2009/05/17(日) 16:18:32
XPpro VC++6.0 です プログラム作ってビルドは成功する(警告はたくさんありますが)のですが、その後VC内の実行ボタンを押しても真黒なウインドウが出るだけで動きません。 ところがDebugフォルダ内の出来たexeファイルをクリックして実行させるとまともに動きます。 何回ビルドしてもこの調子です。 これは何が原因なんでしょうか?
VC++6.0が古すぎだと思う。 XP上ではまともに動かない可能性あり
>>658 主な違いはプログラム実行時のカレントディレクトリの扱いぐらい。
相対パスでファイルを読んだり、argv[0]を参照したりといったことをしていないなら
>>659 の言うような問題かも。
661 :
658 :2009/05/17(日) 17:03:18
なりほどありがとう。 ソフト替えるか・・・
662 :
658 :2009/05/17(日) 17:04:05
○なるほど ×なりほど ('A`)
真黒なウインドウってコンソール?
一瞬で処理終わってるだけじゃないのか?
その真黒なウィンドウがすぐ消える、というのならそうだろうね。 VC関連で何百回も出てる質問だ
本来「起動する→終了する」が自然なのにね。 終了が当たり前じゃない世代
667 :
658 :2009/05/17(日) 18:30:44
C言語の質問です。 LLONG_MAX,LLONG_MIN とかってlimits.hの中に定義されていないのですか? 環境はubntu9.04です。
-std=c99
670 :
デフォルトの名無しさん :2009/05/17(日) 21:38:57
switch文の中でswitch文を2回くらい使ってるのですがあまり好ましくないですか? あとifやforのネストは何回くらいまでが基本でしょうか
>>670 そんなもん場合によるとしかいえん
そうするのが自然なら別にかまわない
そんなの好きにしろよ… チーム制作になるなら、ルールはその時決めるだろ
>>670 好ましくないと思うから聞いてるんだろ?
ネストした時点ですぐに関数の分割を考えるぐらいでいいよ。
>>670 switch文がネスとするのは、私の場合ほとんど無い。どうしても必要なときはするけど
普通はまず無い。だから何かの設計の仕方が私と違うと思う。
ifやforは,場合によってはネスとする場合があるが、その中身は小さなも物がほとんど。
だから、for、ifの重なった先が大きなブロックなら、私とは設計の概念が違う。
実物を見たら、もっと具体的な話が出来るが。ネットで長いリストは読む気がしない。
>>655 >>654 です、Thxです。
DKERNEL_VER=`uname -r` これを、カーネルのバージョンを変数、DKERNEL_VERに取得して
その内容で、インクルードするファイルを決める事と、理解しましたが、やはりMakefileに記述すれば良いですよね?
>>675 変数じゃなくてマクロ
-Dはマクロを定義するコンパイラオプション
ここまで分かればあとは自明だと思うが
なんかアツく語ってる奴が居るので俺も語る 関数内クラス最高。
>>677 テンプレートパラメータとして渡せないお前なんかイラネーヨ
>>659 > VC++6.0が古すぎだと思う。
言語仕様も古いしね。デバッグバージョンで
for (;;) {
T* p = new T();
delete p;
}
↑のコードで放っておくと(今時のマシンなら)数時間
で停止するしね(内部で使っているデバッグ用のメモリ
アロケータのカウンタが 0 に戻ってどうの、だったと
思う)。
show()の中のようなイタレータを定義すると error: expected `;' before ‘itr’ というエラーが出るのですが、 対処方法が分かりません。 ご指導お願いします m(_ _)m ----------------- template<class Type> class List{ private: list<Type> tlist; public: List(){} void show(){ list<Type>::iterator itr; } }; int main() { List<vector<int> > tl; return 0; }
全角空白を除けば普通にコンパイル成功するけど… それだけのコードで再現するの? 普通にどこかで文法を間違ってるだけだと思うんだが
683 :
681 :2009/05/18(月) 16:08:40
>>682 コンパイル通りますか!?
今
>>681 をコピペしてやったけどダメでした。
なぜだろ・・・
------------------------------
以下原文
#include<iostream>
#include<vector>
#include<list>
using namespace std;
template<class Type>
class List{
private:
list<Type> tlist;
public:
List(){}
void show(){ list<Type>::iterator itr; }
};
int main()
{
List<vector<int> > tl;
return 0;
}
684 :
681 :2009/05/18(月) 16:12:16
>>683 の続き
以下 gcc -v 結果
Using built-in specs.
Target: i486-linux-gnu
コンフィグオプション: ../src/configure -v --with-pkgversion='Ubuntu 4.3.2-1ubuntu12'
--with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs
--enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared
--with-system-zlib --libexecdir=/usr/lib --without-included-gettext
--enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3
--program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc
--enable-mpfr --enable-targets=all --enable-checking=release
--build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
スレッドモデル: posix
gcc version 4.3.2 (Ubuntu 4.3.2-1ubuntu12)
C++で共有ライブラリとメインプログラムを別々にメンテしています。 共有ライブラリ内のクラスでメンバやメンバ関数を追加した後ライブラリを再コンパイル して置き換えると、どうもプログラムの挙動がおかしくなる (e.g. コンストラクタが正しく 呼ばれなくなる)のですが、もしかしてこれがいわゆるC++でバイナリ互換性を失った状態、 でしょうか? こういう場合、メインプログラムを動く状態に保つためのノウハウみたいなものは ありますかね? とりあえずメインプログラムも再コンパイルし直せばいいみたいですが、それだと ライブラリとプログラムを分けている意味が... これ以外にも方法はあるでしょうか? なお、プラットフォームはLinuxとMac OS Xです。
>>685 デザインパターンの出番だな
よく知らないけどファクトリーなんとかってのでいけるかもしれんw
詳しくはググるなり書籍なりでどうぞ
とりあえずインターフェースが変わらない部分のみについては大丈夫だと思う
typename list<Type>::iterator itr;
688 :
681 :2009/05/18(月) 19:02:30
>>687 できました。
ありがとうございます!
typename を使うことで list<Type>::iterator が型であると明示するんですね。
これを使わないと、list<Type>::iterator っていう変数とも考えられてしまうと、、、。
勉強になりました。m(_ _)m
689 :
デフォルトの名無しさん :2009/05/18(月) 23:39:50
int round(double input) という感じの四捨五入関数を書きたいのですが、四則演算だけで書けるでしょうか?
>>689 return (int)(input + 0.5)
691 :
デフォルトの名無しさん :2009/05/18(月) 23:55:20
ありがとうございます。
負数でも大丈夫なのかそれ
環境依存
負数の四捨五入は未定義だから好きにすればいい
>>689 return (int)(input - 0.5)
return (rand() % 16 >= 8) ? (int)(input + 0.5) : (int)(input - 0.5);
JIS丸めというかISO丸めというか銀行丸めというか五捨五入というか知らんが、 あれだと実装するの面倒なのよね。
return (int)(input+(input-(int)input));
699 :
デフォルトの名無しさん :2009/05/20(水) 02:20:27
Win32プロジェクトから「空のプロジェクト」を選択してC++のウィンドウズアプリを 作ったのですが、リリースビルドにすると、LNK1257エラーが出ます。 今まではデバッグビルドでうまくビルドできており、ライブラリの場所などは同じになってます。 ライブラリもデバッグ用ではなく、リリース用のものを指定してあります。 C++でデバッグビルドで開発してたプロジェクトをリリースビルドにする際に、なにか やらないとだめな設定ってありますか?
わかりません!
>>699 それは次の方法で解決できる。(つづく)
>>699 VisualStuidoスレへどうぞ。
つーか、指定しているライブラリがデバッグビルドとリリースビルドで名前が違うとか、
そもそもリリースビルド用がないとか、そんな落ちじゃないよな。
703 :
デフォルトの名無しさん :2009/05/20(水) 09:46:40
つまりデバッグビルドからリリースビルドに変更したらよくでるエラーとかそういうわけでは なさそうですね。リンクしてるライブラリをコンパイルしたコンパイラと、現在使用中のコンパイラ がバージョンが違うのかな。。。
704 :
699 :2009/05/20(水) 10:12:43
>>702 すいません。
> つーか、指定しているライブラリがデバッグビルドとリリースビルドで名前が違うとか、
> そもそもリリースビルド用がないとか、そんな落ちじゃないよな。
それは全部確かめてあります。名前が違うので、それは指定しなおしたし、ライブラリが存在することも確かめました。
とりあえずVisual Studioスレに逝ってきます。失礼しました。
WINNT40で動いていたCのプログラムをXPで動かしたらメモリ共有違反で落ちまくります。 XPはメモリのチェックなど厳しくなってるのでしょうか?
APIに渡すパラメタが間違ってるか変わったかしたんじゃない?
707 :
705 :2009/05/20(水) 12:40:13
例えばstr[5]で確保してるのにstr[5]に値を入れようとしたりする場合です。 そもそもがおかしいのでなんとも言えないのですがNTでは問題なく動作していました。
int a[5]; … a[5] = 1; … i = a[5]; … 配列の範囲外読み込み/書き込みは 未定義 鼻から悪魔 〜 一見正常に動作しちゃうように見える まで "メモリ共有違反で落ちまくり" も未定義の動作としては正しいな
未定義動作なプログラムを書き続けていれば いつかきっと俺の所へも二次元嫁が…
NTで動いてXPで落ちるのも正しい動作だな
よーしパパ初期化しちゃうぞぉ
713 :
デフォルトの名無しさん :2009/05/20(水) 17:47:09
hogeって名前の構造体があったとして t=hoge; t.メンバ名;みたいな感じでhogeの中のメンバの取得ってできますか?
715 :
デフォルトの名無しさん :2009/05/20(水) 17:51:30
参照ってポインタのことだっけ?
テンプレートについてですが STLなんかは実際に利用すると非常に便利ですが 自分でテンプレートを使用するとなると使い所とかメリットがさっぱり思いつきません 皆さんどのように、どんな場面で利用されてるのでしょうか?
テンプレートがどうして有用なのか、継承との違いは何なのかについて基礎的なことは Effective C++やC++ Coding Standardsを、 テンプレートの高度な活用についてはModern C++ Designを参照。 Boostの中身をのぞくというのもあり。
先日発売された C++テンプレートテクニック も読みやすかった。 C++の基本的な知識があれば、さっくり読めるレベル。
>>715 違う
参照にヌルは入らない
配列の参照も作れない
配列の参照も参照の配列も普通に作れるが何言ってんの?
721 :
デフォルトの名無しさん :2009/05/20(水) 21:43:02
それで
>>713 を実行するには何か特別なことをする必要があるの?
構造体型* t;とか?
hoge_t hoge; hoge_t& t = hoge;
723 :
デフォルトの名無しさん :2009/05/20(水) 22:04:32
サンクス 今度やってみる
720 = 724 は C/C++ をマッタク触ったことがない訳じゃないだろうけど 配列の初期化や演算子の優先順辺りで躓いて孤独に力技してる可哀相な人なんだろうな
>>725 いやまてその脳内補完はどうかとおもうぞい
>>725 参照の配列とやらを見せてほしいな
C/C++とか言ってる時点であれだけど
配列の参照と参照の配列は違うし
演算子の順序の問題でもない
配列の参照は普通に作れるな
>>727 やったことないけどこれでどう?
char a;
char b;
char& c[]={a,b};
>>730 char a[1];
char (&b)[1] = a;
ところでこれ意味あるのかな
720 すまん。 719 = 724 の間違い。
>>733 ある
配列にsizeof演算子がちゃんと適用できる
>>733 要素数を求める関数テンプレートが作れる。
template<typename T, std::size_t N>
std::size_t size(T (&)[N])
{
return N;
}
>>731 過去に似たようなこと試して
参照の配列は作れません
と明確にエラー吐かれた(msvc)
#include <stdio.h> #include <math.h> int main() { int i; for(i = 0; i < 20; i++) { double a = pow(0.5, i+50); double b = 1.0 + a; printf("n=%d, %d, %d\n", i+50, 1.0==1.0+a, 1.0==b); } } これ実行すると2列目も3列目もn=52で境目ができると思ったんですが、 VC9はその通りになるもののgccだと2列目の境がn=63にずれます。なんででしょうか? gcc -v Using built-in specs. Target: i486-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 4.3.2-1.1' --with-bugurl=file:///usr/share/ doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with -system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-g xx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug -- enable-objc-gc --enable-mpfr --enable-targets=all --enable-cld --enable-checking=release --build=i486-linu x-gnu --host=i486-linux-gnu --target=i486-linux-gnu Thread model: posix gcc version 4.3.2 (Debian 4.3.2-1.1)
>>735 配列のポインタと同じじゃね?と勘違いしてた
ポインタだと*p[0]とかになるのか
>>736 テンプレートは便利だよな、テンプレートと参照の組み合わせはよく使う
>>739 推測だけど、x86のfpレジスタは80ビットあるから、計算の途中で
(メモリに書くなどして)64bitに落とすか落とさないかで結果が違うんじゃないかね
# VC9でも最適化をかけると、gccと同じになったりするかも
>>741 ありがとうございます。
「浮動小数点 80bit」でぐぐったらいろいろ出てきました。
743 :
699 :2009/05/21(木) 07:02:55
class hoge { public: hoge(int i); }; のように、引数を1つ取るコンストラクタしかないクラスの場合に、これの配列を 作ることは出来ますか?
744 :
699 :2009/05/21(木) 07:19:18
test t[3]={0,0,0}; こんな感じで出来ました。でもトリッキーですね。
そう? #include <iostream> class Foo { int i, j; public: Foo(int i, int j = 0) : i(i), j(j) { std::cout << "constructor " << i << " " << j << std::endl; } ~Foo() { std::cout << "destructor " << i << " " << j << std::endl; } void print() { std::cout << i << " " << j << std::endl; } }; int main() { Foo foo[3] = { 0, Foo( 1, 1 ), 2, }; for (int i = 0; i < 3; ++i) { foo[i].print(); } return 0; }
開発現場ではクラスはソース(cpp)に置いていますか? それともヘッダのような物に分離しておいていますか? メンバ関数についても直接クラスに書いていますか? それとも宣言だけをクラスに書いて実際の関数の中は 別にわけていますか?
普通は分ける。テンプレートは別でヘッダに直接書くけど
あるクラスが持っている変数に対するアクセス方法として 書き換え時はメンバ関数のみとして参照の際は直接見るようなことはできますでしょうか?
#include <stdio.h> #include <conio.h> int main(void) { int tn, ti, tsum; printf("正の整数nを入力せよ: "); scanf("%d", &tn); tsum = 0; for(ti = 1; ti <= 100; ti++) { if (ti % tn == 0) { printf("%d\tn", ti); tsum += ti; } } printf("%d\n", tsum); getch(); return 0; } これを実行すると表示される整数の前にnが出てきます。 これを消すにはどこを変えればいいのでしょうか?
750 :
699 :2009/05/21(木) 11:37:16
クラスがvtableを持つとき、vtableのサイズ分だけクラスオブジェクトのサイズが増えると思いますが、 それはポインタ1個分だけ増えると思えばいいでしょうか?
プレビュー見ないで書き込んでしまった・・・ 見辛すぎますが、どうかよろしくお願いします。
printf("%d\tn", ti);→printf("%d\t", ti);
754 :
デフォルトの名無しさん :2009/05/21(木) 11:49:25
Win+VC6 環境なんですが、 x^2 や、√x などを、上手く表示したいのです。 簡単な数式をCDC::OutTextなどで表記する方法って無いでしょうか?
755 :
デフォルトの名無しさん :2009/05/21(木) 11:53:07
テンプレートとは基本的に型を選ばず動作しないといけないのですよね?
>>757 全ての型に対応しなければならないかという質問なら、そんなことはない。
対応してない型なら意味不明なエラーを返すようなのは現行ライブラリにもいっぱいある。
それをなんとかしようぜというのがC++0x(次期規格)に盛り込まれているが、
いつ実装されることやら。。。
途中で送信してしまいました ウィキペにあった静的継承の例文なんですが template <class Derived> struct base { void interface() { // ... static_cast<Derived*>(this)->implementation(); // ... } }; struct derived : base<derived> { void implementation(); }; この例だと<class Derived>には明らかにimplementation()という関数をもった型が入ることが期待されてるわけですが この場合は、不適当な型が入った場合コンパイルエラーになるから問題なしという考え方なのでしょうか?
追加分を書き込みしてる間に
>>758 さんが意味を汲んで下さったようです
ありがとうございました
class HogeとHogeから派生したclass Hogehoge、class Hageがそれぞれ 内部変数を格納する構造体struct HogeVal 、HogeValから派生したHogehogeVal、HageValをもっています HogeVal* GetVla();と言う関数でclass HogeViewやその派生系に内部変数を渡して class Hogehoge、class HageではHogeValをdynamic_castして中身を確認していますが dynamic_castは出来ることなら使わない方が良いとききます。 もっとよい値の渡し方はないでしょうか?
C++で2次元配列を使っているのですが、変数宣言に他の変数を使って matrix[a][b]みたいにするか、それに近い動作はできないでしょうか? vector.hは使っています。
new
言ってる意味がよく判らんが、上から順に俺的オススメ順 1. vector<vector<なんか> > 2. boostを使ってもいい環境なら、ググってboost::multi_arrayを導入する。 3. new
C99もしくはgcc拡張では変数を添え字に可変長配列が作れるけど、 C++だと無いんだっけ。
テンプレートとの整合が執れないから可変長配列は無理 STLあるし
その可変長配列って中ではallocaしてるだけ?
>>761 HogeとHogeView、つまりModelとViewが常に適切な一対であるような仕組みを用意してあげるなら
dynamic_castしても良いんじゃない?
AbstractFactoryパターンを適用してFactoryにHogeとHogeViewのインスタンスの生成を丸投げしてしまえばいい
Abstract Factoryが解らないならググってください、為になるんで
いつも書き捨てでめんどくさいからcastしちゃうけどもっと良いやり方あるものなの?
三元牌の一つ
771 :
769 :2009/05/21(木) 21:16:06
麻雀牌は可変数ではないはずだが…
約と点数が可変数です
773 :
デフォルトの名無しさん :2009/05/21(木) 23:25:35
Hogeという自作クラスがあるとして、それとdoubleとの掛け算が出来るようにしたい時、 Hoge Hoge::operator*(double rhs); というのを定義すれば、Hoge×doubleはできますが、 逆も出来るようにするには、Friend関数を使わないと駄目ですか?
>>773 フレンドにしなくても、
Hoge operator*(double, const Hoge&);
ってできなかったっけ?
775 :
デフォルトの名無しさん :2009/05/21(木) 23:36:03
ありがとうございます。でも774の書き方では引数の数が多すぎといわれてコンパイル失敗です。 以下のFriend関数だとコンパイルは通るんですが、、、 こう書くしかだめですかね? friend Hoge operator*(double lhs, const Hoge& rhs) { Hoge tmp; tmp.m_x = rhs.m_x * lhs; return tmp; } Hoge operator*(double lhs, const Hoge& rhs) { Hoge tmp; tmp.m_x = rhs.m_x * lhs; return tmp; }
>>775 2008のVC++で確認したけど、frendじゃなくても引数が多いなんて
エラーは出ないよ。
777 :
デフォルトの名無しさん :2009/05/22(金) 00:03:29
>>776 ほんと?
手元の環境もVS2008 SP1だけど、C2804というエラーが出るよ。
バイナリオペレータの引数が多すぎますとか言ってる。
>>774 の関数はメンバ関数ではないぞ。
クラス定義の外に書け。
何の検証もしてないけどこれでどうだろう? Hoge operator*(double lhs) { Hoge tmp; tmp.m_x = this->m_x * lhs; return tmp; }
friendどうこうよりもtmpやらなんやらの使い方が気になる。 まずいだろそれ。
781 :
デフォルトの名無しさん :2009/05/22(金) 00:49:04
>>780 自分は779じゃないけど、779の書き方で問題ないと思うけどな。
例外が考慮されてないとか、そういう話?
>>774 メンバ関数での演算子のオーバーロードではオブジェクト型が左辺に来るようにしないといけない約束だから
friend指定でグローバル関数にしないとダメ
必ずしもfriendにする必要はないよ。 例えば、その*が可換なら、こう定義できるでしょ。 class Hoge { Hoge operator *(double rhs) const; }; inline Hoge operator *(double lhs, const Hoge& rhs) { return rhs * lhs; }
普通のやり方は class T についてコンストラクタ T( U ) と T operator* ( T , T ) を定義するんだけど、それはいやなのかしら? 暗黙の型変換がいやなので必ずexpliciteをつける主義とか。
785 :
デフォルトの名無しさん :2009/05/22(金) 07:36:59
c++っていつかは今のCOBOLとかFortranとかそんな感じになっちゃうのかな。。。 Lispみたいにいつまでも生き残ってほしい。
>>785 大部分の仕事がCとJavaだけで済ませちゃってるもんな
C++はだんだん現実の言語とは乖離するような方向に行っちゃってる
ような危機感を覚えるのは俺だけではないだろう
>>786 ただc#などのオブジェクト指向の言語を経験してしまうと
Cで書いててもなぜかそれっぽい書き方をしてしまうので
C++は必要だとは思う。
でもC++を使いこなしすぎると乖離していくんだろうな
788 :
デフォルトの名無しさん :2009/05/22(金) 08:15:49
自分はC++が現実の言語と違っていくというより、C++特有のイディオムとか継承とかデザインパターン とかを使って頑張って書いても、正直性能が一番いいわけでもないし、一番速く書けるわけでもないし。 自分の場合は、楽をするためにRubyとかC#とかを選択することは結構多い。でもC++の場合STLとかBoost とかを使って楽をしようとすると、C++の利点である性能から見るとマイナスだと思うし、しかもあんまり 楽じゃないし… そんな感じ。
789 :
788 :2009/05/22(金) 08:20:25
だから、最近このまま「一番得意な言語はC++です」という方向でいいのかな、と疑問を持つようになってしまいました。 なんつーか、自分が「C++を選びたい!」というモチベーションが昔と比べて低くなってきたというか、、、 みんなはこれからもC++の技量を磨き続けていこうと思っていますか?
>>789 問題は個人の自由じゃなく仕事があるかどうかで
仕事によってはC++を信望してる痛い上司がいるとC++でやるしかないわけで・・・
ホビーユースでC++扱ってるけどC#あたりに移項した方が良いのかなぁ?
792 :
デフォルトの名無しさん :2009/05/22(金) 09:54:17
>>790 仕事はこれからもあると思うし、それなりにペイもいいんじゃないかと思う。
今じゃ大学で教えるのはJavaだし、Cでアセンブラに近いところが書けてC++
のオブジェクト指向なコードも分かるプログラマって、今後は減ることはあっても
増えないでしょ。
ところで、今でもC++が一番性能が出せる言語なのかな?
最近CのコードをC++に書き直す仕事をやってて、わかりにくいコードをクラスとか
定義して書き直していくと、コードの抽象度が高まるにつれて、実行速度が低下して
いくのをみて、「性能ならC++」という世間の風評に疑問をもつようになった。
性能ならCだろ 何言ってんだ
単純に速度のみ求めるならC言語のほうが早いのは当然かと それでもまぁ他の言語に比べれば早いんじゃないの?適切に組まれてれば
795 :
デフォルトの名無しさん :2009/05/22(金) 10:13:30
>>793 まあそれは分かる。それでもコンパイラの力でCで書いたのと同じくらいになるのかなと思ってたんだよ。
Javaやスクリプト系の言語とかと比べた場合に、性能重視ならC++って言うでしょ。
でも、スマートポインタを使えば速度ガタ落ち、DB関係は苦労してC++で書いてもRubyやC#で適当に書いたのと
ほぼ同じ性能(DB側が時間を食ってるから)、、、とかさ。
テンプレートくらいだよ、最近C++使ってて楽しいのは。
いまさら新しい言語とか覚えられないしな。かりに覚えられても、俺の今のC++の水準まで行こうとしたら、
どれだけ大変か、、、
C++の基本理念は受益者負担だからね C++の便利な部分を利用すればするほどコストが増大していく betterCで使えばCと大差ないんじゃない?(当たり前か
抽象化すると速度低下はしかたないよね Cと比較するとやっぱりC++は速度が落ちる。
798 :
デフォルトの名無しさん :2009/05/22(金) 12:48:58
まあ、C++できると、違う言語の案件でも、信頼されるので仕事取りやすくなるよね。
>>792 > コードの抽象度が高まるにつれて、実行速度が低下し
> ていく
C++ には C++ なりの速度の出し方がある。malloc/free
をそのまま new/delete に置き換えるだけじゃ駄目だぞ?
C++が遅い?それでもC#の2倍近い速度を出してるわけだが
しおの2倍の性能が全体の1/10以下のとこで効いててもあまり効果がないってことでしょ
でもJavaの5倍の速度は出るぞ Java遅すぎる
OOPっぽいこともできてその中にC的な物も含めることが出来て しかし、そこそこの実行速度が出る便利な言語 異様な言語仕様とトレードオフになったが・・・
Javaが遅いだって? 開発が遅いC++ or Cに言われたくないな
一長一短 Javaってまだ開発案件あるの?
速度が必要ならJNIがあるじゃない
>>805 ある
今の所Javaが一位
これとセットで速くて高価なハードウェアを売りつける
それで糞遅いJavaの欠点を隠蔽するわけ
だから初めからJIT言語として開発されているC#は、Windows上 でアプリを動かす条件さえ飲んでもらえば、最適 今の所二位 Linux上でもMonoを使えばC#3.0までは動くしSIMDもついにサポートした 速度もどんどん速くなってるしC#3.5もそのうち出来るでしょう マルチコアCPUでGCを分担作業するというのはなかなかいい
経営者視点だとうれしいのか?C#とか.net系言語って プログラマ視点だと「またかよ」感があるけど
そう? C#触りだしたら気に行っちゃって、何でもこれでいけないか考えちゃうようになってしまった。 上から下までこれで行きたいわ。サーバはJavaクライアントはC++がまだ多いけど。
template <class T> class Base{ public: void SetT(T input); } Base<int> base1; Base<double> base2; このbase1とbase2は別の型扱いで良いのでしょうか? また、このBaseから派生したクラスを作るときは template <class T> class Derived : public Base<T> {//〜〜〜//} という形で良いのでしょうか で、やはりこれもテンプレート引数が異なれば別の型扱いでしょうか?
C#はASP.NETとLINQがいいよな これ多言語で組もうとしたら大変な事になる
×多言語
○他言語
>>811 別の型
typeid().name()を見てみ
>>812 後で出来た言語なんだからそういう親和性があって当然かと
過去の言語の不味かったところとかを解消するために出来上がってるんだし。
そういう意味ではC++は中途半端なんだよな
理想を掲げて完璧な言語を作っても 普及しなきゃ終わりっていう現実と戦った結果だからしかたなかんべ。 javaのような成功は稀。ほとんどの言語は理想だけで消えていく。
C++から大きくは変えなかったから成功したんだろう そのJavaもそろそろ役目終えそうな気配ではあるが
いくら後発とはいえc#が思いのほか優秀だったな 初めは酷い言われようだったな
休校中の学生でもタムロしてるのか いつもの数倍増しで低レベルでキモイ進行
平日の昼間から書き込みできる人にしか嫌われていないC++ ^^
起動してるアプリケーションにキーボード操作を送るにはどうすればいいんですか?
822 :
デフォルトの名無しさん :2009/05/22(金) 19:32:27
AAAかBBBが定義されてるときにコンパイルされるようにしたいのですが、 #ifdef AAA || BBB #endif と書いても駄目でした。どうすればいいですか? VC++です。
>>822 #if defined(AAA) || defined(BBB)
対象のプロセスに送るにはどうすればいいんですか?
826 :
デフォルトの名無しさん :2009/05/22(金) 20:24:30
>>825 意味不明
名前欄に名前を入れて
環境について書いてください
828 :
ははは :2009/05/22(金) 20:42:13
ほほほ
>>825 例えば CTRL + C を送る場合、
kill(プロセスID, SIGINT);
830 :
デフォルトの名無しさん :2009/05/22(金) 21:20:51
初歩的な事ですいません。 静的な配列 hoge[2][4] を動的に宣言した関数 test(char **hoge) に渡す場合どうすれば 変換エラーが無くなるのでしょうか。 試しに関数呼び出しに (char **) と添え字したらメモリ関連で止まる感じでした。
831 :
830 :2009/05/22(金) 21:22:36
ちなみに test(char hoge[2][4]) という宣言では解決しましたが、 あくまで動的宣言でのポインタ受け渡しをしたくて・・・。言葉足らずでした。
>>830 無理です。強引に型キャストすればエラーは出なくなりますが
配列の構造が異なるため正常に動作しません。
833 :
830 :2009/05/22(金) 21:37:26
無理ですか、、レスありがとうございました。 他の形式で対応してみます。。 よくよく考えてみたら動的に割り振った方はブロックサイズが解らないんですね。
>>830 宣言
test(char*hoge[4]);
呼出し
char hoge[2][4];
test(hoge);
配列はポインタに置き換え可能なんじゃなく、 メモリ上で連続しているオブジェクトに対しては そのポインタに整数の加減算が可能ということを シンタックスシュガーである[]を使って実行しているだけ と考えるべきなんじゃないか、と。 そうすれば char [][] を char ** で置き換えることは不可能だと 自然に理解できる。できない?あ、そう。
最近のCなら void f (int m, int n, int a[m][n]) { ... } みたいな書き方ができるはず。
>>835 char[][]は無いだろう。ひどい説明だ。
>>836 せめてa[][n]にしてくれ。ひどい説明だ。
っていうか、 test(char*hoge[4]); はエラーだけどね。
>>836 だから二次元配列(配列へのポインタ)とポインタへのポインタは
構造が異なるから書けたとしても渡せないわけ
>>837 そりゃ int a[m][n] のmはあってもなくても同じだけど、あっても文法違反じゃないからいいじゃん。
なんとなく書いた方がm*nの配列を渡したいという意図が伝わるような気がしないでもない。
>>836 うひ。これでちゃんとうごくのね。いいこと教えてもらった。
#include <stdio.h>
int f(int m, int n, int a[m][n]) {
int x = 0, i, j;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
x += a[i][j];
return x;
}
int main (void) {
int a[3][2] = {{1, 2}, {3, 4}, {5, 6}};
int b[2][3] = {{2, 3, 4}, {5, 6, 7}};
printf("%d¥n", f(3, 2, a));
printf("%d¥n", f(2, 3, b));
return 0;
}
#include <stdio.h> #include <stddef.h> #define SIZE_Y 4 void bar( int *p, size_t s ) { size_t i; for ( i = 0; i != s; ++i ) { printf( "%d ", p[i] ); } printf( "\n" ); } int main() { int i[][SIZE_Y] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9,10,11,12 }, { 13,14,15,16 }, }; size_t s = sizeof i / sizeof i[0][0]; bar( ( int * )i, s ); return 0; }
C99は便利だなぁ。
>>841 のfを可変長配列で読んでもOKなのね。
void g (int m, int n) {
int a[m][n], i, j;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
a[i][j] = m * i + j;
printf("%d¥n", f(m, n, a));
}
いま受けている講義では、Cの配列宣言は大きさがコンパイルするときに
決まってなければならないと習ったのですが、
>>844 みたいに引数を使っ
て宣言するのはありなんでしょうか。
ダメ。そんな古いCを教えている授業自体がもうダメだが。
>>845 C99(ISO/IEC 9899:1999)なら通ります
Indel C++が100%対応
gccが部分的に対応
***しかし大部分のコンパイラは対応しておりません***
マジでgccとインテルのコンパイラしか使ったことがないので、もうC99が 世界を征服しているのかと思ってた。つか対応してないコンパイラって何?
>>846 どっかの大学の先生が自分のブログに、C99を教育に使うのは時期尚早だとか書いてたのを思い出した。
>>848 Visual C++ のCコンパイラはいまだにC99の大部分の機能が使えないんじゃなかったっけ?
851 :
845 :2009/05/22(金) 23:03:01
>>847 ありがとうございます。講義で使っているのはLinux上のgccなので
たぶん大丈夫なのかも。でも宿題のプログラムで
>>844 みたいな
書き方をすると×を喰らいそう。小学校の算数で習ってない解き方を
して×を喰らったトラウマが…
>>846 講義を担当されている先生は結構お年寄りで、ご専門はソフトウェア
工学じゃなく信号処理らしいので、必ずしも最近のプログラミング
言語事情には詳しくないのかもしれません。
「時期尚早」とか「最近」とかいうけど、C99はその名のとおり1999年、 つまり10年も前に制定されたのよ? マウスイヤーとさえ呼ばれるIT業界で、どこまで進化を拒む気なのだ^^
RubyのソースなんてK&Rスタイルだよ。ANSI(C89)ですらない。
C++からの上位互換を失っちまったら魅力半減だからね 特にライブラリ関係で
うちはC99禁止なんだよなあ。
C99はやっちまったよなあ なんであんなバカな国際規格を無理矢理通そうとするかねえ
c99って何が問題だったの?
>>858 主要コンパイラメーカーが無視して対応しようとしない
C++の上位互換性が大きく損なわれてしまい未だに
C89が使い続けられる結果に
C++規格化 1998年 C規格改定 1999年 まずこれがおかしい 摺り合わせろよ
やっぱり「何故 trigraph なんてものが制定されたのか」っつー メタなところ(制定プロセス)から反省すべきだったんだろうと思う。
>>860 C++がCの上位互換として作られたのに、その土台となるCがC++規格化後に大幅改定になったらだめだろうってこと?
中途半端に便利で互換性失う位なら 互換ガン無視で物凄く便利な言語に移ればいい
>>863 過去の言語よりいいべ
で生まれた互換性がん無視なんていっぱいあるけどどれも微妙じゃん
>>811 さすがtemplate,genericsにはできないことがちゃんと出来ている
>>836 VC++6.0だけど関数宣言時に 定数式が必要 ってエラー吐くなぁ・・・。
リロードすべきでしたスマソ。。orz...
>>866 Cソースの書き方であっても拡張子をcppにしておけばC++側でコンパイルするので
結果C99な書き方ができるんじゃなかったっけ?
CとC++を意識して区別するのが面倒なので 趣味レベルでCを扱う場合は.cppでCライクな書き方をしてる
で、参照引数あたりがゴキブリホイホイになって住家Cへ戻れなくなるんです。
871 :
デフォルトの名無しさん :2009/05/23(土) 03:42:37
上の方で見たんだけど、参照の配列ってC++で作れるの? int a; int* ptr_array[5] = {&a,&a,&a,&a,&a}; これはポインタの配列。で、参照の配列が出来るなら int a; int& ref_array[5] = {a,a,a,a,a}; で出来るのかなと思ってやってみたけど、駄目でした。 できるのでしょうか?
>>871 基本的に出来ない
struct ref_int{ int &a; ref_int(int&a):a(a){;} };
int a;
ref_int ref_array[5] = {a,a,a,a,a};
無理矢理やればそれっぽいことはできるけど意味があるのかは不明
シリアルポートを制御するクラスの 通信条件を設定するメソッドですが void SetProperty(DCB &dcb) としてユーザー側にDCBを設定させるのと void SetProperty(const char* portname , 〜〜〜) と、最低限のプロパティを引数で受けて、制御クラスがDCBを弄るのはどっちがよいでしょうか?
DCB構造体の全項目をユーザ設定可にするなら前者。 一部を許可するなら後者。っていうか「最低限」て書いてあるから結論出てる?
875 :
デフォルトの名無しさん :2009/05/23(土) 13:52:57
C++ Builder を使ってるけど MFC ってどうなの?
MFC を使ってるけど C++ Builder ってどうなの?
やっぱ、C#が一番
878 :
デフォルトの名無しさん :2009/05/23(土) 15:47:33
Java経験者でC++を最近やり始めました。 すごく初歩的な質問で申し訳ないのですが、教えて頂けると助かります。 あるクラスAをクラスBの中でインスタンス化し、 それをクラスBの中で使おうかと考えています。 Javaっぽく書くと class A{ B b A(param){ b = new B(param) } someFunc(){ b.hogehoge() } } って感じです。 ただ、C++の本に書いてある初期化方式 A a(param); だと、宣言と実体化が同一箇所でやる必要があるため、 コンストラクタの中でインスタンス化した場合、 他のメソッドでそのインスタンスを使えません。 これってどうやって解決すればよいのでしょうか? よろしくお願いします。
コンストラクタの初期化子のことかな class A { B b; public: A(param) : b(param) {} // 引数渡して初期化 void someFunc() { b.hogehoge(); } }; という感じ。
>あるクラスAをクラスBの中でインスタンス化し、 逆じゃないか?
881 :
デフォルトの名無しさん :2009/05/23(土) 15:59:49
>>879 ありがとうございます。
そういえば、そういうのを見たことあるような気がします。
>>880 たしかにwww
882 :
デフォルトの名無しさん :2009/05/23(土) 16:03:43
あと似たような質問もあるのですが、 フィールドの変数を、コンストラクタ以外のメソッドで初期化するには、 同様に method(): hogehoge{ } って形になるのですか?
883 :
882 :2009/05/23(土) 16:14:36
これができるのはコンストラクタだけと怒られてしまいましたwww
コンストラクタでインスタンス化されてるのに他で初期化できるわけないでしょ。 ポインタでやるのがいいんじゃ? B* b; b = new B(param); b->hoge(); delete b;
>>883 コンストラクタ以外でやりたければ、単に代入すればいい。
class B{public:int x;}; class C{int x;public:C(int x_):x(x_){}}; class A{public:B b: C c;}; A a={0,(0)}; みたいな感じ
887 :
882 :2009/05/23(土) 16:28:10
>>884 おお、動きました。感動です。
文法的にはJavaに似ていると思っていたのですが、
実際にやってみるとだいぶ違うみたいですね。
ありがとうございました。
そもそもメンバにBのインスタンスを持つんだったら、 Javaのようなインスタンス化なんて考えなくていい。
889 :
882 :2009/05/23(土) 16:33:10
>>885 もうちょっと詳しく教えてもらえませんか。
さっき、
class A{
B b;
somefunc(){
b = B(hogehoge);
}
とやったら、エラーが出て無理でした。
884の人みたいに、ポインタに代入しろって意味でしょうか。
>>886 よく意味がわかりません。
コンストラクタも、メソッドも使わずに
フィールドに代入できるってことでしょうか?
>>889 b = B(hogehoge);とやりたければ、クラスBに代入演算子を定義する。
が、Bの意味として代入できるのが相応しくないというのは割とよくあることなので、
(だからJavaのクラスは参照型でnewしてやるのはJavaでは適切な判断だったと思う)
そういうときは
>>884 のようにポインタを使う。
891 :
882 :2009/05/23(土) 17:00:15
>>890 なるほど。
ただ、自分で代入演算子を定義すると面倒くさいので、
ポインタを使う方針でいくことにします。
ありがとうございました。
>>808 C#3.5て何よwww
そして参照の配列はどうなった
template<class Type0, class Type1> class{ void func(Type0 t0, Type1 t1){ t0 * t1; } }; としたときに、 Type0 * Type1 となるような演算子オーバーロードがされていない場合、 コンパイルエラーになるような方法ってありますか?
t0.operator*(t1); 何がしたいのか意味不明だけど。
895 :
893 :2009/05/24(日) 00:40:52
>>894 ありがとうございます。
挙げた例は実際のものではありませんが、
Type0 と Type1 となるクラスの条件が、
Type0 * Type1 が定義されていること したかったのでお聞きしました。
Boost Concept Check Liblraryが探しているものに近いと思う。
897 :
893 :2009/05/24(日) 01:53:23
>>896 ありがとうございます。
確かに私の想定しているものに近いです。
先日、std::mapのKeyに自分で定義した型を使用したときに、
<演算子が無い、と怒られたのですが、あれはどうなってるんですかね?
>>897 map は整列させるときに < の演算子を使うから
key の < 演算子をオーバーロードしないかぎり使えないだけ
899 :
893 :2009/05/24(日) 03:09:23
>>898 再度質問になってしまうのですが、
map のエラーと、
>>893 のコンパイルが通ってしまうことの違いが分かりません。
>>893 は > ではなく * を使ってるだけで、
(プリミティブ以外)オーバーロードしなければならない演算子という意味では同じように見えてしまうのですが。
void Read(char *buffer , int count) という関数で、ファイルからcountバイト分だけ読み出してbufferに書き込みたいのですが bufferの示す先が何バイト確保されてるか確認する方法はあるのでしょうか?
ない。
うーん、ないですか そうするとオーバーラン上等な仕様にするしかないのか・・・ それとも他に良い方法はあるでしょうか?
C/C++とはそういうもの。 それが嫌ならもっと安全で高級な言語を使えばよい。
いや、それはおかしい
>>900 というかchar x count バイトだろ?
>>899 map でも使うまではエラーにならなくないか?
>>893 の場合だと func を使おうとしたらコンパイルエラーになるはず
>>902 バッファは、Read()の中でmalloc()して返して、呼び出し側で責任もってfree()してもらうとか。
オーバーラン上等というか、勝手にバイナリの長さに合わせて 伸ばしてくれるのを希望なら std::getline(std::string&) を使えばよい std::string は何も文字列だけを入れるわけじゃなくバイナリを 入れてもよい
ヌル文字もいいの?
バイナリはvector<char>にしようぜ
vector<char>は遅いからなぁ。
scoped_array<char>で
引数一つ増やしてバッファサイズをわたせ。 C/C++の配列はそうやって扱う決まりだ。
vecterとかarrayって速度気にしなくていい横着できる開発くらいし使わないだろ
900のやりたいことがファイルからのデータの読み出しなら そっちの方が圧倒的に遅いしvetctorの遅さは問題になりにくいんじゃないか?
>>914 バッファサイズ>countを期待するけど、呼び出し側のバグを回避するために
実際にbufferで確保されているメモリサイズが知りたいということじゃないの?
WindowsならAPIで上のことができたような気がするけど、ハンドルが必要だったかも・・・
バッファサイズを指定できないAPIを見直すべき。
919 :
デフォルトの名無しさん :2009/05/24(日) 21:06:45
boost::scoped_ptr<T> pT; というスマポがあるときに、これにNULLを代入したい場合、 pT.reset(); pT.reset(NULL); のどちらが正しいでしょうか? どちらも可能みたいなのですが…
>>919 ソースをちらっと見てみるといい
本当に簡単だから読めると思うよ
まったく一緒です
921 :
919 :2009/05/24(日) 22:56:31
見ました。 pTがScoped_ptrの場合には pT.reset(NULL); と書けたのですが、pTがShared_ptrの場合には書けなかったので、 Explicitのせいかと思ったのですが、両方のコンストラクタが Explicit指定になってました。それなのにどうしてScoped_ptrの場合に NULL指定でResetできるのでしょうか?
Cygwin-1.7でprintfとwprintfを混ぜると挙動が変なんですが、そもそもワイド 文字系の入出力とバイト文字系の入出力を混ぜたとき、ちゃんと動くことは 規格上保証されてるんでしょうか?
923 :
デフォルトの名無しさん :2009/05/25(月) 08:02:50
質問2つさせてください。 [1] blitz::Array< T, 3 > ってあったとき、これはテンプレート型の…3は何を表しているんでしょうか? というかそもそもblitz::Arrayって何ですか。行列か何か…? [2] C++のヘッダファイルで、***.hと***.hppはどう違う?どう使い分けたらいい? こういうC++の初心者の質問ってこのスレでいいんですかね…初心者歓迎って書いてあったからこっちにしたんですが C++相談室 part69 の方が・・・?
処理の順番がクラスAから始まって A-B-C1--C2-----D |-C'2-C'3-| -C''2-C''3- となっていてどのC2に移項するかはC1の結果次第となっているとき C1からC2への動的な繋ぎ換え、C処理の末端からDへの動的な繋ぎ換えをどう実装したらよいでしょうか?
普通に分岐すりゃいいだろ
927 :
デフォルトの名無しさん :2009/05/25(月) 11:53:18
VisualC++2008EEなんだが、 クラスメソッドが、クラスのインスタンスから呼び出せるんだけど これって当たり前だっけ? class A { public: static void func(){ ::OutputDebugStr( _T(__FUNCTION__) );} }; A a; a.func(); // OK A::func(); // OK
あたりまえ 無理なのは逆な方
はい。
>>930 いや、C#はあんまり経験はない。
むしろ
>>927 は、C#やJavaから許された
シンタックスシュガー的なもんだと思っていた。
932 :
デフォルトの名無しさん :2009/05/25(月) 13:40:05
template <int v> struct Int2Type{enum {value = v};}; というテンプレートを見たのですが、これって一体何に使うのでしょうか? いまいち使い道がよくわからんです。 cout<<Int2Type<100>::value<<endl; とかやると、100と表示されるんですが、これって何か意味あるんでしょうか?
その名のとおり値を型に変える 値によって異なる型を作るので、 オーバーロードを利用していろいろ使ったりする 静的なif文消滅させたり
DOSプログラムにファイルをドラッグした時に プログラムがドラッグされたファイルを知る方法はありませんか?
>>935 mainのchar**argvで分かる。
>>932 整数を型に変換しているんだよ
テンプレートで型引数があってint引数が無い場合に int をいったん型にしてから使う。
value は型から元の値を引っ張り出すのに必要。
938 :
デフォルトの名無しさん :2009/05/25(月) 21:43:01
>>933 ,937
ありがとうございます!
でも、テンプレート引数にint引数を追加すれば、わざわざInt2Typeとかを定義しなくても
やりたいことができませんか?
>>938 できるときもあればできない時もある、定数の取り扱いと型のマッチングはちょっと違うので。
そもそもライブラリを書く側にしてみれば、全部型に統一して取り扱うほうがライブラリ側も統一できて便利だし統一されていればそれだけバグも少ないのだが、
逆に使う側からすれば指定するは毎回型ではたまったものではないと、折衷案を考えるとこうなる。
マッピングには型→型、型→整数、整数→型、全部あるはずなんで確認してそれぞれの関係を見ておくといい。
941 :
デフォルトの名無しさん :2009/05/25(月) 22:19:29
>>939 ,940
難しいス。つまり
template <class T> class ccc{};
というクラスがあったときに、ccc<double>とも書けるし、ccc<Int2Type<100> >とも
書けるということが長所なんですかね。
942 :
デフォルトの名無しさん :2009/05/25(月) 22:47:23
グローバルコンストラクタって何ですか? ググっても何かって説明が出てこないっす
環境依存だと思いますが、例外が投げられたとき、catchではどのようにして例外の型を調べているのでしょうか。 型の名前をバイナリに入れて、strcmpでもして調べているのでしょうか。 // SDKとして class MyException : public std::exception {}; // DLLのホストで typedef (void *DllFunc)(); DllFunc func = (DllFunc)GetProcAddress(..., "ExportedFunc"); try { func(); } catch (const MyException &) { /* 例外検出 */ } // DLLで extern "C" { __declspec(dllexport) void ExportedFunc() { throw MyException(); } } とかやった場合、ホスト側とDLL側の実行ファイルは同じコンパイラで作られたものでないと、正常に動かないと言うことになりますか。
>>941 これは直接使うものではなくてライブラリの中で使うのが一般的。
ライブラリを使う側には利便性を上げる、作る側には一般性の向上をもたらすもの。
945 :
デフォルトの名無しさん :2009/05/26(火) 00:04:25
配列の中身を空にするには'\0'で埋めればいいんですか?
>>945 どういう状態を「空」と呼ぶかは設計次第なので、なんとも言えないが、
空の文字列、いわゆるヌル文字列なら先頭を'\0'にすればよい。
947 :
デフォルトの名無しさん :2009/05/26(火) 00:12:42
948 :
デフォルトの名無しさん :2009/05/26(火) 01:22:19
VBで、空行が入力されたら、今までに入力されたものを出力 というプログラムを作っているのですが、 空行はどうやって表せばいいのですか?
>>922 ちゃんと動くというのがどういうことかはわからないがプログラムは書いたとおりにちゃんと動く
sjisのファイルを読み込んでユニコードに変換して出力とか普通に可能
951 :
デフォルトの名無しさん :2009/05/26(火) 13:28:15
visual c++ 2008を使い始めたC言語初心者ですが ビルドに成功したあと、プログラムに書き加えたらビルドに失敗するということが良くあります それでソースを別名でどんどん何種類も保存して必要があれば古いソースにさかのぼって ビルドしたいと思ってるのですが、それがどうにもうまくいきません 昔使ったボーランドのbuilderXだとそういうことが楽にできたんですが ちょっとVisual C++は慣れてないせいかお手上げ状態です 具体的には 1.ビルドに成功したソースファイルを別名で複製保存しておく 2.オリジナルか複製ファイルどちらかを改変する 3.それでビルドに失敗した場合 4.保存ファイルにさかのぼって1と同様のことをする これだけのことがしたいのですがわかりやすい手順を教えてくださいませんでしょうか
VCのエディションは? EEでなければAnkhSVNとか入れるのがいいと思うけど。
953 :
951 :2009/05/26(火) 13:52:08
>>952 ありがとうございます
Version 9.030729.1SP および Version 3.5 SP1となっています
すみませんEEとはなんでしょうか
AnkhSVNってのはなにかアドインみたいなものらしいことはググッてわかりました
これを入れればいいのですか?
エンタープライズエディション?
EEはExpressEditionね。 EEはアドイン使えないからね。 AnkhSVN入れるなら、それ自身ではリポジトリ作れないから他の Subversionツールも必要。TortoiseSVNなんかお勧め。 バージョンあわせるなら、AnkhSVNは1.6サポートのDailyBuildのほうがいいよ。 でもまあSubversionの使い方覚えないとならんからやること多そうだな。
>>955 残念ながらExpress Edition です
となると以外に難しいのかな
TortoiseSVNでVC外から管理する手もあるが・・・ バージョン管理ツールそのものをあまり使ったことがないのかな。 builderXは調べてみたけどバージョン管理ツール対応ってなってるね、 この機能使ってたのだろうか。
>>957 お察しの通りバージョン管理ツールという言葉自体初耳でして
PCを新調したら使い慣れたbuilderXがダウンロードできなくなってるみたいなので
EEを使い始めてまだ全然慣れていない状況です
といってほかに使えそうなのもないのでTortoiseSVNってのを調べてみますが
意外と大変そうですね
>>958 そうでもないよ
TortoiseSVNはエクスプローラーに拡張を施すだけなので
TortoiseSVNで管理させたいフォルダを設定すれば右クリックであれこれできる
最近オプソに参加するのに導入して使い出して、昨日自分のローカルプロジェクトを
ローカル鯖立てて管理するようにした。
まあweb鯖とアクセスするようなものだよ
960 :
デフォルトの名無しさん :2009/05/26(火) 19:30:41
質問があります。 粒子を動かすシミュレーションをやっていて、運動量を計算する必要が無くなったので その運動量を計算する部分を削ったのですが削る前と比べて明らかに遅くなりました。 そこで、削る前の状態から一つずつ式を削っていったのですが全く速度が変わらなかったため 最後に関数外の宣言部分を削ったところ、また遅くなりました。 宣言部分を復活させたところ、速度が元に戻ったので宣言だけダミーとして残しています。 削った部分が他のところで使われてないか検索してもヒットしなかったので、やはり宣言の有無だけで 速度が変わっているのだと推測できます。 無駄に宣言してるのに速くなるってことがあるのでしょうか・・・。
どっかのライブラリの中の関数と名前が被ってて、 ライブラリの内部で使われてる関数のリンクがおかしくなってると見た 変な空っぽの関数とリンクされて計算結果が狂ってないか確認した方がいい あと削った関数の名前はひねくれた物に変えておけ
962 :
デフォルトの名無しさん :2009/05/26(火) 19:52:55
>>961 結果を見比べたところ、全く変わっていませんでした。違うのは速度だけ・・・。
今まで、double MomX,MomY,MomZ;としてたのをdummyx,dummyy,dummyzとしても
遅くならなかったのでdummyxと宣言してますが使ってない変数を宣言するのは何か気持ち悪い・・・
オーバーランとかのバグじゃないのか?
>>960 >>963 と同じ意見
ソースコードを見てみないことには分からない
ソースコードを晒せない場合
仕様を書いてくれれば新規に作るよ
高速化もやってみるよ
現在の処理時間の目安も書いてくれると嬉しいな
作ってみたい
965 :
デフォルトの名無しさん :2009/05/26(火) 20:28:49
実数型変数では保持できないくらい大きい数値を扱うとき、int型配列を用いるとよいと習いました。 一つの要素に数値を1つ入れるのと、4つ入れるのでは、違いはやっぱり処理速度ですか?
エスパーの回答 そうです!
967 :
棚大生 :2009/05/26(火) 20:37:26
他のスレッドにものせましたが反応がないので。。。 時間があまりないのでお願いします。 大学の課題です。 言語:C++ 提出期限:5/27 0時 @ int i=99;と設定されていたら、 i/3 と i/3. では結果が異なる。 プログラミングを作成することによって、i/3 と i/3.を評価せよ。 (a,bを実数としてi/3 と i/3.をa,bに代入することとする。) A a=10, b=3, c=2 として !aかつb>cの戻り値、!aまたはb>cの戻り値を求めるプログラムを作成せよ。 B a=1,b=10,c=100のとき c<b && b<a と c<b<a は同じものではない。 上記のことをプログラム化して確かめよ。 C i=100で a=i++, a=++iの値を確かめるプログラムを作成せよ。 D 1から10までの和を計算するプログラムをインクリメント演算子を用いて、作成せよ。 デクリメント演算子を用いて、nCmを計算するプログラムを作成せよ。但し、n,mは cin を使って キーボードから読み取ること。
>>967 期限が短くなっとるwww
両方のスレ見てる人が多いから回答率が低くなるぞ
おとなしく向こうで待ってろよ
int i = 55; printf("1から10までの和: %d\n", i++);
コードでわからない事なんですが雑学的なことなんですが CLASSA と Pre-CLASSA の2つの名前付されているクラスのPre-ってどういう意味なんでしょうか?
自分でやれよカス
「前の」
thx!
974 :
デフォルトの名無しさん :2009/05/26(火) 22:19:31
>>964 え〜と、ソースコードを晒せないし高度な物理の法則を使ってるから仕様を書くのも難しいのです・・・。
1500行書くの疲れた・・・
>>950 状況としては、Cygwin-1.7.0-48で、
setlocale(LC_ALL, "ja_JP.UTF-8"); wprintf(L"Test\n"); printf("Test\n");
を実行すると、最後のprintfで派手に文字化けします。
で、これは正しく動くよう直すべきなのか、それとも、そもそもワイド文字系
I/Oとバイト文字系I/Oは、規格上「混ぜるな危険」なのかを知りたいのです。
正しく動くべきなら、もうちょっと気合入れて解析しようかと。
(だいたい当たりは付けたんですが、まだ解析途中)
>>974 詳しくはよくわからんが宣言することによってたまたまCPUキャッシュ上に
効率よく乗る形になって速度でてるけど宣言しないことによって分岐予測失敗とかで
CPUキャッシュの無駄な破棄や転送が起きてるとか
ちなみに計算が必要なくなったので外したというのはその関数がやっていた計算を
あらかじめ配列などに収まるようにプールしておいて参照するだけにしたとか?
977 :
デフォルトの名無しさん :2009/05/26(火) 23:14:51
>>976 粒子間に働く力を計算する関数と粒子を動かす関数を作ったのですが、粒子を動かす関数内部で
各粒子の運動量の総和をMomX+=vxで取り、最後に粒子数で割るという処理をしていました。
しかしデータとして出力する結果に運動量の項目は必要なかったので上記の処理を消したという次第です。
処理を消すだけなら速度も変わらず問題無いのですが上のレスで書いた通り宣言まで消すと遅くなるのです。
また、今度は極端に削除した例としてデータを出力する部分(ここは数値計算はしておらずofstreamで出力するだけ)
を消してみたのですがこっちはより遅くなるという結果でした。
自分もキャッシュ関連かと思っているのですが、まだプログラミングには詳しくないのでちょっと対策は勉強しないと考えられません・・・。
まずは、 アセンブリコードレベルでの違いがあるかどうか。次は、 アライメントがあっているかどうか。 を調べてみて x86 はそれほど影響はないと思うけど。 Itanium の例だけど、アライメントがずれると数分の1に遅くなってた。
条件確認→300mSecほど待機を条件を満たすまで繰り返すとき Sleep()を使うと動作がカクカクになってしまいます システムに負荷をかけない形で待機をするほうほうはないでしょうか?
>>979 MS-Windows なら WaitForSingleObject
981 :
デフォルトの名無しさん :2009/05/27(水) 02:59:22
あほか。先生に訊け
983 :
デフォルトの名無しさん :2009/05/27(水) 20:04:41
std::ifstream::read(char* データ保存先, int データサイズ)を使ってバイナリデータを読み込もうとしています。 データ保存先をstd::vector<char>にしたいのですが、read()の第一引数としては受け付けてくれません。 reinterpret_cast<char*>やstatic_cast<char*>を試してみたのですが駄目でした。 このような場合は、一度charの配列に入れてからvector<char>に入れなおすしかないでしょうか?
vector<char> buffer; buffer.resize(1024); istream.read(&buffer[0], 1024);
985 :
デフォルトの名無しさん :2009/05/27(水) 20:14:04
986 :
デフォルトの名無しさん :2009/05/27(水) 22:36:35
C言語の入門書は一通り読破して簡単なプログラムは作れるようになったのですが どうしてもグローバル変数だらけになったり関数や構造体が増えてくると統一性がなくなったりしてしまいます グローバル変数をやめると他の関数からアクセスしにくくなるし宣言するまで実体がないしで困っています この先勉強をしていく上で参考になるような書籍等はないでしょうか?
上3行と最後の行の関連性を説明しなさい
上3行が目を引くための釣りで 下1行が本題なんだろ
埋め
いっそC++でも勉強しろ
こんばんわ。 C++BuilderではSHCreateDirectoryを使うことは出来ますか?
992 :
デフォルトの名無しさん :2009/05/27(水) 23:50:18
どうせここでレスを書いてもすぐに読めなくなるだろうけど それ以上の勉強は、実際のソースをみるしかないと思う。 おれとしては、自分の興味のある分野のオープンソースなのを探して それをよみながら使うのを勧める。 それが出来なければ、Cの実力は現状止まりだろうな。
グローバル変数はstatic変数にしてファイル内スコープにして適切にファイル分割すればましになると思うけどなあ
994 :
デフォルトの名無しさん :2009/05/28(木) 00:19:00
○○すればましになるとか、そんなのじゃないんだよ。 反吐を吐きそうになりながら、与えられたソースと格闘して、 思ったとおりに動かないソースのせいで何日も苦しみ、そのあと 今まで発見されなかったバグのせいだと分かり、、、、 というのをやるしかないんだよ。
>>989 学生さん?
録音テープに法的な証拠能力は無いんだが
996 :
デフォルトの名無しさん :2009/05/28(木) 00:37:24
あとは基本的なデータ構造(ダブルリンク、スタックや、ハッシュとかバイナリツリーとか)を使った練習ソースを覚えるまで書いてみるとか、 ダイクストラとかバックトラックとかFFTとかルンゲクッタとかそういうのをCで実装してみる。 そういうのに慣れると他のソースが読みやすくなる。 さらに完全なCでなくてもいいからある程度Cっぽい言語のコンパイラを自分で書いてみるといい。 externとか、staticとか、auto変数とかそういう部分の理解がしやすくなる。 あと、アセンブラも軽くやっとけ。ダブルポインタとかそこらへんが理解しやすくなる。 まあ毎日3時間づつくらいやれば、半年だよ。
997 :
975 :2009/05/28(木) 00:57:14
自己解決しますた。結論。規格上、ワイド文字系I/Oとマルチバイト文字系I/O は混ぜるな危険。 入出力ストリーム(要はFILEオブジェクトの内部)には、どっちで入出力して いるかの「入出力単位」というものがあって、一度でもどちらかのI/O関数を 使うと、入出力単位がそれに固定されます。要は、一度でもwprintf()を使っ たらprintf()しちゃダメです。 どうしても途中で入出力単位を変更したい場合は、freopen()してからfwide() する必要があります。(って書いてあったけど、freopen()したら入出力単位が リセットされるんだから、明示的なfwide()は不要のような……^^;) ソースを追いかけてたらfwide()にぶち当たって、これをキーワードに あらためて調べてみると、手持ちの本に思いっきり書いてありました……orz
一つの関数を10回ぐらい一から書き直すとかなりシェイプアップ出来る。 ついでに参考にしてたソースが最初 「なんでこんな面倒で分かり難いことやるんだよ!」 と思ってた箇所が実は合理的だったことに気づく・・・かも。
糞スレ埋め
まんこ
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。