【初心者歓迎】C/C++室 Ver.58【環境依存OK】
1 :
デフォルトの名無しさん :
2008/08/06(水) 20:56:17
2get
刀、 , ヘ
/´ ̄`ヽ /: : : \_____/: : : : ヽ、
,. -‐┴─‐- <^ヽ、: : : : : : : : : : : : : : : : : : : : : : }
/: : : : : : : : : : : : : :`.ヽl____: : : : : : : : : : : : : : : : : : /
,. -──「`: : : : : : : : : :ヽ: : : : : : : : :\ `ヽ ̄ ̄ ̄ フ: : : : :/
/: :.,.-ァ: : : |: : : : : : : : : :\: : : : :: : : :ヽ \ /: : : :/
 ̄ ̄/: : : : ヽ: : : . . . . . . . . . . .、 \=--: : : :.i / /: : : : :/
/: : ∧: \: : : : : : : : : : ヽ: :\: : : 〃}/ /: : : : :/ 、
. /: : / . : : :! ヽ: : l\_\/: : : : :\: ヽ彡: : | /: : : : :/ |\
/: : ィ: : : : :.i: : | \!___/ ヽ:: : : : : : :\|:.:.:.:/:! ,': : : : / |: : \
/ / !: : : : :.ト‐|- ヽ \: : : : : l::::__:' :/ i: : : : :{ |: : : :.ヽ
l/ |: : :!: : .l: :| \: : : l´r. Y {: : : : :丶_______.ノ: : : : : :}
l: : :l: : :ト、| 、___,ィ ヽ: :| ゝ ノ '.: : : : : : : : : : : : : : : : : : : : : : /
|: : :ト、: |: :ヽ ___,彡 ´ ̄´ ヽl-‐' \: : : : : : : : : : : : : : : : : : イ
!: :从ヽ!ヽ.ハ=≠' , ///// ///u /  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
V ヽ| }/// r‐'⌒ヽ イ〉、
ヽ、______ー‐‐' ィ´ /:/:7rt‐---、 こ、これは
>>1 乙じゃなくて
ィ幵ノ ./:/:./:.! !: : : : :!`ヽ ポニーテールなんだから
r‐'T¨「 |: | !:.∨:/:./: :| |: : : : .l: : : :\ 変な勘違いしないでよね!
4 :
デフォルトの名無しさん :2008/08/06(水) 21:19:28
,. -─‐ー=-<._ ノ―- 、
,. '´: : : : : : : : : : : : : :`:<: : : `ヽ、_` 、__
,. -一'´: : : : : : : : : : : : : : : : : : ヽ: : : : :.ヽ ̄
,. '´: . : : : : : i: : : : : : : : :ヽ. :',: : :.丶: : : : :.\
,. '´ ,' イ:.∧:.ヽ: : : : : : :.',: : : . .:',=-: :}:::: : :|: : : ヽ
_,. '´-‐'7 . . : : : : :/|:.l ヽ: :l\‐- 、: :.',: : : : :.!: : :.`、::: :lミ、: :.}/^i
.  ̄ /: : : : :i: : : : l, |:.| \! \: : : : ',: : : : .!: :.〃}::: :l }: :/ イ
/: : :./: :!: : :./| l:| ヽ \: : :.',: : :l:.|: ://:|::::/ノ‐'´ノ/
/: : /{: : |: : : : | l:l r勿示ミ、',: :.!:.|彡':::!:/´ ィ_
l: :/ !: : l: :.l: :.lxィキ !::fr..:ト、!: ト.:ト、::::从 ,. ' ´ `i
|/ |: : :!: ヽ.:{ 代..ヽ 代.じ:| |: l´ヘ Y ノ'´ |
|: : : ',: :.ト〈{:::じi| 辷ソ !/ }} ノ / l._ 私じゃ
>>1 乙って出来ないみたい
l: : : ∧:.い弋ソ . xxx ,.ァ ' { }
l: : / ヾヽ}xxx __,. ∠、 l l
!: :l ヽ、.__ ,. ィ〃: : y'⌒ヽ、! |
ヽ{ ,.`「¨刀´ /: : / >、 l
ノ ノ: : :l /: / ,. '´ .::rヽ、 ヽ
/ ヽ: : :.l // / ,.. | }
{ \:| // ,. '´ / ! |
/\ Y/ イ / ノ
>>4 つかさちゃんきゃわあああああああああああ!!!!!!!!!!!!
つかさちゃんとちゅっちゅしたいよ〜
6 :
デフォルトの名無しさん :2008/08/07(木) 01:47:42
gdbで一行ずつ見ていくとSegmentationFault出さずに終了するんだけど 普通に実行するとエラー吐いて終了してしまいます。こういう場合どんな原因が考えられますか?
うははははは
float i = 0.0f; while( i != 7.0f) { i += 0.1f; } これだとwhileで7が認識されず終わらない。 0.2とか色々数値を変えても終わらない。 でもi += 1だと終わる。 なぜか 1を半分に割っていく数値0.5,0.25.0.125といった数値なら抜けれる。 謎過ぎてもう頭がパーンしそう。 誰か原因わかる人居ますか?
>>9 9割自分で答えが導けてるじゃないか
2進数で小数を表現すると、0.5、0.25、0.125…しか正確に表せないからだよ
でも丸めが出るから処理系によって上手く「動いてしまう」ときもある。
浮動小数点数でwikiれば自ずとわかる
>>9 浮動小数点数(float/double)で表現できる数値について
学校の宿題なんだろ。 >なぜか 1を半分に割っていく数値0.5,0.25.0.125といった数値なら抜けれる。 これは、そのヒントっぽいな。本人はわかってなかったり。
な・・なんだと・・・ そんな法則があったのかw 自力でその法則を発見した俺は数学者になる素質があるな、と思った。 とりあえずおまいらありがとう。
数学者?
少数を比較するときは範囲で比較しようって学校で教えてくれなかったんか?
複数行の文章が書いてあるテキストファイルから 一行ごとにもじれすを抜き出す方法を教えてくださいm(_ _)m
もじれすってなに?
文字列のことだろうか。 fgets()は? あるいはcin.getline()とか。
24 :
デフォルトの名無しさん :2008/08/08(金) 12:08:50
申し訳ありませんが、詰まってしまったので・・・ XP SP2 VS2005 c++8.0 なのですが、 MultiByteToWideChar を行った際に、変換後の文字列にゴミが付加されてしまいます なぜなんでしょ・・・ 以下、コードです。よろしくお願いします。 CString UtoT(const xmlChar* str, int len) { CString ret; if (str) { int wclen = MultiByteToWideChar(CP_UTF8,0, (LPCSTR)str, len, NULL, 0); LPWSTR wcbuf = ret.GetBuffer(wclen); MultiByteToWideChar(CP_UTF8, 0, (LPCSTR%
25 :
24 :2008/08/08(金) 12:11:15
途中送信に成ってしまったので、もう一度。 CString UtoT(const xmlChar* str, int len) { CString ret; if (str) { int wclen = MultiByteToWideChar(CP_UTF8,0, (LPCSTR)str, len, NULL, 0); LPWSTR wcbuf = ret.GetBuffer(wclen); MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)str, len, wcbuf, wclen); ret.ReleaseBuffer(); } return ret; }
>>24-25 0でターミネートしてないだけじゃない?
MB2WC()のlenをlen+1にすれば解決する予感。
>>23 たぶん配列のキューの方が速い
要素を追加/削除するたびにメモリの確保/解放をせずに済む
リストのキューは、追加/削除するたびにノードを確保/解放する必要がある
メモリ効率は、配列のキューは要素が空いててもその分のメモリを解放できない点で無駄があるが、
リストのキューも要素ごとに次のノードを指すポインタが必要という点でやはり無駄な部分がある
どっちが特に優れているというわけではない
状況に応じて使い分けるもの
28 :
24 :2008/08/08(金) 12:46:26
>>27 ありがとうございました。
キューのサンプルを探したところ、リストを用いたものばかりだったので
疑問に思い、質問した次第です。
地震だ><
キューならstd::dequeかboost::circular_bufferが良いのじゃないかな
>31 ありがとうございます。 わざわざ作らずとも、すでに用意されているのですね
こんにちは。ポインタと free() についての質問になると思います。 C は初心者ながらも単機能な Web サーバを作ってみようと思い立ち、 libevent を触ってみています。 evbuffer という構造体が出てきますが、 evbuffer_free() では orig_buffer と buffer を free() しています。 void evbuffer_free(struct evbuffer *buffer) { if (buffer->orig_buffer != NULL) free(buffer->orig_buffer); free(buffer); } そこで、 orig_buffer と buffer の正体を見てみようと、 PHP でいう print_r のような関数を作って調べてみました。 evbuffer: 0x606080 size_t misalign: 0, totallen: 256, off: 4 void* cb: 0x0, cbarg: 0x0 u_char* buffer: 0x609100 [HOGE] u_char* orig_buffer: 0x609100 [HOGE] buffer と orig_buffer は同じ場所を指しているように見えます。 二回も free() して大丈夫なのでしょうか。
34 :
32 :2008/08/08(金) 21:11:20
>>33 のアドレスでいうと
if(0x609100 != NULL) free(0x609100);
free(0x606080);
になると思いますよ
37 :
32 :2008/08/08(金) 21:36:55
>>35 よくわかりました。ものすごく勘違いしていました!
free(buffer->buffer); しているものと空目していました。
ありがとうございます!
38 :
デフォルトの名無しさん :2008/08/08(金) 22:22:48
Effective C++ 第3版12項にコピーコンストラクタの実装でコピー代入演算子を 呼び出すことはナンセンスと書いてあるが、実際どういう弊害があるんですか? これでいい気がするんだけど。 ClassA& operator=(const ClassA& rhs) { メンバ変数 = rhs.メンバ変数; return (*this); } ClassA::ClassA(const ClassA& rhs) { (*this) = rhs; }
初期化リストが使えないとか その例だと意味無いが
>>38 もしoperator =はthisがすでに初期化済みであることを前提にしたコードを書いた場合、
コピーコンストラクタの中では初期化されていないので=演算子を使えないという事態に陥ってしまう。
そうでないとしても、時と場合にもよるが一般的にデフォルト構築+代入演算はコピーコンストラクタよりコストがかかるとされている。
Effective C++に載っていなかった気がするからここに書くけど、
こうやって、=演算子はコピーコンストラクタ(とswap)を使って実装できる。元ネタはExceptional C++。
ClassA& operator=(const ClassA& rhs)
{
ClassA tmp(*this);
tmp.swap(rhs);
return *this;
}
実害はないんじゃないの? 「覚えておくこと」のところに共通の処理は別の関数に実装すれば良い みたいなこと書いてあるし 「代入は既に存在するモノの値を変えるのに使う。 まだ存在していないモノに対して行うのはおかしい」って事だと読み取ったけど
newで確保した領域の容量ってsizeofで求められないんですか? byte *p=new byte [1000]; int size=sizeof(p); ってしてもsizeof(p)が実行されなんですが何で?
43 :
デフォルトの名無しさん :2008/08/09(土) 08:04:28
>>42 実行されます。
ポインタのサイズが返ります。
>ってしてもsizeof(p)が実行されなんですが何で? どうして>42みたいな質問する奴ってこれだけの文章もまともに書けないんだろうな。 しかも、ちょっと探せばすぐに見つかるのに。
45 :
38 :2008/08/09(土) 10:55:23
>>39-41 参考になります。
コストはかかるがoperator=をそれなりに実装しておけば問題ないってことですかね。
atan2のテーブルを高速参照したいんだが何かいい方法はないですか? 高速であればテーブルじゃなくてもいいです 環境はcygwin上のgccで、math.hとかはあります
48 :
46 :2008/08/09(土) 12:52:21
>>47 精度は単精度floatです。
制約条件っていうのがよくわからないので教えてください
>>48 引数ってんだから、その形式とか範囲とかじゃね?
三角関数系はゲームとかだと360度やラジアンでやるより
一周を0xffや0xffffにしたほうが扱いやすいし…、とかそういう
ことだと思うが。あ、おれ47じゃないから
>>49 形式はfloatで1周1024で分割
ってかんじでいいんですかね?
それだったら、単にテーブルを作るだけでいいと思うが。
atan2だと、引数の精度(x,y)がfloatで、戻り値の角度が一周1024ってこと? 45度ごとに場合分けして、小さい方を大きい方で割って、 まあ2048倍して、テーブル2048個から0〜1023を返すようにすりゃいんじゃない? 倍にしてるのは気分的に。
あ、ちょっと違うか、1週1024なら45度の範囲だとその 1/8のテーブル量で済むわ
どうでもいいけど、atanをあーたんと読むとちょっとカワイイよな
独学でC++、DirectX、Win32APIでゲームを作り始めたんですが、 いつも設計に悩まされ、綺麗な形にできません。 起動した瞬間開始する単純な2Dシューティングから始まり、 メニュー画面を追加し、一時停止画面を追加し、 エロゲーみたいな会話画面をはさみ、3D描画を入れたりと、 機能追加するごとに、設計がぐだぐだで汚くなっていきます。 プログラムは2chとグーグルだけで覚えたので、 他人が作ったアプリのソース全体を見たことがないんですが、 アプリケーション全体の設計を勉強するにはどうすればいいでしょうか? 何かお勧めの本があったら教えてもらえませんか。
あーくたんもカワユイ
>>55 適当なデザインパターンの本を読んでふむふむと思いつつ、
あとは習うより慣れろで行くしかないと思う。
俺も同じような時期があったから一言だけ言わせてもらうと、
『本当に必要のないものは実装するな』の一言に尽きる。
>>54 こたんはなんか犯罪の香り
>55 まずは構造化プログラミングですね。>57の言うようにデザインパターンとかってのもあるけど、 >起動した瞬間開始する単純な2Dシューティングから始まり、 >メニュー画面を追加し、一時停止画面を追加し、 >エロゲーみたいな会話画面をはさみ、3D描画を入れたりと、 >機能追加するごとに、設計がぐだぐだで汚くなっていきます。 を見る限りでは、オブジェクトとのマッピングや責務分割を考えるよりも、スパゲッティっぽくなってるのをちゃんと整理する力をつけるのが先かと。 あと、今時、全てを一つのEXEで作らなくても良い、と言うのも重要。
ゲームだとタスクシステムとかかなぁ
>>43 ありがとう
ずっと確保した容量が返ってくるものだと勘違いして使ってた
確保サイズが知りたい場合は_msizeだそうな(注:Windows限定)
× Windows限定 × VC限定
64 :
55 :2008/08/09(土) 20:31:01
>>57 まだ、何ができるかをちゃんと把握してないので、
思いついたものや試しをどんどん追加実装してるのが一番問題っぽいですが、
習作なので仕方ないかなとも思います。
実装するものの全体像を把握するまで、慣れるしかないですかね。
>>58 EXEを分割できるとは知りませんでした。
そういう場合、複数EXEで共用するモジュールを作ったりするんでしょうか。
それともまったく独立して複数作るんですか?
>実装するものの全体像を把握するまで、慣れるしかないですかね。 ゲームプログラマーから一言。 あとからいくらでも追加に耐えられるように組むこと。 全体像なんて最初から最後まで同じである保証なんてどこにも無いよ〜 >EXEを分割できるとは知りませんでした。 ニュアンスが違うんじゃないか? ゲームだったらEXE一個だよ。分割なんか考えなくていい。 まあ機能ごとにDLLに分解するのはあると思うが、まだそんなこと考えなくてもいいだろう。
>>65 拡張性を無視して作って変更が出たら作り直すって手法なかったっけ?
一回やってみたいと思ってるんだが勇気がなんだ
アジャイル?
>>66 >拡張性を無視して作って変更が出たら作り直すって手法なかったっけ?
かってにすればーw
冗談じゃねー、1回作り直すのに数年かかるわ!
XP?
>>67 >>69 ああ、そんなんだった、調べてみる
>>68 >冗談じゃねー、1回作り直すのに数年かかるわ!
俺もそう思うんだ、だからやってみたことはない。
でも手法として確立してるからにはどうにかなるのだろうとは思う。
ちょっと調べてみていけそうなら今度提案してみる。
XPでなんとなく理解できたのはペアプログラミングくらいだったな
>>52 ,53さんありがとうございます。
また質問になりますすみません。
環境は
>>46 と同じです
error: cannot convert 'Bullet (*)[100]' to 'Bullet**' for argument '4' to 'void Shot(int, Image*, MyShip*, Bullet**)'
という意味はわかるのですがですが、改善法が分からないエラーが出て困っています
typedef struct{
略
}Bullet;
Bullet shot[100];
Shot(ctrlmode, bullet, &MyShip, &shot);
void Shot(int shot_ctrl_flg, Image* Star,MyShip *MyShip,Bullet *shot[]){略}
どこがいけないのでしょうか?
構造体の中身を全て = 0 にするにはどうしたらいいですか。 宣言のときなら struct hoge a = {0}; でできると思いますが。 全ての中身に対して = 0 をするコードを書くしかないですか。
構造体の中身が全て整数型なら0にmemsetすることで実現できます。 それ以外の場合は0を意味する値を代入するしかありません。
>>73 struct hoge a;
...;
struct hoge zero = {0};
a = zero;
a = hoge();
>>72 Shot(ctrlmode, bullet, &MyShip, shot);
void Shot(int shot_ctrl_flg, Image* Star,MyShip *MyShip,Bullet shot[]){略}
>>72 引数shotの型が違う。
Bullet shot[100]; のとき、&shotは配列へのポインタで
関数の仮引数のBullet *shot[]はBulletへのポインタへのポインタ。
何がしたいのか良く分からんけど。
Bullet shot[100];
void Shot(int shot_ctrl_flg, Image* Star,MyShip *MyShip,Bullet *shot){略}
か
Bullet *shot[100];
void Shot(int shot_ctrl_flg, Image* Star,MyShip *MyShip,Bullet *shot[]){略}
こうで、
Shot(ctrlmode, bullet, &MyShip, shot);
こうじゃね?
>>78 配列がまずいのですかね?
両方ともやりましたが結果は同じでした・・・
MyShip *MyShipってありなのかぁ…
newでchar型の配列を1521090492個以上確保したらエラーがでるのですが何故でしょうか? メモリは4G積んでるんでメモリが足りなくて確保できないってことではないと思うんですが newで確保できるのは1521090492byteまでって決まってたりするんですか?
それはコンパイラを作った人に訊いてくれ。
どんなエラーよ? 他にもOSとかコンパイラとか色々あるじゃん。書くことが。
ごめんなさいコンパイルは通るけど、それを実行すると確保するところでエラーでる mlock.cの void __cdecl _unlock (int locknum){ //leave the critical section. LeaveCriticalSection( _locktable[locknum].lock ); } で 0x7d4f2366 でハンドルされていない例外が発生しました: Microsoft C++ の 例外: std::bad_alloc (メモリの場所 0x0012fe40)。 ってエラーがでます これってコンパイラかデバッガの仕様なんですか? ソースはこんなのでnewのところでエラー int main(){ char *p; p=new char [1521090493]; delete [] p; return 0; }
>>85 そもそもWindowsでは32ビットアプリで32ビット(2GiB)以上のメモリ空間をアクセスする単純な手段は提供されていません。
大人しく64ビットアプリを作るか、ありえないメモリ戦略を諦めることをお勧めします。
OSはXPx64でコンパイラはVisualStudio2008Proです タスクマネージャでみるとメモリのコミットチャージは newで確保前は470MB/3826MBで充分空いてます
std::bad_allocでググれば。
>>86 ありがとうございます。32ビットでも2Gまでならいけるはずですよね
とりあえずこんなに確保するつもりは無いんですが、色々試したら[1521090492]
を超えたところでエラーがでたので興味本位できいてみただけです。
>>88 ググったら色々情報でてきた。あとは自分で調べてみることにします
ゲームでアジャイルとかできるんかね。 ゲーム作ったことないけどテストパターンが割りと膨大になりそうにおもう。
Code::Blocks(MinGWつき)とwxWidgetsをWindows XPにインストールした後、 「壮大な一歩を踏み出すぞ〜」と意気込んで、とりあえずwxWidgetsプロジェクトではなく 以下のコードをビルド、出来上がったexeをコマンドプロンプトにて実行しました。 #include <iostream> using namespace std; int main() { cout << "こんにちわ世界" << endl; } 日本語は文字化けしてしまったので、プロンプトのフォントをMSゴシックに変えたんですが それでも駄目で、壮大な一歩を踏み外してしまいました。 Unicodeがらみの文字化けというところまでは分かるのですが、解決策が分かりません。 Code::Blocks WikiのWxWindowsQuickRefに書かれているBuild wxWidgetsはすでに終えたのですが、 まだwxWidgetsを使う所まで行ってないので、関係ないだろうし。 Code::BlocksとwxWidgetsでC++を始めようと考えていたのですが、かなり道は険しいようです……。
>>91 ソースコードの文字コードを変えてみては?
なんでもいいけど、int main なら値返そうよ。 2歩目も怪しい。
>>93 C++ならmainでreturnしないとreturn 0:したことになるって規則があって問題ない。
省略していいかどうかはまた別問題。
UNICODEで文字列を表示したいのか 単に日本語を表示したいのか
>>91 g++なら--input-charset=cp932 --exec-charset=cp932でどう?
Code::Blocksでどう設定するかは知らないけど。
ソースをUTF-8か何かで書いてるのかな
これって問題あるでしょうか? struct hoge { int x; }; hoge *ptr; hoge &ref = *ptr; ptr = new hoge; //参照を作った後に確保 ref.x = 1; //参照からアクセス
問題なし
問題あり。 refの指している先はnewされたところではない。
102 :
デフォルトの名無しさん :2008/08/10(日) 08:32:10
動かしてないけど hoge &ref = *ptr; のところで落ちるんじゃない? ptrは無効なポインタだからね、この時点で。
そもそもなんでnewしたいんだ? そこから見直すべきだな。
>>102 試して落ちたの?
中身へのアクセスは無いからそこじゃ落ちないと思うけど。俺は試してないw
遅れてすみません
>>80 それはまずいですかね?
別の名前に変えてみます
>>81 言葉が足りませんでした、すみません
まさにその通りです
106 :
デフォルトの名無しさん :2008/08/10(日) 08:52:57
>>104 そうかもね
「動かしてない」って書いたジャン・・
規格的に、どこを指してるかわからないポインタに"*"を適用した時点で、鼻から悪魔が出るかもしれない、はず。 実装的にも、大抵は「どこを指してるかわからないポインタ変数の指すアドレス」をコピーして別の変数に保持するだけだろうから HDDをフォーマットしてスパムメールを送りまくってももおかしくない、はず。
>HDDをフォーマットしてスパムメールを送りまくってももおかしくない、はず。 おかしいと思います。文章が。
いいもも〜
110 :
デフォルトの名無しさん :2008/08/10(日) 11:57:43
>>109 中学生の太もも??
いいももだよねーーー
ハァハァハァハァハァハァハァ
mapに関する質問です。以下のようなプログラムをビルドした際に、 (1)または(2)のように記述するとエラーとなりました。 error C2662: 'MYTYPE::hoge' : 'const MYTYPE' から'MYTYPE &' へ 'this' ポインタを変換できません なぜ(1)(2)だと失敗するのか、(3)だと成功するのか教えていただけないでしょうか。 ※環境 WindowsVista, Visual C++ 2008 Express map<string, vector<MYTYPE> > mapA; for(map<string, vector<MYTYPE> >::const_iterator it = mapA.begin(); it != mapPitcher.end(); ++it) { // イテレータを用いた方法 for(vector<MYTYPE>::const_iterator it2 = it->second.begin(); it2 != it->second.end(); ++itv) { it2->hoge(); // (1)コンパイルエラー } // イテレータを用いない方法 for(vector<MYTYPE>::size_type size = 0; size != it->second.size(); ++size) { it->second[size].hoge(); // (2)コンパイルエラー mapA[it->first][size].hoge(); // (3)成功 } }
>>111 MYTYPE::hogeがconstでないから、const MYTYPEに対してhogeを呼べない。
試しに↓やってみ。
const MYTYPE x;
x.hoge();
↓のようにhogeにconstを付ければok。
struct MYTYPE {
void hoge() const;
};
void MYTYPE::hoge() const {
...
}
113 :
111 :2008/08/10(日) 13:36:10
>>112 ありがとうございます。関数にconstをつけることで(1)(2)ともにコンパイルに成功することができました。ただ、
>const MYTYPE x;
のように、変数宣言の時にconstをつけた場合に
>void hoge() cosnt;
とすればよいと自分なりに解釈したのですが、変数宣言は上で書いたとおり
map<string, vector<MYTYPE> > mapA;
とMYTYPEにconstをつけていません。どこでconstがついたのか教えていただけないでしょうか。
たびたびで申し訳ありませんが、よろしくお願いします。
const_iteratorだからじゃね
>>113 >どこでconstがついたのか
根本的に勘違いしてる。オブジェクトがconstかどうかと、
メンバ関数のconst指定は、まったく無関係ではないが
基本的に別物
116 :
111 :2008/08/10(日) 14:27:47
>>114 const_iterator → iterator とすると、エラーになりませんでした。
イテレータについてまだ理解していないので、勉強したいと思います。
ありがとうございました。
117 :
111 :2008/08/10(日) 14:34:27
>>115 >>113 の解釈は間違っているということですね。
オブジェクトのconstとメンバ関数のconst指定について調べていきたいと思います。
ご指摘、ありがとうございます。
わざわざconst_iteratorを使ってるからには、constになることくらいわかってるんだと思ってた 世の中難しいものだ
>>118 イテレータについての理解があまりなく、参考書丸写ししてました。
120 :
デフォルトの名無しさん :2008/08/10(日) 17:12:14
C言語の標準ライブラリ関数qsortについての質問です この関数はメモリ上で連続していない配列に対しても動作は保証されているんでしょうか?
122 :
120 :2008/08/10(日) 17:27:06
>>121 そうでしたか。
回答ありがとうございました。
123 :
120 :2008/08/10(日) 17:32:00
よく考えたら連続していない配列って・・・。 お恥ずかしい限りです。
少しスレ違いかもしれませんが、VC++で作った実行ファイルについての質問です。 リリースビルドした実行ファイルを覗くと、pdbファイルへのパスがそのまま残っているのですが、 これは他の数、例えば0x00等で塗りつぶしてしまってもいいのでしょうか? 問題なく動いているように見えますが、異常終了した際になにか不具合がでたりしませんか?
>124 失礼しました、コンパイラはBorland C++ 5.5.1です。
>>124 >>126 BCCなら、多分Makefileの問題じゃないかね?
コンパイルするときに分割コンパイルするオプション付いてる?
-oか何かだと思うけど。
ごめん。大嘘コイた。 多分-c
>127-128 ありがとうございます!ご指摘のとおりでした。
>>125 そんな面倒なことしなくてもコンパイラオプションで消せる。
>>130 ありがとうございます。
なんでデフォでリリースビルドにデバッグ情報埋め込んでるのやら……
以下のようにvoid*型にポインタを変換したとき、 delete時にデストラクタが呼ばれるでしょうか? class test { int *p; public: test(){ p = new int(); } ~test(){ delete p; } }; int main() { void *ptr = (void*)(new test()); delete ptr; return 0; }
_
>>132 delete p;
の上にprintfを入れて試してみては?
136 :
132 :2008/08/10(日) 21:58:43
そりゃvoid*で型情報消してるし
じゃあどうしてvoid*型の変数をdelete/delete[]しようとするとエラーが出るようにはならないんですか? new void;とかできませんよね?なぜ?どうして?
>>131 リリース版でもデバッグできるって結構便利だと俺は思う。
>>138 エラーにしたいという要望だけはboost::checked_delete使えば叶う。
あと、boost::shared_ptr<void>だとデストラクタが呼ばれるというマジックもある。
140 :
135 :2008/08/10(日) 22:28:54
>>138 gccならwarning deleting void* is undefinedって警告がでた。
>>73 なんだけど
gccで構造体を = {0} して初期化すると、「最初以外の、他の中身の初期化子(?)がない」っていう警告が出るんだけど、
これは無視してもいいの?
それ構造体か?構造体の配列とかでやってないか?
構造体です。例えば具体的に言うと、struct tm(mktimeとかで使う、time_tを要素毎に分けた奴)で、 struct tm a = {0}; ってすると、 *.cpp:36: warning: missing initializer for member `tm::tm_min' *.cpp:36: warning: missing initializer for member `tm::tm_hour' *.cpp:36: warning: missing initializer for member `tm::tm_mday' *.cpp:36: warning: missing initializer for member `tm::tm_mon' *.cpp:36: warning: missing initializer for member `tm::tm_year' *.cpp:36: warning: missing initializer for member `tm::tm_wday' *.cpp:36: warning: missing initializer for member `tm::tm_yday' *.cpp:36: warning: missing initializer for member `tm::tm_isdst' って出ます。(最初のtm::tm_secだけ警告が出ない) コンパイル時の設定は -Wall -W ってやってるんだけど、問題ないんだったら、これだけ警告でないようにできないかな…
なら struct tm a = {0, 0, 0, 0, 0, 0, 0, 0, 0}; にすると出なくなるような気がしないでもない。
テンプレートの引数にoffsetofを使いたいのですが、 offsetに使用するパラメータがprivate内にあると エラーがでてしまいます。 なんとかメンバをprivateにしたいのですが、 手は無いでしょうか。 template <int T> class test { }; class Hoge1 { friend test<offsetof(Hoge1, Hoge1::a)>; public: private: int a; }; 以下の様にするとエラー無し。 template <int T> class test { }; class Hoge1 { public: int a; }; test<offsetof(Hoge1, Hoge1::a)>; よろしくお願いいたします
>>145 そもそもクラス(非PODか?)では、変数が宣言順に配置されるという保証がなかったと思う。
危険コードかもよ。
>>146 こらこら
クラスは変数が宣言順に配置されるぞ
メンバ関数だけは別扱いだけど
メンバ関数ポインタも宣言順に配置される
148 :
デフォルトの名無しさん :2008/08/11(月) 10:20:49
>>145 そのコードの目的が分からん
offsetofを使わずに済むコードを考えた方がいいんじゃない
見てていらつくコードなんだけど
C++でクラス内でoffsetofを使うのは大抵委譲を使う場合だな
else if{ } と else{ if{ } } とで内部的に違いありますか? 見た目的にネストは浅くした方がいいのかな?
>>150 前者はelseの後に複文が書けない
後者は複文が書ける
それ以外は同じ
>>147 一般論?
なら順序が保証されるのはアクセス指定子が間に挟まらない場合だけだった気がする。
155 :
152 :2008/08/11(月) 14:09:51
昔、sunかどっかのCコンパイラのstructのメンバの順番が ソースの上下と逆だった覚えがある。 それ以来構造体のメンバの順番に依存したコードは書かなく なったので、構造体が拡張されたC++ではどうなのか気にした こともないやw
トラウマというやつですね
仮に配置が宣言順にならない場合も、初期化子の実行順は保証されますか?
>>158 されます
宣言順です
並べた初期化子の順ではありません
C言語検定の1級をもってるとゲームプログラマーとして就職するときどのくらい有利ですか?
宣言順にならないとき、Cスタイルの初期化はプログラマの意図した通りになる? struct hoge { int a; int b; }; hoge h = {1,2};//h.a==1,h.b==2
>>160 それでやっと最低限。しかも資格持っていないC言語分かってる
連中とまったく対等くらい
こころなしか足しになる程度であんまり意味は無いんじゃないかと あの程度は研修で叩き込まれたらすぐ身に付くレベル 他の要素のほうが重要視されるだろう
なるほど、じゃあ線形代数ができる等 のほうが強みになるってことですか。 スレ違いの質問に答えていただきありがとうございました。
>>164 ゲームプログラマーとして(大手に)就職したいなら、普通に
大卒か院卒で、趣味でゲーム一本でも作っておけ。
チームで作ってメインプログラマ兼取りまとめ役とか
だとポイント高いよ。
-> これはどういう意味ですか? こんな感じで使われているようです。 node->setMaterialFlag(EMF_LIGHTING, true); また何と呼ばれてますか? ->でgoogleで検索かけてもかからないので困ってます。
>>166 アロー演算子
(*node).setMaterialFlag(EMF_LIGHTING, true)
の書き方が違うだけ
あるクラスの実体である、node変数のsetMaterialFlag()メンバ関数を呼び出している class CHoge { setMaterialFlag(XXX, bool){} };
なんでメンバのアクセスって.と->に分けてるんだろう。 どちらかに統一すると困るケースが思いつかないのですが、 何か理由があるのでしょうか?
>>170 *(p + i)で事が足りるのにp[i]と書けるのと同じ理由で、
(* p).mで事が足りるけれどもp->mと書けるようにしてある。
タイプを楽にするためですよ
そういうのって糖衣構文と言うのだったかな?
いや、ポインタでも実体でもどちらも.か->に統一してくれたほうが ジェネリックプログラムで楽で、メリットがあるのではと思ったんですよ。 そういうメリットを捨てて*や->を使わせてるのは、 ポインタからメンバにアクセスするのに*をつかわないで直接 ptr.mで良いようにしてしまうと、言語仕様として何か不都合が あるからなのかなと、疑問に思ったわけで。
なんか数ヶ月前にも似たような話題があった。
ptrptr-->m
歴史的経緯は知らんが状態を持つイテレータを使うので . と->の両方が無いと困る。
Cのころからそうだったのを受け継いでいるのはおいといて、 C++では「.」はオーバーロードできない(させない)という差がある。 ->はオーバーロードできる。いろんな都合で現状のルールに落ち 着いてるようだ。
Dだとどっちも . でいけるって話なかったっけ?
gccで特定のファイルというか場所というかインクルードしたファイルに対してだけ警告がでないようにはできますか? 使っている環境のgccで警告を厳しくすると、stlに対して大量の警告がでてしまうので、うっとおしいんです スクロールしないと見たい警告みれないですし 自分でstl側をいじれる環境ではないです
配列とポインタで A *a=new A[100]; A b[10][10]; とした時に &((((*A)[10])a)[i][j]) - a == &(b[i][j]) - b これって常に成り立ちますか?
>>181 要するに要素数10の配列へのポインタへ強引にキャストして
成り立つかというわけでしょ。
そりゃ成り立つわ。
サン・クスコ
どういたしマチュピチュ
マンコ=カパックがどうしたの?
今知ったんだけど、newって失敗したらNULLを返すと思ってたけど違うのね ずっと p=new int [1000]; if(p==NULL){〜 みたいな意味ないことしてた…
nothrow
パスの後ろに '\\' が無い場合は追加する関数を作ったんですが, "像\\" とかだとさらに追加されて "像\\\\" になってしまいます. 正確にやるには先頭から調べるか, wstring に変換するしかないでしょうか? std::string& AddBackslashIfNotExist1(std::string* ptrPath) { std::string& strPath = *ptrPath; if( strPath.empty() ) return strPath; if( strPath[ strPath.size()-1 ] != '\\' ) return strPath += '\\'; if( strPath.size() > 1 ) { if( _ismbblead( strPath[ strPath.size()-2 ] ) ) return strPath += '\\'; } return strPath; }
要するにSJISの2バイト目が\の文字の対策ってことだよね? 先頭から見て行くか別の文字コードにするしか手は無いよ。
>>188 SJISの1バイト目領域⊂2バイト目領域だから、これはいかんともしがたい。
>>188 律儀に先頭から見る必要は必ずしもないけれど、1バイトずつ遡る関数を作ったところで効率はさほどよくならないね。
192 :
188 :2008/08/14(木) 08:14:20
>>189-191 解答ありがとうございます.
遡るのは面倒なので wstring に変換して調べることにします.
C++のコンパイルの仕方がわかりません
>>193 エイホが書いたドラゴンブックとか、アマゾンで「コンパイラ」関連の書籍を読んでみては?
>>193 はそういう質問なんだろうか
・ソースの拡張子をcppにしてみよう
・ccではなくc++コマンドを使おう
・makeのサフィックスルールなんかも気をつけよう
とかいうはなしかと思ってしまった
あの、プロンプトからcppファイルをコンパイルしたいんですけど、どういうコマンドを打てばいいのか解らないんです。
使ってるコンパイラは何よ? それがわからなきゃこっちもエスパー回答しかできない
Visual Studio 2008だと思います
>>196 コマンドプロンプトはあきらめて、普通にビルドしてはいけないのですか?
VC9ならcl ソースファイル名 だよ。 でもその前に vcvars32.bat を実行してからにしてね。
>>199 コマンドプロンプトの方が手軽に見えたので
有難う御座います。解決しました
関数の戻り値を配列に場合どう記述すればいいのでしょうか?
>>203 まずローカル変数を返さないように注意しろよ。
次に受け取った配列の先頭アドレスを返すようにするか、
もしくは配列そのものを返したければ構造体の中に配列を入れて
返すようにする。
すごいコードに展開されててワロタ #include <stdlib.h> struct Int { int N[10000]; }; struct Int func(struct Int a); int main(void) { int i; struct Int *a = (struct Int *)malloc(sizeof(struct Int)); for (i = 0; i < 100000; i++) func(*a); free(a); return 0; } struct Int func(struct Int a) { return a; }
構造体にしまった意味が無いだろwwwww
だって配列そのものを返すには?って聞かれたんだもんwww
>struct Int *a = (struct Int *)malloc(sizeof(struct Int)); これ笑いどころ?
そうでした もうしわけありませんでした
>>208 static領域に確保したらつまらないコードを吐くもんで
わざとそうした
スレ誘導されてきました #include <iostream> using namespace std; //2直線の交点を求める関数 double lineIntersect(double *L1Point, double L1Slope, double *L2Point, double L2Slope); int main() { double P1[2] = {4, 10}; double P2[2] = {6, 18}; double S1 = 2/3; double S2 = 1/3; double ans[2] = {0, 0}; *ans = lineIntersect(P1, S1, P2, S2); cout << "交点の座標は" << ans[0] << '/' << ans[1] << "です\n"; return 0; } double lineIntersect(double *L1Point, double L1Slope, double *L2Point, double L2Slope) { double ans[2] = {0, 0}; ans[0] = (L1Slope * L1Point[0] - L2Slope * L2Point[0] + L2Point[1] - L1Point[1]) / (L2Slope - L1Slope); ans[1] = L1Slope * (ans[0] - L1Point[0]) + L1Point[1]; return ans; } 30分位調べたり考えたりしたのですが1つだけエラーが解決しません;; cpp(29) : error C2440: 'return' : 'double [2]' から 'double' に変換できません。
>double lineIntersect(double *L1Point, double L1Slope, double *L2Point, double L2Slope) { >double [2]lineIntersect(double *L1Point, double L1Slope, double *L2Point, double L2Slope) {
ローカル変数のアドレスだと・・・
(double *)[2] どちらにしろ関数を抜けた時点で実体がなくなるわけだが。 構造体にして返すなり工夫をしろ
215 :
208 :2008/08/14(木) 18:26:09
構造体の考え方で記述してみます アドバイスありがとうございました
>(double *)[2] これじゃエラーか double (*)[2] だな
ポインタ引数を使うのが普通かな。 double lineIntersect(double *L1Point, double L1Slope, double *L2Point, double L2Slope, double* ans1, double* ans2)
219 :
211 :2008/08/14(木) 19:32:40
構造体を利用して記述しています。 まだ途中ですができそうな気がしてきました。 結果が出たら報告します。
#include <iostream> using namespace std; struct Point{ double L1Point[2]; double L2Point[2]; double L1Slope; double L2Slope; double num[2]; }; double ans[2]; Point pt = {10, 20, 20, 44, 10, 3, 3, 20}; double lineIntersect(Point* pt1); int main() { *ans = lineIntersect(&pt); cout << "答えは(" << ans[0] << ',' << ans[1] << ")です\n"; return 0; } double lineIntersect(Point* pt1){ pt1->num[0] = (pt1->L1Slope * pt1->L1Point[0] - pt1->L2Slope * pt1->L2Point[0] + pt1->L2Point[1] - pt1->L1Point[1]) / (pt1->L1Slope - pt1->L2Slope); pt1->num[1] = pt1->L1Slope * (pt1->num[0] - pt1->L1Point[0]) + pt1->L1Point[1]; return pt1->num; } """"""'return' : 'double [2]' から 'double' に変換できません"""""" 構造体でやってみたのですが同じエラーが出てできません;; 自分のスキルが足りないのは百も承知ですが誰かアドバイスいただけませんか? 214さんの(double *)[2]をどこかで使えばいいのでしょうか。
>>220 ×return pt1->num;
○return pt;
×double lineIntersect(Point* pt1) ○struct Point *lineIntersect) それから構造体へのポインタを渡しているので 戻り値は別にvoidでもよい。
ところでC言語の仕様ではどうやっても配列そのものを返す事は できんな。 返せたと思ったら配列へのポインタだったorz #include <stdio.h> double (*func(double (*a)[2]))[2]; int main(void) { double a[2][2] = {{1.0, 2.0}, {3.0, 4.0}}; double (*b)[2]; b = func(a); printf("%f %f\n", b[0][0], b[0][1]); printf("%f %f\n", b[1][0], b[1][1]); return 0; } double (*func(double (*a)[2]))[2] { a[1][1] = 10.0; return a; }
221さんと222さんの方法を試しても同じエラーが出たので C言語の本をもう一度やり直してきます。 参考にしたいので誰か時間のある人がいたら 実行できるソース書き込んでもらえたら幸いです。 お騒がせしました。
完全なソースを一応貼っておく。 #include <iostream> struct Point { double L1Point[2]; double L2Point[2]; double L1Slope; double L2Slope; double num[2]; }; Point* lineIntersect(Point* pt1); std::ostream& operator<<(std::ostream& os, const Point& pt); Point pt = {{10, 20}, {20, 44}, 10, 3, {3, 20}}; int main() { Point* ans = lineIntersect(&pt); std::cout << "答えは(" << *ans << ")です\n"; } Point* lineIntersect(Point* pt1) { pt1->num[0] = (pt1->L1Slope * pt1->L1Point[0] - pt1->L2Slope * pt1->L2Point[0] + pt1->L2Point[1] - pt1->L1Point[1]) / (pt1->L1Slope - pt1->L2Slope); pt1->num[1] = pt1->L1Slope * (pt1->num[0] - pt1->L1Point[0]) + pt1->L1Point[1]; return pt1; } std::ostream& operator<<(std::ostream& os, const Point& pt) { os << pt.num[0] << ' ' << pt.num[1]; return os; }
それともう少し言えばC++ならlineIntersectはメンバ関数に すべき。他の変数は全部privateにしてしまう。
連投すまんがC++流に書くなら次のように書いた方が良い #include <iostream> class Point { double L1Point[2]; double L2Point[2]; double L1Slope, L2Slope; double num[2]; public: Point() { L1Point[0] = 10; L1Point[1] = 20; L2Point[0] = 20; L2Point[1] = 44; L1Slope = 10; L2Slope = 3; num[0] = 3; num[1] = 20; } void lineIntersect() { num[0] = (L1Slope * L1Point[0] - L2Slope * L2Point[0] + L2Point[1] - L1Point[1]) / (L1Slope - L2Slope); num[1] = L1Slope * (num[0] - L1Point[0]) + L1Point[1]; } friend std::ostream& operator<<(std::ostream& os, const Point& pt); }; std::ostream& operator<<(std::ostream& os, const Point& pt); int main() { Point ans; ans.lineIntersect(); std::cout << "答えは(" << ans << ")です\n"; } std::ostream& operator<<(std::ostream& os, const Point& pt) { os << pt.num[0] << ' ' << pt.num[1]; return os; }
C++を単なるBetter Cとして使うだけならそこまでする必要はない罠。 しかし日頃からC++を使い慣れている人には気持ちはわかる。 特にプログラムが大規模になればなるほどC流儀よりもC++流儀の方が プログラムをコントロールする労力が遙かに少ない事がわかってくる。 namespaceの必要性も最初は理解できないだろうが、プログラムが大きく なると必然的に必要性がわかってくるし。
#include <iostream> using namespace std; class Point{ private: double L1Point[2]; double L2Point[2]; double L1Slope, L2Slope; double num[2]; public: Point(); void lineIntersect(); void show(); }; //メンバ関数の定義 Point::Point(){ L1Point[0] = 9; L1Point[1] = 6; L2Point[0] = 5; L2Point[1] = 6; L1Slope = 2; L2Slope = 1; num[0] = 0; num[1] = 0; } void Point::lineIntersect(){ num[0] = (L1Slope * L1Point[0] - L2Slope * L2Point[0] + L2Point[1] - L1Point[1]) / (L1Slope - L2Slope); num[1] = L1Slope * (num[0] - L1Point[0]) + L1Point[1]; } void Point::show(){ cout << "答えは(x=" << num[0] << ",y=" << num[1] << ")です\n";} int main(){ Point pt; pt.lineIntersect(); pt.show(); return 0;} 227さんのレスを見て自分なりにコードを書いてみました。無事実行できました。コードで直したほうがいいところがあったら指摘お願いします。
>>230 いいんじゃね?特に問題となるような点はないみたいだ。
当初の質問の『関数から配列を返す』という話題からは
かけ離れてしまったけどそれはいいんだね?
>>231 それも自分で納得できるように理解したいのですが
今のスキルじゃちょっときついのでC言語の本をもう一度読み返してからチャレンジしようと思います。
色々ありがとうございました。
>>232 そうですか。
構造体へのポインタを使えば「データそのものを書き換えてくれ」と
委譲できるし、構造体を返すのは通常オーバーヘッドが大きいので
Cの流儀としてもあまりお勧めできない。
だから構造体へのポインタさえ理解すれば大抵の場合はそれでいいと思う。
効率を無視してポインタを使わずに構造体そのものを返すという事になると だいたい次のようなプログラムになると思う。 これが当初の『配列を関数から返す』に一番近い答えになるだろう。 #include <stdio.h> struct Point { double L1Point[2]; double L2Point[2]; double L1Slope; double L2Slope; double num[2]; }; struct Point lineIntersect(struct Point pt1); struct Point pt = {{10, 20}, {20, 44}, 10, 3, {3, 20}}; int main(void) { struct Point ans = lineIntersect(pt); printf("答えは(%f %fです\n", ans.num[0], ans.num[1]); return 0; } struct Point lineIntersect(struct Point pt1) { pt1.num[0] = (pt1.L1Slope * pt1.L1Point[0] - pt1.L2Slope * pt1.L2Point[0] + pt1.L2Point[1] - pt1.L1Point[1]) / (pt1.L1Slope - pt1.L2Slope); pt1.num[1] = pt1.L1Slope * (pt1.num[0] - pt1.L1Point[0]) + pt1.L1Point[1]; return pt1; }
catchで受け取る型をテンプレートにしたいのですが無理ですか? //こんなの template<class T> } catch(T Obj) { 〜〜
むりだお。 最低限共通の基底クラスから派生させるとかしないとだめ。 もう少し具体的に何がしたいのかを書けば誰か親切な人が考えてくれるかも。
クラステンプレートか関数テンプレートの定義内で、テンプレート引数型でcatchすることは出来るんじゃない。 何がしたいのか分からないのでこれが解決になるのかは分からんが。
class Base{}; class A:public Base{}; class B:public Base{}; みたいな感じで、 class A内で、Baseの値を変えたとき、 class BのBaseの値も変わっているようにするにはどうすればいいのでしょうか?
>>238 そんなことをするくらいなら、class Bがclass Aを継承すればいいんじゃね?
Baseが基底となる全クラスのインスタンスで値を共有したいならBaseの値をstaticにすればいい。
>>238 宣言と実態をごっちゃにしていそうな気がするので、何をしたいのか詳しく。
242 :
デフォルトの名無しさん :2008/08/15(金) 16:00:56
>>238 メンバをすべてstaticにしたらかっこいいYO!
無理しないでグローバルな構造体でいいじゃん^^;
ソースコードの書かれたテキストを読んで、 使われている変数や関数を解析するパーサみたいなものが作りたいのですが、 こういうのって一行まるごと読んで正規表現で抜き出したりって方法でいいんでしょうか。 効率的といいますか、定石みたいなのがあれば教えてください。
247 :
デフォルトの名無しさん :2008/08/15(金) 18:39:40
一行づつで問題が発生しないならそれでいいんじゃね
ひょっとしてCですか?
ドラゴンブックに
yaccとかbisonを使う方向の方が幸せになれそうだが
>>246 プリプロセッサに通した後のファイルを読むようにすると随分と楽になる
>>246 Cのソースコードを正規表現でパースすることは原理的に不可能であることがわかってる。
厳密でなくていいならどうとでも出来るけど、
そんなことを考えるより既存のライブラリやツールで処理した方がてっとりばやい。
ctags とかではいかんのか?
配列のポインタから中身サイズを取得する方法ありますか? sizeof()だとポインタそのもののサイズが取得される
sizeofnakami()
間違ってるかもしれないけど、 呼び出した関数の中とか、現在のスコープにおいてその配列の要素数が わからない場所でsizeofを使ってもそのポインタのサイズしか得られない。 要素数はなんらかの方法で渡さなきゃならない
わたし環境依存それわからなーず
環境依存・・・ それは標準の方法では決してできないことを平然とやってのける魔法の道具 しかし環境が変わると途端に動かなくなる諸刃の剣
if( ! a=Test() ) 代入かつ否定 はこれでおk?
不安ならなんでも括弧つけとけ、損はしない
>>260 ダメ。
代入をカッコで囲んでそれを否定する。
把握
関数へのポインタの配列を動的に確保するにはどうすればいい? int size=10; void(**ppfunc)(void); ppfunc=new void(*)(void)[size]; とかだとコンパイルが通らない。typedefするしかないのかね
>>264 C的に考えても、(void **) の意味がよくわからないのですが。(void *) でだめですか?
266 :
265 :2008/08/16(土) 19:57:42
ごめんなさい。勘違いしていました。
これでコンパイル通ったよ #include <iostream> void func1(); int main() { void (**func)(); func = new (void (*[10])()); func[0] = func1; (func[0])(); } void func1() { std::cout << "func1()" << std::endl; }
>>267 new void(*[10])();が通らなかったので見逃してた。
なるほど、括弧で囲めばいいのか。ありがとう。
読み辛いし、普通にtypedef使おうぜ・・・
知っておくのも損は無いだろう。typedefで省略して良いのは基本を理解していてなぜtypedefが必要なのかを知っている者のみ。
>>270 基本は new T[N] で、この書式に合わせるためには typedef が必要だとわかっている。
typedef を使わない書き方を知る必要は無いよ。
typedefを使わないと理解出来ない馬鹿は去れ。
そりゃtypedefを使わない奴は馬鹿だが関数宣言における他演算子と比べた時の優先順位を理解できない奴も馬鹿だろ
人の事はどうでもいいから自分の恥を知れ。
275 :
デフォルトの名無しさん :2008/08/17(日) 17:37:46
初心者歓迎ってスレタイに書いてあるのに馬鹿は去れとか
ageて言うほど悔しかったかワロスwwwwwwwww
来るものは拒まず、馬鹿は去れ
278 :
275 :2008/08/17(日) 17:39:44
>>276 sageチェック外す癖が付いてたんだよ悪かったな
馬鹿に限って煽りをスルーできないんだよな( ´ー`)y−~~
( ゚Д゚ )y−~~
>>272-280 なんという夏休み。
>>264 今日び配列newなんてやめておいた方が良い。
std::vectorか、boost::arrayあたりを。
それにC++的には関数ポインタより関数オブジェクトを。
typedefがよくわかりません 教えてください 釣りではありません 本当です
どう分からないんだ
>>281 嫌だね。
人にプログラミング上の事まで強制される謂われはないし
int a; //aという変数の宣言 typedef int a; //変数宣言の形にtypedef修飾子をつけるとaという型の宣言になる
typedefのあとに変数宣言の形とか考えたこともなかった そんな分かりにくい説明なんか読むんじゃありません typedef 元の型 新しく宣言する型; これで分からなかったらもうどうしようもない
ちなみにtypedef修飾子は他の修飾子がそうである様に 元の型 typedef 新しく宣言する型; という元の型の後の修飾でも有効
typedefがわからんて…
質問です。C++のクラスのメンバに、自身のクラスのメンバ関数ポインタ、 あるいは他のクラスのメンバ関数ポインタを保持させ、 呼び出すことは可能でしょうか?また、それはどのような方法でしょうか? 次レスに、実験したソースを付けます(インデントは全角スペース)。 プログラムの意図は、 ・自身のメンバ関数ポインタによる自身のメンバ関数の呼び出し ・同じ変数による、他のクラスのメンバ関数ポインタによる他のクラスのメンバ関数の呼び出し の二つです。 多少、形が変わっても構いません。 ご存知の方、よろしくお願いします。
290 :
289 :2008/08/17(日) 20:45:42
#include<stdio.h> class object1{ public: void (object1::*PFunc)(void); void Func1(void); }; class object2:public object1{ public: void Func2(void); }; void object1::Func1(void) { printf("1\n"); } void object2::Func2(void) { printf("2\n"); } int main(void) { object1 *Obj=new object1; Obj->PFunc = &object1::Func1; (Obj->*PFunc)();//error C2065: 'PFunc' : 定義されていない識別子です。 Obj->PFunc = (void (__thiscall object1::* )(void))&object2::Func2; (Obj->*PFunc)(); return 0; }
>>290 何がしたいのかいまいちわかんないけど、(Obj->*Obj->PFunc)();じゃね?
->*が出てくるときはまず設計ミス
293 :
289 :2008/08/17(日) 22:40:10
>>291 動きました。ありがとうございます。
-> と ->* は全く違うんですね…。
>何がしたいのか
まず、あらかじめ別の型で動的確保した領域で、線形リストをクラスで組んでメンバ関数を使おうとしました。
しかし、その場合、仮想関数はなぜか使えませんでした。
仮想関数を呼び出すとコンパイラはエラーを出さないんですが、実行時に停止するんです。
そこで、関数ポインタを入れ替えることにし、このような形になりました。
かなり横着している気はしますが…。
__thiscallとか移植性ないんだからやめろよ
boost::ptr_funでも使ってポリモーフィズムすりゃいいんじゃね?
boost::ptr_vectorだったorz
#include <iostream> void (**(**func)())(); void func3(); void func4(); int main() { void (**(func1()))(); void (**func2)(); func = new (void (**(*[1])())()); func[0] = func1; func2 = func[0](); func2[0](); func2[1]();} void (**(func1()))(){ void (**func)() = new (void (*[2])()); func[0] = func3; func[1] = func4; return func; } void func3(){ std::cout << "func3() " << std::endl; } void func4(){ std::cout << "func4() " << std::endl; }
自分で考えろカス
いやそういう意味ではなくて、何の質問もないのに関数への ポインタとか関数へのポインタを返す関数へのポインタとかの ソースをいきなり貼られてるのは何の意味があるのかと思って。
それなら「ない」
void (**(func1()))(); こんな関数のプロトタイプ宣言初めてみたぞ。 まあ書けばいくらでも複雑に書けるんだろうけど、 デザパタの生成パターンでもこんな書き方はしないし。
何故括弧を一つ増やしたし
c/c++で開発経験者にお聞きしたいのですが、 コボルみたいにコードインスペクションは現場でやりますか また、ソースを読み上げたりハードコピーにマーカーでチェック、机上チェックなんかも やったりしますか?
306 :
デフォルトの名無しさん :2008/08/19(火) 07:33:51
BSD socketでsendしてerrno:9が帰る場合考えられる原因ってなんなんでしょうか。 char *c; strcpy(c,str); printf("Sending:%s¥n",c); int checker=send(socketID, c, strlen(c), 0); if(checker == -1){ NSLog([NSString stringWithFormat:@"Send Error:%d",errno]); return 2; } return 0;
307 :
306 :2008/08/19(火) 07:37:57
Obj-CのNSLog();使ってエラー表示させてるけどそこは気にしない方向でお願いします。 NSLog([NSString stringWithFormat:@"Send Error:%d",errno]); は printf("Send Error:%d¥n",errno); とほぼ同じです。
>>306 #define EBADF 9 /* Bad file number */
ならsocketIDが無効
socket( )の戻り値は確認してる?
>>306 数値の意味がわからないなら文字列にすれば
NSLog([NSString stringWithFormat:@"Send Error:%s", strerror(errno)]);
310 :
306 :2008/08/19(火) 08:15:49
>>308 ありがとうございます。
socket()の戻り値は確認していて、connect()及びrecv()は問題なく行えています。
socketIDがガベージコレクションで解放されちゃったのかもしれないのでその辺りで探ってみます。
>>309 文字列にできたんですか。ありがとうございます。
関係ないけど7bit asciiのみなら NSLog(@"format",...); って書けた気がする。
>>305 プロジェクトの性質によって色々だとは思うが、
絶対ないと断言できるのは「読み上げ」だな。
やれるもんならやってみろ。
>>305 >ソースを読み上げたりハードコピーにマーカーでチェック、机上チェック
そんなアナクロなこと、COBOLでだってやりませんよ。
>>305 俺は「コードレビュー」はやったことはある
紙の無駄だけどプリントアウトしたソース使って
ただ、(若手の)教育と(協力会社さんなどの)スキル把握(もちろん
悪いところは直してもらう)が主な目的だったんで、約束事として
つねにやってたわけじゃない
hppファイルにクラス、クラスの内部にメンバ関数の宣言を記述し、 同名のcppファイルでそのhppファイルをインクルードし、cppファイルにメンバ関数の 定義を記述したのですが、コンパイルしようとすると、cppファイルのメンバ関数定義に ついて未解決の外部シンボルとなってしまいます。 WinMain関数の記述されているファイルにhppファイルだけでなく、直接 cppファイルをインクルードすると、コンパイルが通ります。 未解決の外部シンボル となってしまう原因は何なのでしょうか? 環境はVisual Studio2005です。
main.cpp sub.hpp sub.cpp があるとして cl main.cpp sub,cpp とやるか cl /c sub.cpp cl main.cpp sub.obj
ヘッダファイルにあるクラスの定義がおかしいんじゃないの?
>316 ありがとうございます。コマンドラインから個別にコンパイルしてやるか、 同時に指定してやるかということですね。 もしかして、こういった構成だと、統合開発環境からはコンパイルできないのでしょうか… >317 クラス、及びメンバ関数の宣言とメンバ関数の定義を両方ともhppファイルに 記述した状態だと動作していたので、それはないとは思うのですが…
cppファイルにあるメンバ関数の定義がおかしいと思う
戻り値の型 クラス名::メンバ関数名(引数) int HOGE::hogehoge(void) { }
>もしかして、こういった構成だと、統合開発環境からはコンパイルできないのでしょうか… それはないw 何のための統合開発環境なんだかわからなくなるって
>319,>320,>321 すみません、原因がわかりました。 大騒ぎしといてわざわざレスまで頂いて、本当に申し訳ありませんでした。 テンプレートだから、っぽいです。
エスパー力が足りなかったようだ、修行してくる
export templateか・・・・全部ヘッダに書けよ それかComeau C++を使うか
>324 そういうのもあるのですね でもヘッダに書かないとダメならダメでも良いんです。 広く外部に公開するものでもありませんので…
326 :
305 :2008/08/20(水) 23:50:09
回答していただいたみなさん、ありがとうございました
作ったexeファイルをメモ帳で開いたら「"」で括って書いた部分がそのまま見えちゃう んだけどこれ見えないようにできますか?
328 :
デフォルトの名無しさん :2008/08/21(木) 11:35:35
>>327 ソースに書き込んでいるものは見えちゃってもしょうがないよね
暗号化するとかしかないんじゃない?
ソースで見える文字列は見えちゃうと思った方がいい
>>328 ありがとう。簡単にどうこうできるものじゃないのね
諦めます
簡単な方法としてはEXEをUPXみたいなパッカーで圧縮するとか
331 :
デフォルトの名無しさん :2008/08/21(木) 15:00:03
Win32アプリケーションでLoadLibrary()使って開いたハンドルをWM_DESTROYのときにFreeLibrary()したら、DispatchMessage()で例外が発生したんだが何が原因だろうか
平面状の2点間の距離を求めたいのですが、三平方の定理を利用(xyの差を二乗して云々…)する 以外に、C++的にもっと良い方法はありますか?それとも上記の方法が無難でしょうか?
>>332 C++的に?
こういうのは言語の問題ではない。数学の問題だ。
最良のアルゴリズムを導いて、それを言語で表すだけ。
>>333 何か自分の知らない役立つ関数があるかもしれない…と思い質問しました。
三平方の定理の方法でも特に問題ないので、そっちを使いたいと思います
ありがとうございました。
>>335 ありがとうございます。今回の目的以外にもかなり便利なライブラリが
あるようですね。勉強になります。
>336
ずばりな回答ですね。ありがとうございます!
こういった形で公開されていると、非常に参考になります
336のソース見たけどmoler-morrison法って計算量多いからなんか遅そうなんだけど math.h にhypot()があるお 試しにコンパイルしてみたらやっぱり遅かったお(g++ 4.1, 1.6GHz) register 着けたけど、sqrt()呼び出しが最速だったお ライブラリは、汗で(ry
>>331 DLLが作成したウィンドウがまだ残ってるのにFreeLibrary()して
DispatchMessage()が既に開放されたDLLのウィンドウプロシージャを呼ぼうとして落ちた。
>>338 平方根ぐらいはFPUが1サイクルで計算できるから
下手に四則演算にばらさないほうがいいってことだろう。
>>338 6回も割り算してるからな。そりゃsqrtのほうが速いわ
普通にhypot()を使えばいいだけじゃん。iccのhypot()は速いぞ。
まあ、hypotはC99からやし
boost::math::hypot
345 :
338 :2008/08/22(金) 02:40:24
>>344 boostの実装ぱくったら爆速だったお、やほお。最適化(-O2)したけどね。
実際にあのアルゴリズムで解が出るとは、驚きだおおおお。
標準C++的には_hypot?
特定の条件でのみJaneのlast.datをlast2.datにコピーしたいのですが 「特定の条件」の判定は問題無くできたけど、肝心のファイルコピーが出来ません void copy_last()のkekkaかkekkaAが毎回0で失敗しています CopyFileは BOOL CopyFile( LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, BOOL bFailIfExists ); なので、ファイル名をLPCTSTRで LPCTSTR moto=_T("last.dat"); LPCTSTR saki=_T("last2.dat"); int kekka=CopyFile(moto,saki,false); こんな感じにしてるのですがダメでした LPCTSTR moto="last.dat"; LPCTSTR saki="last2.dat"; でも同じでした どのようにファイル名を指定すればコピー出来るのでしょうか? 環境はBCC Developer+Vista SP1+Borland C++builder 5.0 です
>>347 Vistaか
書き込み権限の関係?
とりあえず
DWORD GetLastError(void);
でエラーの原因を絞れ
カレントパスが思っているのと違うところにあるから上手くいかなくて、 絶対パスで指定すればいいなんてことはない?
>>348 GetLastError、そういうのもあるのか!
32でした
ファイルサイズ取得する時に開いたハンドルが原因でした
CloseHandleで無事コピー出来ました
ありがとうございます
>>336 そのコードに
x = x ? x : -x; // x = fabs(x); と同じ結果だが高速な方法。
って行があるんだけど、おかしくね?
-xになるのはx==0の時だけで、fabs(x)と同じになんてならないよね?
>>351 ほんとうは分かってかってるだろwww
x >= x ? x : -x;
の間違いだってw
x = x >= 0 ? x : -x; だろJK
おしいw
馬鹿ばっかw
浮動小数点数の絶対値なんて大抵、符号ビットを取り払うだけで済むわけで、 環境に合わせて最適化してるfabsのほうが速いと思うんだが、2002年の記事だからそんなものなのか?
357 :
351 :2008/08/22(金) 14:23:02
あぁそうか。(いや、素だったよw>352) しかし単純ミスにしては・・・。「負は偽」と誤解してそう。
符号ビットを取り払……う?
359 :
デフォルトの名無しさん :2008/08/22(金) 16:12:14
構造体のメンバで、stringstream型のメンバ変数だよって分かりやすくするように struct sample { std::stringstream m_ssData; } みたいな記法を考えているんですが、変でしょうか?? mとかいらないですかね?? なにかセオリーのようなものがあったら教えていただきたく。
360 :
359 :2008/08/22(金) 16:15:48
DataのDが大文字なのも変かも・・?と思ったり・・
>>358 ん?何か間違ったこと言ったか?
世の中で使われてる浮動小数点形式は、符号ビットを0にするという
比較的簡単な操作だけで絶対値が求まるようにできている。
それに対して、浮動小数点数が0より大きいかどうかを判断するには、
符号ビットを見ただけでは十分ではなく、値全体を眺めてNaNでないことを
確かめないといけないので、より時間がかかる。
だから、0と比較→符号反転は明らかに無駄。
363 :
359 :2008/08/22(金) 16:21:05
おお、そんなスレが。そっち行って見ます。ありがとうございますm(_ _)m
自前で x &= 0x7FFFFFFF みたいなことはできないのですか?
366 :
デフォルトの名無しさん :2008/08/22(金) 18:17:54
ある値が16進数で表されている文字列があって、(LPSTR str = "0x2345e23";こんな これからその値を取り出してintでもlongにでも入れたいんだが。。 どうすればいいかわからんからキミたち教えて
368 :
デフォルトの名無しさん :2008/08/22(金) 18:29:22
>>367 素早い応答感謝。
おとなしくstrtol使ってくる。
strtolって16進表記も使えたっけ?
おいおい
ナイスボケ
>>361 浮動小数点の形式がIEEEなのかはたまた別なのかは定義されていないから環境依存が激しくなると思われ。
といいつつ大概は先頭ビットを0にする処理で終わらせてるが。
つまり素直にfabs使っとけってこったな
>>372 いやいや、そうじゃなくて、CPU内部ではフラグ倒すだけの操作だってことを言いたかった。
ビット操作で符号フラグをクリアしろという意味じゃない。
>>356 で「環境に合わせて最適化してる」と書いたとおりです。
変な質問ですが、下のプログラムは最適化をかけた時に展開されますか? template <unsigned int N> inline double pow(double v){ return v * pow<N-1>(v); } template <> inline double pow<0>(double v){ return 1; } 使用例:pow<4>(3) コンパイル後:3*3*3*3 ? コンパイラはbcc使ってます。デバッグモードじゃ展開されないみたいだし、 リリースモードだと、アセンブラが分かりません;〜; よろしくお願いします。
まともなコンパイラなら展開されると期待していいと思う。 問題はbccがまともかどうかということだが……。
>>375 gccの例で恐縮だが、printf("%g\n", pow<4>(3))したらprintf("%g\n", 81.)相当に展開された。
つーか、展開されないってどんだけよ。 試しにpow<4>(argc)したらこんなことになったけど。 -- cvtsi2sd 8(%ebp), %xmm1 movapd %xmm1, %xmm0 mulsd %xmm1, %xmm0 mulsd %xmm1, %xmm0 mulsd %xmm1, %xmm0 movsd %xmm0, 4(%esp) -- # アセンブラ読めなくても掛け算3回連続ってのは判るでしょ。
>>378 定数畳込みがされるかどうか聞きたかったんじゃ。
>>376-378 ありがとうございます。展開されると期待します。
ところでもう一つ質問なのですが、
template<unsigned int n,unsigned int i>
struct h{
static inline double hill1(double t,double p[n]){
return p[i]*t + h<n,i-1>::hill1(t,p);
}
};
template<unsigned int n>
struct h<n,0>{
static inline double hill1(double t,double p[n]){
return p[0];
}
};
このテンプレートでh<1,0>::hill1(0,hoge);とした時に下のテンプレートが適用されないみたいなんですが
原因がよく分かりません。エラー文は
最大 VIRDEF 数を超過した; 再帰をチェック
と出ています。また、よろしくお願いします。
BCCだと知らないけど、インライン展開のネストの許可数を設定する プラグマか何かあるんじゃないかな。上限ぐらい上げられると思うけど。 VCの#pragma inline_depthみたいな
>>381 すいません。問題はそこじゃなくてテンプレートの部分特殊化がうまくいってないっぽいというところなんですが
383 :
デフォルトの名無しさん :2008/08/23(土) 00:15:22
C言語ド素人です。この問題を解いていただきたいです・・・。 1. 次のような式で表される数列が与えられたとする。 a0=1,a1=1,an=an-1+2an-2 int型の整数n(n≧0)を受け取り、上記の数列anの値をa0からanまで全て表示する関数printa(n)を作成せよ。 2. 要素数2個のdouble型の配列xy(xy[0]にはx座標、xy[1]にはy座標が納められている)と2行2列のdouble型の2次元配列Aを受け取り、座標(x,y)のAによる1次変換を求めて、その結果を配列xyに格納する返却値無しの関数LinearTrance(xy,A)を作成せよ。 3. 文字列の納められた文字型の配列sとstailを受け取り、sの末尾にstailの文字列が含まれているかどうかを調べ、含まれている場合には1、含まれていない場合には0を返す関数strcmptail(s,stail)を作成せよ。 4. 4個の文字列"abc.txt","xyz.jpg","foo.txt","bar.mp3"と文字列"txt"を受け取り、文字列の末尾に"txt"を含む文字列かあるかどうかを調べて、あればその文字列全てを表示するプログラムを作成せよ。ただし問3で作成した関数を用いること。 見づらいかもですが、よろしくお願いします。
世の中には宿題スレというものがあってだな、…。 宿題程度は自分でやれといいたいが。
>>380 BCCが関数テンプレートの部分特殊化に対応してるか怪しいような。
対応してても、ぐぐったらちょっとバグがあるらしいので
標準に完全準拠してると期待しない方がいい。
インライン展開で無限ループしてるんじゃない?下の特殊化版を消してコンパイル結果が
同じならそういうことかと。
386 :
デフォルトの名無しさん :2008/08/23(土) 00:29:16
gccにおいて、特定のヘッダファイルに関してだけ警告が出ないようにするというか 特定ファイルだけ警告出さないようにするというのはできますか? それというのも少し環境が変わって以前使っていた警告オプションだとSTLに対して大量の警告がでるようになってしまい、 これを何とかしたいんです
gccではそういうのありまえん
>>385 どうやらそのようです・・・ありがとうございました。
これをクリアするのは至難の業ですね・・・Umm
簡単だよ。bccを捨てればいい。
>>380 BCC5.9.3(C++Builder2007の付属品)だとちゃんと動くよ。
>>390-391 そうですね。てゆうかよく考えたら、今やってることが必要ないことに気づきました。
template<unsigned int i>
struct f{
template<unsigned int n>
static inline double hill(double t,double p[n]){
return p[i] * Bernstein<n,i>(t) + f<i>::hill<n>(t,p);
}
};
template<>
struct f<0>{
template<unsigned int n>
static inline double hill(double t,double p[n]){
return p[0] * Bernstein<n,0>(t);
}
};
main:
こうしたら一見コンパイルは通るんですが
Shift+Enter押しちゃった・・・ 続きですが、上のやつだと f<2>::hill<1> が関数として見られないらしく関数ポインタに代入しようとすると”式の構文エラー”と出てしまいます。 これも不正あるいはBCCの未対応によるものなんでしょうか
>>388 そうですか
どうもありがとうございました
なんとかならないのかなぁ
半年前くらいから、独学でCとC++をやってるんですが、 普通どのくらいファイルを分割するものでしょうか? 1プロジェクトのソースの総サイズが160KBで、 ヘッダを含めて110ファイルになったんですが、 これって分割しすぎですか?
>>396 1ファイルの平均が1.5Kか。
こういうのに正解はないから好きにすればいいとは思うけど、普通よりだいぶ細かく分割してるのは違いないな。
やっぱり細かいですか。 どうもありがとうございます。
>>396 私は1クラス2ファイル(hとcpp)を目安に分けてる
構造体なんかは関連するクラスにまとめちゃうことが多いな
110ファイルもあると、それ自体のディレクトリを分割整理したくなるな。
ヘッダを細かく分けると、幾つかのヘッダを纏めたヘッダとかも 作ることになるからさらに増えるからなぁ
自分の場合は 一つの処理を行う過程で複数の関数にまたがるような処理 汎用的に使えそうな関数を書く場合 こういうソースを分けてるなぁ
403 :
デフォルトの名無しさん :2008/08/24(日) 11:56:29
以下のようなクラスで、Subのオブジェクトをdeleteすると、 Superのデストラクタで「純粋仮想関数を呼んだ」っていうランタイムエラーが出ます。 SuperのデストラクタでSubの release()を呼びたいんですが、どうすればいいでしょうか? template <class T> class Super{ public: virtual ~Super(){ static_cast<T*>(this)->release();//ここでランタイムエラー } virtual void release() = 0; }; class Sub{ public: void release(){} }; 環境はVisualStudio2003のVC++です。
404 :
デフォルトの名無しさん :2008/08/24(日) 11:58:21
すいません間違えました。Subはこうでした。 class Sub : public Super<Sub>{ public: void release(){} };
class Sub : public Super<Sub>{ public: void release(){} ~Sub(){} };
C++では、Superのデストラクタが呼ばれるときには、 もうSubオブジェクトは無くなっていると考える。 Subにデストラクタは設けられないの?
>>406 おっしゃるとおり、Subのデストラクタでrelease()を呼び出すようにしました。
全子クラスのデストラクタでrelease()を実行するので、親のデストラクタで呼び出したかったんですが。
どういう仕様か知らんが、release
どういう仕様か知らんが、releaseで行うべき処理をデストラクタですればいいんじゃないの?
410 :
407 :2008/08/24(日) 13:21:08
子クラスによって解放するモノが違うので、 親クラスに解放処理の中身はかけないのです。
子クラスのデストラクタに書けよ
もしSuperにデストラクタでreleaseを呼ぶこと以外の目的がないなら、 継承しなくても包含でいいんじゃないかという気もする。
やりたい事情は分かるけど無理。 継承をテンプレートに変えればできるかも。
414 :
デフォルトの名無しさん :2008/08/24(日) 15:07:23
Visual C++ や Borland C++ 等の一部の開発環境で __int8、__int16、__int32、__int64 のような、サイズが定まった整数型が存在します 自分は .NET のようにサイズが定まってる方が好きですし 型名にサイズが記されてて分かり易いので使っていこうかなと思っています (long long int みたいな名称はちょっと微妙な感じ・・・) が、これらの型についてググっても意外に使用しているコードが少ないです 非標準だからでしょうか? これらの型のメリット、デメリットってどんなのがあるんでしょうか? やっぱり、あんまり使わない方がいいんでしょうか? よろしくお願いします
サイズにこだわる必要のない場面も多いだろうし strlenとかのライブラリ関数はそんな型使ってないから整合性に困るし 非標準ってのもあるかもしれないが、それだけならC99標準に合わせて int8_t int16_t int32_t int64_t に typedef して使うのがいいんじゃないかな
>>415 ありがとうございます
元はといえば long long int という型名が嫌だったので別名を探してました
VS2008 で動かしてみたら C99 の int32_t って対応してないみたいですね
ググっても Linux関連が大量に出てきた・・・
VC++ では
typedef で INT8、INT16、INT32、INT64 というのがあったので
コイツらを使っていこうと思います
ありがとうございました
418 :
デフォルトの名無しさん :2008/08/24(日) 20:22:23
#include <iostream> #include <algorithm> #include <set> #include <functional> int main() { char ch[] = { 'N', 'B', 'J', 'K', 'E', 'C', 'G', 'D', 'A', 'C', 'F', 'I', 'L', 'M', 'L', 'B', 'G', 'H' }; int size = sizeof(ch); std::set<char, std::greater<char> > s2(std::greater<char>() ); for (int i = 0; i < size; ++i) { if (!s2.insert(ch[i] ).second) { // 15 行目 std::cout << "失敗\n"; } } } これをビルドしようとすると、エラーになります。何がダメなのでしょうか? (15) : error C2228: '.insert' の左側はクラス、構造体、共用体でなければなりません (15) : error C2228: '.second' の左側はクラス、構造体、共用体でなければなりません visual studio 2005 standardをつかってます
関数宣言と解釈されちゃってんじゃね
× std::set<char, std::greater<char> > s2(std::greater<char>() ); ○ std::set<char, std::greater<char> > s2; キモイ std::set<char, std::greater<char> > s2((std::greater<char>()));
>>419 なるほど
std::set<char, std::greater<char> > s2(std::greater<char>() );
の部分を std::set<char, std::greater<char> > を返す
s2という関数の宣言と解釈されたということですね
>>420 どちらでもうまくいきました。ありがとう
C++標準ライブラリの使い方 完全ガイド では
>>418 の様に書かれてるんだけどな・・・
422 :
デフォルトの名無しさん :2008/08/24(日) 21:07:50
レッドストーンでチートしたいんですが バイナリエディタにつっこんだ後、機械語が横の方にでるんだけど、日本語に翻訳するにはどうすればいいか教えてください
>>422 このスレはC/C++の質問だけにしてください
Winpcapの制御でpcap_next_exを使ってパケットを取る時 大量のパケットが流れている状態だとリアルタイムに取ることができません (秒間60パケット程度になると1秒間の分を1.5秒くらいかけて取り込む結果に・・・) 最適化などで高速化を頑張ってみましたが一向に改善されません ループ処理を軽くすれば解決できるような問題なんでしょうか
>>424 データ量がどれだけか分からないけど
ギガビットイーサで400Mbps(=50MB)の受信があったとすると
かなりの負荷になるな
でもジャンボフレーム16kとして60パケットなら100kB程度
余裕で処理できそうな気はする
>>425 具体的なデータ量は120バイト前後のバラバラのパケットが秒間58個+α流れてくる状態です
これしきのことでどうして酷いタイムラグが起きるのか悩んでます
>>425 計算違うw
16kBx60=1MB程度になる
>>420 うはw
std::set<char, std::greater<char> > s2((std::greater<char>()));
って書くとBCCではコンパイルエラーになるわ
>>426 ブロッキングモードで読んでるのが原因とか?
>>429 Winsock2ではブロッキングモードがあるのは知っているのですが
Winpcapを使った場合でも同様のものがあるんでしょうか
取得までのタイムアウト値を設定できるとのことなので
ぎりぎり動く範囲の2msに今は設定しています
さすがにそれはネットワークプログラミングスレで聞こうや C/C++と関係なさすぎ
すいません、C++で動かしてたのでついここで良かったかと・・・ 友人が英語サイトから有用そうな情報を引っ張ってきてくれたので もう暫く頑張ってみようと思います ありがとうございました
C++の勉強にソースを読みたいんだけど、 いいオープンソースありまっか?
>>433 SourceForge へいってみればあると思うよ
newで生成した配列をreinterpret_castした物のdeleteてどうするんですか? 例: int *pint = reinterpret_cast< int * >( new char[sizeof(int)] ); delete pint; <-これで正しいんですか?
>>435 delete [] reinterpret_cast<char*>(pint);
っていうか最初の reinterpret_cast が要らんような気がするんだが。
new int じゃダメなのか?
>>435 そういうやばいことやるようなケースならmalloc/free使ったほうが明示的で良い気はする
STL の map についての質問です #include<string> #include<map> class hoge{ private: std::string m_name; public: hoge(std::string name) : m_name(name){} }; std::map<int, hoge> hogelist; このとき hogelist に新しいメンバを追加する際 hoge のコンストラクタに引数を指定する方法を教えてください 当然ながら hogelist[1]("hogehoge"); はダメでした
>>438 #include <utility>
hogelist.insert(std::make_pair(1, "hogehoge"));
440 :
438 :2008/08/25(月) 12:05:58
>>439 ありがとうございます
助かりました
今は必要ないのですが、
>>438 と同様の状況で
コンストラクタに複数の引数を渡したい場合の書き方について
ご存知であれば教えてください
>>440 hogelist.insert(std::make_pair(1, hoge("hogehoge", ...)));
442 :
438 :2008/08/25(月) 12:16:01
>>441 なるほど、コピーコンストラクタを使うのですか
勉強になります
443 :
デフォルトの名無しさん :2008/08/25(月) 13:14:14
virtaulなデストラクタを持たないクラスを継承して多態を表したいときどうすればいいですか? Aがデストラクタを持たない親クラスで、 Bがテンプレートを持つクラスで、それを継承したC、D、Eで多態を表したいです。 Bのテンプレート引数には子クラス(C、D、E)を渡さないといけない状況です。 具体的には、ATLのCWindowを継承しているCWindowImplを継承して自分用のclassを作ったんですが、 mapに入れて管理しておいて、参照しているところがなくなったら削除しようと、shared_ptr<CWindow>で入れてみたんですが、 CWindowにvirtaulなデストラクタがなくてshared_ptrでdeleteしようとすると未定義な動作になるようです。
>virtaulなデストラクタを持たないクラスを継承して多態を表したいときどうすればいいですか? 諦める。
間にもう一つかませればいいんじゃない?
>>443 CWindowを継承しないとだめなの?
CWindowImplのprivateメンバに直接アクセスするわけじゃなければ、
CWindow*のメンバ変数を所有するクラスを作って、
場合によりそれを継承するとかじゃ無理?
class Foo { virtual ~Foo(){} virtual CWindow *GetCWindow() = 0; }; のようなクラスを作り、自分用のクラスに多重継承させ、 shared_ptr<CWindow> の代わりに shared_ptr<Foo> を使う
>>443 いやいや、shared_ptrなら仮想デストラクタを持っていなくても、
正しくデストラクタが呼ばれるから問題ない。
shared_ptr<> p(new MyWindow);というように最派生クラスの型へのポインタを
直接shared_ptrのコンストラクタに渡せば平気。
このときのshared_ptrのテンプレート引数はMyWindowでもATL::CWindowでも果てはvoidでも大丈夫。
仕組みが知りたければここ読め。
http://d.hatena.ne.jp/Cryolite/20060108
>>448 おぉ、それは知らなかった。
こういう利便性があるとsharedじゃない単なるポインタ版も欲しくなるね。
450 :
443 :2008/08/25(月) 14:38:11
レスありがとうございます。
>>444 できればなにか回避する方向でいきたいと。
>>445 , 447
間にあるクラス(B)がテンプレートクラスなのでかまさせられないのです。
一番下の子クラス(C)でテンプレート引数として自分を指定するので。
>>446 ATLのCWindowを継承したいのが目的なので、コンポジションではだめなのです。
すべてのメソッドにラッパーメソッドをかますとなると、結構大変そうというのが理由です。
>>448 なるほど、boostのshared_ptrなら、大丈夫だとは。
自分が代入された時の型を覚えておくなんてすばらしいですね。
これを元にして解決してみます。ありがとうございました。
結論としては、virtaulなデストラクタを持たないクラスを継承して多態を表したいときは、
生成した型に合わせてdeleteすればよいということですね。
ありがとうございました。
もちろん、TR1のshared_ptrでも平気だよ。
452 :
443 :2008/08/25(月) 15:04:03
POCOのSharedPtrではだめでした。そういう実装になってなかったです。 boostを参考にしてみます。ありがとうございます。
>>449 C++0xのunique_ptrは参照カウントないんでそういう感じに近いと思う。
virtaulってタイプミスかと思ってたらずっとそう書いてるな
virtaul の検索結果 約 57,500 件中 1 - 10 件目 (0.25 秒) もしかして: virtual
ループ{ Aの処理 Bの処理(しばらく処理が戻ってこない命令含む) } ↑のようなのがあって Aの処理はできるだけガンガン回したいのにBが邪魔なんだ そこでマルチスレッドでAとBを分割してやれば Bの制御が戻ってこない間もAをブンブン回せる?
>>456 ループ1{
ループ2{
Aの処理
}
Bの処理(しばらく処理が戻ってこない命令含む)
}
>>457 ありがとうございます
でもそれをやるとAを何回かまわしてBをやった時
またAに戻るまでにタイムラグができてしまわない?
#include <new> int global_area[1000]; int main(){ int* arr = new(global_area) int[10]; for(int cnt=0;cnt<10;++cnt){ arr[cnt] = 1; } return 0; } 上記のソースはplacement newで領域を確保しようとしています。 コンパイルすると、 'operator new[](unsigned int,int *)' に一致するものが見つからない と表示されてしまいます。new演算子のオーバーロードが必要ということでしょうか? もしそうだとすると、この場合、どこにそれを記述すればよいのでしょうか? コンパイラはBCC++5.5です。
>>459 gcc3.4.5(MinGW)だけどエラー出ないぞ。
>>458 AとBが同じリソース(ファイルとかVRAMとかメモリ)の書き換えを行うようなことをしてなければ、
そのままマルチスレッドでも良いと思うよ。
>>458 どうせ馬鹿なんだから、最初から小出しにしないで用件全て晒せよ。
ありがとうございます ちょっと敷居が高いですが頑張ってみます スレッドが回ってる時にCloseHandleってやってしまうとまずいですか?
>460 ありがとうございます。 そうですか…何故かうちの環境だとエラーとなるのです。 条件変えて試してみます
>>436-437 どうも、ぺこり
実プログラムでは下のようにmalloc/freeで行っているのですが、
それをnew/deleteで行った場合の開放の仕方がわからず質問しました
PSP_INTERFACE_DEVICE_DETAIL_DATA functionClassDeviceData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(predictedLength);
free(functionClassDeviceData);
またおまえか
std::vector<char> buf(predictedLength); PSP_INTERFACE_DEVICE_DETAIL_DATA functionClassDeviceData = PSP_INTERFACE_DEVICE_DETAIL_DATA( &buf[0] ); とかでいいんじゃないもう
デストラクタは、 「オブジェクトが解体される直前に呼び出され、内部で指定された処理を実行する」 以外に、自動的に(ユーザーの見えないところで)何か処理を行っているのでしょうか?
自動的に、メンバ変数のデストラクタを呼び、 仮想関数テーブルを基本クラスのものに戻して、 基本クラスのデストラクタを呼ぶ
placement newと混同すんなよw
473 :
デフォルトの名無しさん :2008/08/26(火) 14:19:27
>>448 の方法での実装をみるとvoid*を経由しているようです
void*を経由した場合、以下の継承関係だとエラーになるんですが、どうやったら回避できますか?
型情報がいったんなくなるので多重継承の場合は無理なのかなぁと思っています。
(shared_ptrのソースはむつかしくて読めてません)
class AAA {};
class BBB {
public:
virtual BOOL x() = 0;
};
class FFF : public AAA, public BBB {
public:
BOOL x() {return 0;}
};
FFF* fff = new FFF();
AAA* aaa = fff;
void* vvv = aaa;
FFF* buf = static_cast<FFF*>(vvv);
delete buf;
>>473 そのAAA*→void*→FFF*って変換が一般にできるは分からない。
けど、BoostとVC++9の実装を見てみたが、delete自体は問題ない。
どっちもshared_ptr用とは別にdelete用のポインタを保持していて、
それはずっとFFF*だったりFFF*→void*→FFF*だったりする。
new の時点で元の型情報保持するためにshared_ptrに 渡してdeleterを作成させなきゃダメでしょ。
476 :
デフォルトの名無しさん :2008/08/26(火) 15:36:04
>>474 void*を経由した時に多重継承だとオフセットわかんなくなりませんか?
>>473 のコードだけでも落ちたのでそうなるかなと。
>>475 生成時に渡しててもvoid*経由してたら落ちると思います。
>>448 のコードでも多重継承のやつをdynamic_scoped_ptr<AAA> buf(new FFF());で落ちます。
>>476 X*からvoid*へ変換してまたX*へ戻すっていう風に、void*にする前と後で同じ型の場合なら、
void*にする前と後でビットパターンが変化しなければうまくいく。
あと、dynamic_scoped_ptrじゃなくて、boost::shared_ptrで試してみ。
dynamic_scoped_ptrほど単純な仕組みではないからうまくいくはず。
478 :
Mr.yutori :2008/08/26(火) 15:53:11
swich文を簡単に、 教えてください。
#include <iostream> #include <cstring> template <typename TYPE> // TYPE max(const TYPE& a, const TYPE& b) // なんかこっちだどだめ ***** TYPE max(TYPE a, TYPE b) { return (a > b) ? a : b; } template <> inline char *max(char *a, char *b) { std::cout << "char *" << std::endl; return (strcmp(a, b) > 0) ? a : b; } int main() { char *s = "fdada"; char *p = "fff"; std::cout << max(s, p) << std::endl; return 0; } コメントアウトした方がダメなのはなぜですか?
特殊化の方 char *max(char* const& a, char* const& b) にしないとテンプレートと合わないんじゃないか?
>>477 shared_ptrのソースの読めた部分だけで、shared_ptrのまねをして
>>448 のdeleterにポインタ渡すようにしてvoid*を経由しないようにしたらできました。
レスくれたかた、ありがとう。
>>481 確か<utility>にstd::maxが入ってるからそれとぶつかるんでは?
なんとか総合研究会って所で C++に使える最強のクラスをまとめたヘッダーファイルが3万で売ってると聞いたのですが 詳細が書いてあるサイトご存じありませんか?
RogueWaveから何か売ってたな
>>481 TYPEをそのままchar *に置き換えてみれば違いがわかるんじゃない?
>>483 Boost使っちゃだめだった?
それなら、shared_ptr.hppをコピーして名前だけ変えたほうが手っ取り早いと思うけど。
あるいはVC++2008なら、SP1あてればshared_ptrも付いてくるし。
>>488 勉強のために理解したかったので今後、何かするときはboost::shared_ptrを使おうと思います。
今まで継承するクラスは仮想デストラクタがないといけないという思い違いをしていましたので、
目から鱗がぼろぼろでした。ありがとう。
#include宣言を、例えばファイル上部ではなくあるクラスAの宣言の下に、クラスAを 基底クラスとする派生クラスB,C,D...と#include していくのは行儀の悪い方法ですか?
行儀が悪いです
>491 レスありがとうございます。 別の方法を探ります
#define ERROR_EXIT() { int line = __LINE__; const char *file = __FILE__;\ __LINE__ とかの__の部分の意味 について解説してるサイトご存じないですか? これについて理解できなくて・・・・。
特に意味はない。
>>493 ただのマクロです行数に置き換えてくれます
意味とかいわれてもわかりません
>>489 全部が全部shared_ptr使うわけでもないだろうし、
スーパークラスとなる可能性があるクラスは、
仮想デストラクタを作っといたほうが行儀はいいと思うよ、一応
>>482 お答えいただいていただきありがとうございます
つまり全部参照にするか、全部値渡しにするかどっちかじゃないとだめだということ・・・?
特殊化って何か分かってるの?
>>500 指定した型のときだけ違う動作させるものじゃないんですか?
>>501 そうそう。
だから、TYPE max(const TYPE& a, const TYPE& b)を特殊化したものも、
またTYPE max(const TYPE& a, const TYPE& b)のシグネチャに一致しないといけないということ。
クラステンプレートならまた話は別だけど。
>>502 ありがとうございます
TYPE max(const TYPE& a, const TYPE& b)の特殊化であってこれに沿っていないといけないのですね
関数のオーバーロードみたいなものでなんでもいいのかと思っていました
どうもありがとうございました
ちなみに、特殊化ではなく、単なる多重定義としてこの2つは共存できるよ。 template <typename TYPE> TYPE max(const TYPE& a, const TYPE& b); char *max(char *a, char *b); あと、誰もつっこんでいないけど、<cstring>ならstd::strcmpだ。
メモリの解放について聞きたいのですが #define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } } これについて解説していただけませんか よろしくお願いします・・・。 SAFE_DELETE(p)の意味がわかりません・・・
if いらんけど、delete後、確実にポインタをNULLにしたいんだろ? なにを解説したらいいの?#defineの動作?
自己解脱しました ありがとうございました
俺も解脱したい
509 :
デフォルトの名無しさん :2008/08/27(水) 14:06:14
自己解脱www 最終解脱まだ??
例えば #define DIGIT 30 だとすると文にDIGITを置くと30と同じじゃないですか その文だと #define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } } になってて そのあと(p)が何度も出てくるんですけどSAFE_DELETEが見当たらないのでどういう意味なのか疑問に思いました
511 :
デフォルトの名無しさん :2008/08/27(水) 14:09:59
| ゝノ __|_______|_ ■■■■■■■■ |iiiiiiiiiiiiiiiii| ■■■■■■■■■ナニヤッテンダヨ!バカモノガァ! |iiiiiiiiiiiiiiiii| ■■■■√ === │ |iiiiiiiiiiiiiiiii|■■■■√ ~ ミ ノノノ 彡 | |iiiiiiiiiiiiiiii|■■■√ ∀ ∀ \ |iiiiiiiiiiiiiiii|■■■ ∵ (● ●) ∴│ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ |iiiiiiiiiiiiiiii|■■■ 丿■■■( │< 常にageとけって |iiiiiiiiiiiiiiii|■■■ ■ д ■ | | 言ったじゃないかぁ! |iiiiiiiiiiiiiiii|■■■■ ■■ ■■ ■ \_________ |iiiiiiiiiiiiiiiiii■■■■■■■■■■■■__ \iiiiiiiiiiiiiii■■■■■■■■■■■■iiヽ \iiiiiiiiiiiii■■■■■■■■■■■iiiiiii| |iiiiiiiiiiiiiiiii■■■■■■■■■■iiiiiiiii|
もしかしてSAFE_DELETE(p)の(p)って仮引数ですか?
ごめんなさい
MSDNライブラリーっていうところでずっと調べてたのですが
見つからなかったので・・・;;
>>514 さんの教えてくれたサイトみたら解決しました
次からはMSDNライブラリーとググってわからなかったら質問します
お騒がせしました
>>505 そんなマクロ要らん。安全性を確保したいなら、せめて auto_ptr とか、何かしらの
スマートポインタ使うほうが簡単で確実。
>>518 たぶん最初に w と Enter を入力したろ?
cin >> rorw; で 'w' だけ読み取って、Enter はまだ読まれてない
次の cin.getline で残った Enter が読まれて終了
>>519 改行を抜いて問題なく実行できました。
ありがとうございます。
コールバック関数とはどういうものなのでしょうか。 WinAPIやMFCを使っていたのでコールバック関数とはてっきり 「何かの動作をした場合に走らせる関数」と思っていたのですが違いますよね。 調べると渡す関数によって動作が変わる関数のような説明が多いです。 例えば○○Func(10,10,AddFunc)だと20が返り、○○Func(10,10,DivFunc)なら1が返るなど。 つまりこの○○Funcがコールバック関数なのでしょうか。 「コールバック」という言葉から事前に登録した関数が何らかの動作の際に呼び戻されるという思い込みがあって 未だに曖昧ですっきりしませんorz
そのAddFuncやDivFuncなどの呼ばれる方がコールバック関数 ○○Funcなどの呼ぶ方は何か特別な名前で呼ぶとすれば高階関数かな
523 :
521 :2008/08/27(水) 20:41:12
>>522 レスありがとうございます。
つまり「アドレスを渡した先の関数で動作させる関数」をコールバック関数という認識でいいのでしょうか。
CやC++だとAPIにあるような関数があるわけではないので、これ以外にも思い込みの言葉がありそうで怖い・・・
ファンクタと同じようなモンって認識でいいよね?
525 :
デフォルトの名無しさん :2008/08/27(水) 21:21:00
お世話になります。VC++6を使っています。 Win32APIでファイル一覧を取得するのに_findfirst()、findnext()、findclose()を使うのは分かったのですが、 POSIXでいうところのseekdirに当たるものはないんでしょうか? ない場合、なんとか実現する手段はありますでしょうか?
boostのfilesystemでどう?
527 :
デフォルトの名無しさん :2008/08/27(水) 21:30:39
窓の杜の週末ゲームを良く見る。 たまに凄いハイクオリティーなのあるよな あれってやっぱりCで作ってるのか?
>>525 自分でfindfirstと_findnextが得た_finddata_tを配列に貯めていけばいいんじゃないの?
VISTAで.NET 2008だと VC++6.0でMFCを使用したアプリは動かない様ですが win32APIだけを使用したものなら98SEで動作していたVC++のアプリは動作するんでしょうか? また自作のDLL(同じくVC++で作成)も同様でしょうか?
530 :
525 :2008/08/27(水) 22:11:49
>>526 すいません。言い忘れがありました。
C言語でC++は使わない前提です。
>>528 なるほど。
ただ、行いたいのはwin32上でopendir()/readdir()を実装しかったのですが、
staticな変数に_finddata_tを保存して、最初のreaddir()時に云々するより、
opendir()関数内部で_findfirst()を行った後、seekdir()みたいなもので
参照ポイントをずらせないかなと思って質問しました。
//------------------------------------------------------------- // デフォルトコンストラクタ //------------------------------------------------------------- Renderer::Renderer() : m_pD3D(0), m_pD3DDevice(0) { } これの : ってつけるとどういう意味があるんですか? メンバ関数にアクセスするためですか?
「もし、
>>531 の質問に完全な答えを教えたら、
>>531 も私と同じように利口になるだろうが、それは望ましくないな。」
メンバ初期化リスト
コンストラクタ初期化子ってやつですか 調べたら解決しました ありがとうございました
536 :
デフォルトの名無しさん :2008/08/27(水) 23:59:16
複数のデータを連結したバイナリファイルから、 freadでデータを一つずつ読み込みたいんですが、 最後のデータに到達したことを判断する方法ってありますでしょうか。 ファイルの終わりに到達したのにさらにfreadをした場合どうなるのでしょうか。 環境はVC++、Windowsアプリケーションです。
538 :
536 :2008/08/28(木) 00:03:28
自己解決したかも。。 これでいいですか? while(fread(pBuf, size, 1, fp) == size) { }
テキストエディタをエディットコントロール使わずに自前で自作しようとしたら、 ウインドウに描画する文字列は再描画し続けないと駄目なのでメモリ上に取り込んで おく、っていうやりかたであってますか? ためしに100MBのテキストファイルを notepadで開く -> notepadのメモリ使用量約200MB 秀丸で開く -> 秀丸のメモリ使用量約50MB だったので秀丸ってどうやってるのかなとちょっと疑問に思ったもので
ファイル全体を保持してるわけじゃないんでしょ。
542 :
536 :2008/08/28(木) 00:35:30
>>537 どうもありがとうございます。
戻り値は読み込んだサイズでなく、個数なんですね。
int num = 0; //配列番号 double box = 0.0;//任意の数値 double data[ 3 ] = { 1, 2, 3 }; num = 0.4 * box; でnumに小数点以下切り捨て(例1.2→1)の数値を入れるにはどうすればいいでしょうか?
>>543 numはintだから何もしなくてもいいんじゃない
>>543 intに変換した時点でなる
ただし四捨五入ではなく小数点すべて切り捨て
warningが気になるならキャスト(cast)調べろ(ただしあまり使うべきではない。その理由もキチンと把握すべし)
あとその場合、boxが10以上の場合
異常をきたすので、その対処も忘れずに
static_cast<int>()
547 :
545 :2008/08/28(木) 08:06:16
ああ、済まない
「dataが10以上のときに」ではなく
「numが0より低いor4以上のときに」だな
>>546 ひけらかしたいのか教えたいのか
dataでなくboxだた
>>547 >キャスト(cast)調べろ(ただしあまり使うべきではない
>546
微妙に論点ずれてる上に答えになってない つーか君は会話出来ないのか?
それだと型はdoubleのままだ。
546じゃないけど546のレス以外の何ものでも無いと思う。
Cなら少し違うけど。
それに
>>543 の目的で「あまり使うべきではない」のも意味が分からない。
切り捨てのセマンティクス的にってことかな?
整数化のセマンティクスとして問題無いように思うけど。
>>552 型変換自体は暗黙の変換を期待してるが floor を使う理由は
次のコードにおいて
#include<stdio.h>
#include<math.h>
int main(void){
int base=10000, a, b;
double ratio=0.7;
a=base*ratio;
b=floor(base*ratio);
printf("a=%d b=%d\n", a, b);
return 0;
}
Borland C++ Compiler 5.5.1 での出力結果は
6999 7000
gcc 3.4.5(MinGW) での出力結果は
7000 7000
と出力結果が異なる不具合を避けるため
処理系間の浮動小数点数の誤差って程度問題じゃね? 完全に誤差無くそうとしたら大変だと思うけど・・・。
10.2 * 100 = 1019 になるしな
557 :
デフォルトの名無しさん :2008/08/28(木) 13:12:49
マネージコードでdllを作成することってできる? dllのソース内でSytem::Stringを使おうとしたらC4747エラーがでちゃった ソースの方に「#pragma unmanaged」宣言してるから仕方ないんだけどさ なんかやり方あるんでしょうか? 環境はvc++2005でc++/clrでやってます
>>557 時代に乗れなくてマネージコードが理解できないおじさんが通りますよ
C++はマネージコード廃止してくれないかな
>>557 C++/CLIはC++とは別言語です。
専用スレがあるのでそちらへ。
>>559 言語名間違えたまま検索して専用スレがないと思ってこっちにきてました
移動します
char*の文字列に漢字をいれるとプログラムによって1バイトごとの中身が変わるのですが何が原因なのでしょうか。 sprintfを使ってchar*に入れたもので、文字列をprintfすると正しい漢字が表示されます。 ただしchar*の文字列を別のプログラムに渡したり受け取ったりすると正しく表示されません。
はあ?
これは難しい・・・・
>char*の文字列を別のプログラムに渡したり どうやって別のプログラムに渡してるんだ?
>>564 単純にchar*文字列を1バイトずつファイルに入れているだけです。
渡す以前に
char str[256];
sprintf( str, "漢字" );
を実行したときのstrの中身が1バイトごと見ると違っていたりします。
デバッグでstrを見ると「漢字」が表示されます。
英数字は大丈夫(中身がバイト単位で一致)で、ひらがなも問題ありませんでした。
2つのプログラムで同じ漢字を使っても1文字でchar2つ分使ってたり1つで済んでいたりと違いがあります。
>違っていたりします。 何と違うの? 別のプログラムの具体的な名前と、 渡したり受け取ったりというのを詳しく。
使用している文字コードの違い char型といってもSJIFやUTF8など色々あるので開発環境が違えば正常なデータのやり取りが出来なくなる危険性がある ちなみにUnicodeは2バイト固定なのでTCHARとかで拾ってやれば漢字でも問題ない 質問者はともかく回答者まで知らなかったとかいうオチじゃないよな・・
原因はそうだろうけど、 質問者のレベルがどの程度かを、ね。
>>567 TCHARもどっかがUNICODEコンパイルせずでダメになるだろ。WCHARにしないと。
>>567 話は逸れるけど、今時のUTF-16も1文字2バイト固定ではありませんよ。
572 :
デフォルトの名無しさん :2008/08/28(木) 22:45:57
template <class T> class A { }; template <class T, int I> class B : public A<B<T, I>> { }; int main(int argc, char* argv[]) { B<int, 5> b; return 0; } Visual C++ 2008なら通るんだがg++だと通らない。 a.cpp:7: error: template argument 2 is invalid a.cpp:7: error: template argument 1 is invalid なぜじゃー
m_pVB->Lock( 0, 0, (void**)&v, 0 ); (void**)&v これってどういう意味なんですか? &だから参照渡しかと思ったら*でポインタっぽい感じがしてよくわかりません・・・
>Unicodeは2バイト固定 突っ込みたいがスレ違いなのでバナナ食べてくる
>>573 & ってのは、変数を定義するときにつければ「〜型への参照」になるけど。
すでに存在する変数につければ「〜へのポインタ」になる。
つまり
int& a = 〜〜〜;
これは「 a は int 型への参照」を意味するが
int b;
f(&b);
これは「 b へのポインタを関数 f に渡す」になる。
つまりその
(void **)&v
は、「 v へのポインタを、void ** 型にキャストする」
ってことになる。
ドライバのプログラミング(WDK)についての質問ってここでいいんでしょうか? スレ違いだったらすみません
>>567 友人とソケット通信を作って動かしたら文字化けしたの思い出した。
送信する文字列やサイズは合ってるのでソケットプログラムが原因だと半月対峙したのも今は昔。
>>573 恐らく頂点周りのかな。
575も書いてるけどvをvoid**型にキャストするだけ。
頂点の型は色々ある(ユーザーが作ると型名なんか全て一緒にならない)けど、結局は座標やUV値など中身は似たようなものなので
Lock関数でどんな型でも受け取って処理できるような形になってる。
もう1つだけ分からない点があるのですが voidのあとに**を2つつける意味ってなんですか? 調べたら === C++でも任意のポインタから void * へは暗黙の型変換が可能です。 でも、void** は、void * ではありません。 ということです。 ちなみに、Cだと、void ** へも暗黙の型変換できてしまうようです。 === という風に書いてあったのですが いまいち2個つける意味が理解できません よかったら教えていただけませんか よろしくお願いします
581 :
576 :2008/08/28(木) 23:12:46
>>579 vを持った配列のアドレスといったら分かりやすいかな。
リンゴ(int)の配列がダンボール(int*)で、それの配列が店(int**)。
ダンボールに入れることが出来るのはリンゴだけ。
店にダンボールをいくつも置けるし、そのダンボールにリンゴを入れることも出来る。
店(int**)が今日は1番目のダンボール(int*)を使い、明日は5番目のダンボール(int*)を使う・・・とか店(int**)1つで管理できる。
voidの場合はアドレスの型を指定させない場合に使うので使い方は変わるけどね。
例えが宜しくないけど、ポインタのポインタってこんなイメージでも。
>>582 おお!ありがとうございます!
理解できました
ポインタのポインタって感じですね
>>582 ダンボール(int*)が本当にリンゴ(int)を入れてもいいダンボールなのかチェックが必要とかw
例え話はそのままで教えるよりも余計ややこしく感じるぜ
マトリョーシカな世界だな
テキストで書かれた"FF00CC"てな感じの文字列をバイナリに直しているのですが 文字列に"0A"が来ると改行コードと間違えるのか、変換されたバイナリが「0D0A」になってしまいます。 うまく対処する方法はないでしょうか? windowsのコマンドプロンプトで利用しています。 int main(int argc, char *argv[]){ int c, sigbit, isSig; isSig = 1; while ((c = getc(stdin)) != EOF) { if ('0' <= c && c <= '9') c -= '0'; else if ('a' <= c && c <= 'f') c = 0x0a + c - 'a'; else if ('A' <= c && c <= 'F') c = 0x0a + c - 'A'; else if (' ' == c || 0x0a == c || 0x0d == c || 0x09 == c) continue; else { fprintf(stderr, "invalid character %c\n", c); break; } if (isSig) sigbit = c << 4; else putc(sigbit | c, stdout); isSig ^= 1; } return 0; }
588 :
素人 :2008/08/29(金) 10:54:29
getcを使わずにfreadを使う!
変換が起きるのは書き込むときだろう
シーンの作成時やレンダラーの初期化時に HRESULTをいうのを使っているのですが HRESULT Renderer::Initialize(HWND hWnd, BOOL isFullScreen, int clientWidth, int clientHeight) LRESULTとの違いってなんですか? LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); ウィンドウプロシージャルを定義するときはLのほうを使って DirectXの初期化の時などはHを使うって事ですか?
593 :
591 :2008/08/29(金) 11:05:59
すいません書き込むスレ間違えました WIN32APIスレ行ってきます スレ汚しすいませんでした
>589,592 ありがとうございました。
595 :
デフォルトの名無しさん :2008/08/29(金) 19:36:10
classの中にstaticな関数をヘッダで定義したのですが、これをソースファイルで定義するときは staticと書かなくてもいいですか?
admini権限を持っている作成したユーザーでvcvars32.bat実行した後、 cl使おうとしてもvcvars32.batを実行したdos窓でしか使えない… これってsetコマンドの元からの仕様ですか? Administratorユーザーならdos窓で普通にclが使えるんですが
あ、ここC言語のスレですね。 Visual Cの専門スレに行った方がいいですね…
>>597 環境変数いじればいいんじゃない?
XP なら
[マイコンピュータ]-[プロパティ]-[詳細設定]-[環境変数]
をいじって再起動すればおk
もしかしたらログオフ&ログインだけでもいけるかも
601 :
デフォルトの名無しさん :2008/08/30(土) 09:18:15
#include <iostream> template<class T> class Base { int m_values[T::Dimension]; }; class A : public Base<A> { enum { Dimension = 3, }; }; int main(int argc, char* argv[]) { A a; } a.cpp: In instantiation of ‘Base<A>’: a.cpp:10: instantiated from here a.cpp:6: error: incomplete type ‘A’ used in nested name specifier a.cpp:6: error: array bound is not an integer constant こういうことってできない?
>>601 Base<A>のm_valueの定義はAが先に実体化されてるのが前提になりますが、
Aの実体化はBase<A>より後にされますよね。
ならばBaseはAが定義されてることをどうやって知ればいいんでしょうか?
どうしても例のコードの機構が欲しいのなら
BaseにDimensionの定義を移譲するか、BaseやAより先に実体化される型にDimensionの定義を移譲して、
AやBaseはそれを参照するとするとかしかなさそうな気がします。
>>602 ども
#include <iostream>
template<class T>
class Base
{
public:
void foo()
{
std::cout << T::Dimension << std::endl;
}
};
class A : public Base<A>
{
public:
enum { Dimension = 3, };
};
int main(int argc, char* argv[])
{
A a;
a.foo();
}
これなら通るんだがそういうもんなのか
foo内部の名前の解決はa.foo();時点であるからAの実体化→コンストラクタ呼び出しの時点では問題無く通る で、a.fooの呼び出しの時点でaの型Aはすでに実体化されてるんでBase<A>::foo内部でのA::Dimensionは問題なく解決できる…と そういうカラクリみたい これをよりわかりやすく確認するには、T::dimensionをT::xxxxxのようにAに無い名前にしたら、 エラーになるのはmain()でのa.foo();の行の時点でA a;の時点ではエラーにならない(=a.foo()をコメントアウトすれば通っちゃう) とかそういう例も見ればいいと思う
僕の通っているゲーム関連の専門学校で9月にC言語検定3級があるのだけど 例年の合格率は20%切ってると先生に言われた。 そんなに難しいのですか?
>>606 問題が難しいんじゃない。 受ける層が(ry
やる気のない専学生やら大学生やらがとりあえずで受けてるから低いんじゃないの? 3級は簡単だよ
3級ってお遊びみたいなやつだろ。 ちなみに、その検定は1級とっても実務では役に立ちません。
2級までは簡単だよ 1級は1600行くらいのソースコードを仕様書通りに変更したりするからそう簡単にはいかない
3級20パーってどんだけw
サーティファイのウェブサイトには平均53.5%って書いてあるから、3級は70%ぐらいなんじゃないの。
20%っていうと基本情報の合格率と同じくらいだぞ・・・
父さん、そんな古い物を…
>>614 のマンガはリアルだな。俺の通ってる専門学校もそんなもんだ
自分はゲーム専門学校の2年で夏休み前から卒業製作(週15コマ)の話が持ち上がった。
俺は1年の頃から3DのRPGを創りたくて授業とは別に独学で毎日勉強していた(数学・物理・DirectX・アルゴリズムなど)
他の人たちは何創るのか聞いてみたら俺以外みんな似たような美少女系サウンドノベル。
先生が必ずチームになる事と言っていたのでどこかのチームに入らなければいけない。
僕が1年半必死になって勉強した成果は学校では発揮できないのであった。
家で創ろう
>>616 おまいさんは腐海で腐らされないうちに逃げ出しておきなよ。
私の勤める会社にも、>614の典型のようなのが定期的に入ってくる。
就職できる分だけ頭はいいんだけど全く応用が利かないんだよね。
・何度説明しても変数という概念が理解できない
・1インチは25.4mmと教えているのにインチ→cmの変換関数を作れない
# 理由は「1インチが何cmか判らない」
・「何でプログラムを作るのにキーボードが必要なんですか?」
もうね。
>・「何でプログラムを作るのにキーボードが必要なんですか?」 この考えを突き詰めると今のように中途半端にVSとかで切り貼りするよりも 新しいタイプのプログラミングモデルが出来るのかも知れない、かも知れないだけだけど
>>617 さすがにそこまでひどいのは見た事無いな
全角空白が混じっててコンパイルできないってやつなら見た事あるけど
キーボードめちゃくちゃ使うだろww
キーボードなんか使うのは素人だけだ 玄人に必要なのはマウスのみ!
もしかして手書き認識機能を使うのか!
キーボードを使わずにプログラミングしてる姿が想像できない……
音声認識でブツブツ・・・と
>>624 なるほど!
それなら寝ながらプログラミングできるな!!
626 :
デフォルトの名無しさん :2008/08/30(土) 16:11:24
質問です std::string::size_type ret = str.find(0x09); while (ret != str.npos && ret + 1 < str.length() ) { str.replace(ret, 1, " "); ret = str.find(0x09); } タブを半角スペース4つに置き換えるサンプルですが whileの条件で、ret + 1 < str.length() は何のためにあるのでしょうか? これがあると、ファイルの最後でタブが見つかっても置き換えされないと思うんだけど
趣味でゲーム作ってるプログラマーです 猫が水泳するゲームを作りたいのですが 創り方のアドバイス?いただけませんか。 使える言語は C/C++ OpenGL/DirectX WIN32API です
628 :
デフォルトの名無しさん :2008/08/30(土) 17:16:51
言語が使えると言いながら使いこなせないならただのアホだろ 脳は腐る前に使えよ
マルチスレッド使えばいいんじゃない?
>>627 Cでアクションとかシューティングゲームのソース公開してるのを見て、真似をする。
>>625 Vistaの音声認識でperlのプログラム書こうとするもうまく行かなくて、
最終的にキーボードつかっちゃう動画があったよな…
C++についての質問です。 CTestAクラスの関数MsgAとCTestBクラスの関数MsgBがあります。 それぞれ void CTestA::MsgA(int) 、 void CTestB::MsgB(int) このような感じです。 加えてCTestCクラスにMsgC( void (*pFunc)(int) )があり、そこにMsgAとMsgBを渡したいのですが無理なのでしょうか。 どのようなクラスでも引数と戻り値があっていればMsgCに渡すことが出来、 MsgC内で if( pFunc ) pFunc( n ); のように実行できるようにしたいのですが、MsgCにクラスの関数を渡すことが出来ずに困っています。 void CTestA::Test(void){ 〜略〜 pTestC->MsgC( (void*)( MsgA ) ); } とやってもキャストが出来ずエラーが出ました。 クラスでなければMsgCに渡すことが出来たので、やはりクラスの関数は無理なのでしょうか。
メンバ関数は、staticなものでない限りインスタンスが存在しなければ実行する事ができない。 よってMsgAはCTestAのインスタンスを必要とし、MsgBはCTestBのインスタンスを必要とする。 即ちMsgC( void (*pFunc)(int) )はどんなインスタンスも必要としない関数しか引数にとることが出来ず、 もし仮に何らかのインスタンスを必要とする関数を外部から実行したいのなら、インスタンスとメンバポインタを渡す必要がある。 ちなみにboostには、インスタンスとメンバ関数のポインタを渡せば、関数の属する型がどんな型であっても 動的に解決して実行してくれるものが存在する。 これは、テンプレート関数で実行をラップし、そのテンプレート関数のポインタを動的に操作しているに過ぎない。
634 :
617 :2008/08/30(土) 19:39:33
>>623 課題の書かれたメールからキーワードを抽出して検索、
見つかったサンプルっぽいコードをコピペすれば完成。
この間、マウス操作だけで行なってしまうわけ。
勿論、最初はコンパイルさえ通らない。
そうしたらエラーメッセージで検索して、
また適当に見つかったサンプルからコピペしてくる繰り返し。
それを見咎めて「目の前にキーボードがあるんだから、
課題ぐらい自分で打てよ」と言われたときの返事が
>「何でプログラムを作るのにキーボードが必要なんですか?」
というわけ。
他の二人は自分には向いてないと理解したし素直にやめたが、
このマウス野郎は親からクレームの電話が掛かってきたらしい。
# この親にしてこの子ありと言うか、まさにモンペ。
>>632 関数のポインタを求めるメンバ関数を作るくらいなら、MsgCが求める
インターフェイスへのポインタを入力にして、MsgCの中でそれを呼ぶ。
仮想関数ってそのためのものだし。
メンバ関数のアドレスを入力にするという方法もある。
個人的にはどっちもおすすめではない。
オブジェクトのコンポジションで解決すべき内容な気がするし。
636 :
632 :2008/08/30(土) 21:21:20
>>633 ,635
ありがとうございます。
改めて色々考えてみましたが一筋縄ではいかないようですね。
想定している用途としてはCTestCクラスのインスタンスに別のクラスの関数を登録しておき、
CTestCクラスのインスタンスが一定回数呼び出されたら登録した関数を呼び出す。
他にもデストラクタに「削除」のメッセージを登録した関数に送るなども考えています。
登録する関数は様々なクラスのもの、関数名自体も不定・・・となれば頭を悩ませてしまいます。
テンプレート自体名前ぐらいしか知らないのですが、これを上手く使えば上記のことが解決するのでしょうか。
637 :
デフォルトの名無しさん :2008/08/30(土) 22:50:32
テンプレートクラスを書くときって cppは空でヘッダにバリバリ書いていくけど、 複数のcppからそのヘッダを読み込んで実体化すると、 その分バイナリの容量が増えることが多い?
638 :
デフォルトの名無しさん :2008/08/30(土) 22:59:00
>>632 テンブレートなんて使わずに、
オブザーバパターンでググってみれ。
ここから先は有料だ。
>>632 のやりたい事が実現できるdelegateという仕組みが他の言語にはあってのう・・
>>638 違うんでない?
Observerパターンはあるオブジェクトの振る舞いがなされたことを、
通知先のオブジェクトの型にかかわらずにインターフェイスを介して
行うこと。通知先の登録・削除があるのが普通。
639も言うとおり、MsgCをコールする際にインターフェイスを
求めるのはどちらかと言うとテンプレートメソッドに近いかと。
いちいち継承したりインターフェイスを実装したりするのがウザい
から、他の言語では delegate。
641 :
デフォルトの名無しさん :2008/08/31(日) 00:21:36
デリゲートなんか使うのは設計が悪い。 そもそもデリゲートはstatic関数しか駄目じゃん。 たくさんコールバック関数があるとかいってるからもう少し整理して抽象化するべき。 よってオブザーバをすすめる。
>>636 関数じゃなくて、オブジェクトを登録して、RTTIでクラスを判別しつつ、適当なメソッドを呼び出すってのもありじゃね。
>>642 とりあえず、swp(int a, int b)がよろしくない。
swp(int& a, int& b)にするとか?
>>642 数値の入れ替え自体は std::swap を使えばおk
但し、配列同士の入れ替えはできないのでこんな感じ
std::swap(cards[ran1][0],cards[ran2][0]);
std::swap(cards[ran1][1],cards[ran2][1]);
cout に char を与えると char を文字コードとして出力する
数値として出力したければ int を cout に渡せばよい
C++ のキャストはよく知らんのでどう書くかは他の人に任せる
入れ替えのアルゴリズムについて
変数 cards は構造体もしくは class にすれば
std::random_shuffle(&cards[0], &cards[51+1]); // この場合は cards[0]〜cards[51] までの計 52 枚をシャッフルする
とかできる
または下記のアルゴリズムがそれなりに優秀
for(int i=0;i<52;i++){
ran2=rand()%(i+1);
std::swap(cards[i], cards[ran2]);
}
>>645 レス有難う御座います。
他のところは自己解決しましたが、シャッフルの良い案が無くて詰ってました。
提示していただいたシャッフルアルゴリズム見ながらいじってみます。
perl でいう CPAN みたいな、 各人がライブラリを公開している所ってある?
648 :
626 :2008/08/31(日) 04:39:59
ファイルって書いちゃったけど、文字列の間違いでした strはstd::stringです ret + 1 < str.length() が必要なのか誰か教えてください
>>648 普通に考えて、タブを空白に変換するには先頭からのカラム数を意識する必要がある。
さもなくば、先頭からの連続したタブだけを対象にするとか。
そのどちらでも無いそのサンプルは、要はそのサンプルならではの仕様なんでしょ。
いずれにしても、「0x09」なんて書いているサンプルじゃ見るだけ無駄だよ。
650 :
デフォルトの名無しさん :2008/08/31(日) 10:00:05
char型で、ワイド文字の関数にアクセスしたくないですか? Wcharは色々と使いにくいんです。 ファイル、ディレクトリアクセスに関わる所だけWcharに変換してアクセスしたら良いと思います
651 :
デフォルトの名無しさん :2008/08/31(日) 10:00:23
コンパイラについての質問なんだが。。。 DJGPPのgxx.exe使おうと思ったら Cannot execute "gcc.exe": No such file or directory(ENOENT) てエラーでたんだが。。。 gxxってコンパイラの補助してるだけなの? やっぱりcygwinとか入れてgcc使える状態にしなきゃだめなの?
メンバ関数全部仮想にしてもいいよね(´・ω・`)
#include <stdio.h> main() { int ia; printf("好きな数字を入力してください:"); scanf("%d", &ia); if (ia >= 0) printf("+の数字が入力されました\n"); else printf("-の数字が入力されました\n"); } これをコンパイルしようとすると rezserverd.libが見つかりませんって出るんですけど どう対処すればいいですか?
655 :
デフォルトの名無しさん :2008/08/31(日) 10:56:16
質問です。 データをバッファにため込んで書き出すクラスを作ったとします。 アクセスごとに、バッファのサイズを確認して書き出せば一応出来ますが もしバッファが、49M貯まっていてあと1メガふえれば書き出す場合に データはしばらく来なかったら、書き出されるバッファを占有し、電源切れたらデータも消えます。 タイマーみたいにしてアクセスが無い事を知る方法はありますか?
>>655 デストラクタでフラッシュするようにしたら?
>>654 本当にそのライブラリがないといわれるなら作成環境を1から作り直さないとやばそうな気が。
>>651 環境変数 djgpp に djgpp.env のフルパスを設定しる
>>654 開発環境がおかしい。
環境は何?
まぁ何であれ
>>657 の通り作り直さないといけないけど。
>>651 gxx.exeが「djgppのgcc.exe」を呼び出してると思われ。
cygwinとかは要らないっしょ。
661 :
デフォルトの名無しさん :2008/08/31(日) 11:36:08
>>660 readme読んだらそうらしい。
最低限必要なファイルが4つくらいに分かれて配布されてた。
英語でもreadme嫁ですね。
>>659 開発環境はマトリョーシカです。
開発環境の構築を再確認してみます
うちの専門学校に某ツクールで創ったゲーム持ち込もうとしてるやつがいる。 結構面白くてみんなから羨望のまなざしを受けてるんだけど、某ツクール作品で受かったやつっているのか? 流石に無いと思うんだが・・・。
書き込むスレ間違えました スレ汚しすいません
666 :
デフォルトの名無しさん :2008/08/31(日) 12:44:07
SetTimer SetWaitableTimerは使う用途は違うんですか?
667 :
デフォルトの名無しさん :2008/08/31(日) 12:47:12
666です。わかりました。とおもいます。 Settimerは時間経ったら関数を呼び出し SetWaitableTimerは時間経ったらシグナルを出すんですね。
668 :
デフォルトの名無しさん :2008/08/31(日) 12:57:22
マルチスレッドの勉強をしているのですが、次であってますか? どの排他処理が優れているとかはないですよね? 以前はどれか一つを学べば良いと思ってました。 クリティカルセクション ・・・ コードで止める ミューテックス ・・・ リソースで止める セマフォ ・・・ 回数で止める SetWaitableTimer ・・・ 時間で止める
うーん。 もう少しOSの勉強してからだと理解早いと思うよ。
671 :
デフォルトの名無しさん :2008/08/31(日) 13:24:18
673 :
デフォルトの名無しさん :2008/08/31(日) 14:06:20
ミューテックスだったらデットロックは発生しないんですか?
>>673 性質を理解してれば発生しないように作ることは出来るよ
675 :
デフォルトの名無しさん :2008/08/31(日) 14:46:14
ファイルを書き込む関数を作ったとして、参照で5Mの書き込み要求があった場合 それをコピーしておけば、他の書き込み待ちがあっても呼び出し先へ直ぐに復帰でき 元のメモリも自由になります。 もし、500Mの書き込みなら、メモリにコピーするのは大変で、書き込み完了まで待たせた方が良さそうです。 何メガ以内ならコピーしたら良いと思いますか?
676 :
デフォルトの名無しさん :2008/08/31(日) 14:57:20
ファイルへread write read write とする場合、write write read readの方が速いでしょうか?
mutexでもデッドロックは発生する可能性がある 十分注意せよ
スレッド使わなければ気にしなくていいんじゃね?
680 :
デフォルトの名無しさん :2008/08/31(日) 15:54:34
よく考えたら、バッファついてたら、Read優先したほうがいいですね。 Writeは利用する側からすれば完了しているになっているので
wavファイルから象の雄叫びを入力して 数値によってエコーの量が変わるプログラムを作りたいのですが 何から着手していいのかわかりません・・・・。 アドバイスもらえませんか?
>>680 何を言いたいのかよくわからないが、一度「トランザクション」でぐぐって勉強がいいかも。
これ以上の話はスレ違いだから、続けるならどこか適当な場所で。
BOOL isFullScreen = FALSE; for(int i = 0; i < nCmdShow; i++) { if(_stricmp((char*)&lpCmdLine[i], "/f") == 0) { isFullScreen = TRUE; break; } } これの部分でif(_stricmp((char*)&lpCmdLine[i], "/f") == 0) コマンドラインに/fがあればTRUEにするってことだと思うのですか (char*)&lpCmdLine[i]はどういういみですか?
(char*)(lpCmdLine+i)
>>684 なんで質問部分の肝になるlpCmdLineの宣言をコピーしないの? つーか、取捨選択もできない馬鹿なら関数丸ごと貼りなさいよ。
>>686 ごめんなさい
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// フルスクリーンかどうかの判定
// コマンドラインに/fか/Fがあればフルスクリーンにする
BOOL isFullScreen = FALSE;
for(int i = 0; i < nCmdShow; i++) {
if(_stricmp((char*)&lpCmdLine[i], "/f") == 0) {
isFullScreen = TRUE;
break;
__stricmp()に渡すためにLPSTRでは警告が出るから 型キャストして警告を消してるんだろう
それなら、char*へのキャストは無駄以外の何物でもない(少なくともWin32では)。 &lpCmdLine[i]で全く問題ない。元のコード書いたやつが無知なだけだ。
>>688 LPSTRはchar*のtypedefだぞ。
というかこれだと fで始まるオプションは"/f"しか使えないけどいいんだろうか
ごめん大丈夫だった 寝るか
693 :
デフォルトの名無しさん :2008/09/01(月) 02:01:38
コマンドラインの単純なプログラムで、Windowsのバーに表示させない方法ありますか? 常駐みたいな感じです。
APIを使えばできます。
int han[2]={0,0}; int hant(int f, int s) { if(f==1 && han[0]/100<=0) return han[0]+100; else if(f==2 && han[0]/10%10<=0) return han[0]+10; else if(f==3 && han[0]%10<=0) return han[0]+1; if(s==1 && han[1]/100<=0) return han[1]+100; else if(s==2 && han[1]/10%10<=0) return han[1]+10; else if(s==3 && han[1]%10<=0) return han[1]+1; } 数字1〜3を受け取り一回でも現れたら 1=100 2=10 3=1 の桁に1を入れて3桁の数字を返したいですが 何度やっても、0しか返してくれません。 何度読み直しても何処がいけないのか分かりません・・・ ヘルプお願いします。
>>695 どれにも一致しなかったら何を返すんだい?
>>695 han[ ]が初期化されている1回目はちゃんと動くはず
いったん値が保存されると2回目からは値を返さないよ
関数の最後にreturn han[0];とかいらないのか
int v; 一応ちゃんと帰って
698はミスったごめん int v; v = hant(0, 3); みたいにするとhantの戻り値でちゃんと返ってきてるみたいだよ 0になるってもしかして printf("%d, %d\n", han[0], han[1]); みたいにhan[0]を表示しようとしていない?
>>695 一応受け取る数字は1〜3以外はブロックしてます。
あと、この問題自己解決しました。
どうやらHant()が丸ごと動かなかったようで
Han[]のグローバル宣言をやめMain()内で宣言、Hant()もMain()に組み込むことで
何とか動いてます。
>>700 元のままで、
int hant(……
→
void hant(……
return han[0]+100;
→
han[0]+=100;
他も同様
と変える。
色々なアドバイス有難う御座います。
いま、プログラム自体は何とか動いてますが
Main()が無駄に膨らんできたのでげんなりしてます。
これからもお世話になると思うので、今まで書いたソースをUPしときます
一から自分で書くのは今回初めてなので悪い所があったらご指摘お願いします。
http://www.dotup.org/uploda/www.dotup.org2141.cpp プログラムはマルバツゲーム、大体の動きが出来上がったので
次はAIを詰め込む予定です。
勝利判定がまた不十分な点は暫くスルーすることにしました。
指摘項目 >void main() 基本的には間違い。 > char fil[5][5]={"0123","1","2","3"}; 無駄。表示用文字管理とデータ管理は分けたほうがいい。 その所為で、入力処理の辺りがぐだぐだになっている。 つーか、肝心なまるとばつを置く場所が初期化されてないぞ。 > if(flag==0) cout <<" MARU \n"; > else if(flag==1) cout <<" BATU \n"; 慣れないうちはブロック化推奨。 > //勝利判定の時間 > > > > cout <<han[flag][0]<<" !!!!!!!!!!!!!! "<<han[flag][1]<<"\n"; //判定フィールド確認用 何この変なインデントと無駄な空行。 つーか、判定方法考えすぎで滅茶苦茶になってないか? なんでわざわざ数値化しているんだ? 仮に、filがちゃんと管理されていればhanの配列なんていらんだろ。 例えば、fil[1][1] == 'O' && fil[1][2] == 'O' && fil[1][3] == 'O'みたいな愚直な判定で十分。
704 :
デフォルトの名無しさん :2008/09/01(月) 12:37:21
>>703 main()の宣言について、少し調べてみます。
>> char fil[5][5]={"0123","1","2","3"};
>無駄。表示用文字管理とデータ管理は分けたほうがいい。
>その所為で、入力処理の辺りがぐだぐだになっている。
>つーか、肝心なまるとばつを置く場所が初期化されてないぞ
データ部分だけくりぬくってのはやりたいのですが
出力方法は配列しか思い浮かびませんでした。
初期化については、文字を一度クリアして同じ所に描画することなら
今猫でもわかるで調べてますが、上手く行ってません
>つーか、判定方法考えすぎで滅茶苦茶になってないか?
>なんでわざわざ数値化しているんだ?
最初は力業でやろうとしましたが、物凄い量のコードになりそうだったことと
CPU対戦を詰め込むとさらに増えそうだったので、数値化してみました。
>>704 海岸でいきなり1mもあるような砂の城を作ろうとしてもw
まずは30cmくらいの砂の山で我慢しておけって。
そうすれば城を作るにはどんな技術が必要になるのか見えてくるだろ。
と、例え話はさておき。
filは初期状態ではこうなっている。
0 1 2 3 \0
1 \0 \0 \0 \0
2 \0 \0 \0 \0
3 \0 \0 \0 \0
\0 \0 \0 \0 \0
一方、表示ルーチンではその内容を文字列としてではなく文字として出力している。
つまり、\0を出力しようとしているわけで、そこは明らかにおかしい。
更に言えば、文字単位でしか出力しないのなら、文字列として扱う必要もないということ。
また、表示用の0123なんて文字も、データとしては全く必要ない。
そこで私がこのレベルで書くなら、char fil[3][3]; for (int iy = 0; iy < 3; ++iy) for (int ix = 0; ix < 3; ++ix) fil[iy][ix] = ' ';とする。
# まぁ、定数の3は生では使わないが。
表示ルーチンも、最初から独立して考えればいい。
例えばこんな感じ。
void print(char const field[][3])
{
cout << "0123\n";
for (int iy = 0; iy < 3; ++iy) {
cout << iy + 1;
for (int ix = 0; ix < 3; ++ix) {
cout << field[iy][ix];
}
cout << '\n';
}
}
これなら、最初の表示にもループ中の表示にもそのまま使える。
今のうちに見た目スッキリなソースを目指すよう、心掛けるんだ
class A { public: virtual void method(){..} }; class B : public A { public: void method(); }; こういう継承関係があって vector<A> list; B b; list.push_back(b); list[0].method(); こうやるとBのメソッドが呼ばれず直接Aに行くのだけど Bに行かせるにはどうすればいいの?
vector<A*> list; B *b = new B(); list.push_back(b); list[0]->method(); ※deleteし忘れ注意
それは ((B*)list[0])->method(); じゃなくて? スマートじゃないな
>>707 がうまくいかないのは、vector が内部に持ってるのは
push_back に渡された b を元にコピーコンストラクトした A で、
その A の method を呼んでるだけだから
vector に持たせるのがポインタだけなら
ポインタ自体をいくらコピーされても実体は B のままだから呼べる
でも解放し忘れやすいので vector<shared_ptr<A> > を使うべきという人もいる
>>707 スライシングと言って、listに格納されたときにはBではなくAのオブジェクトになっている。
だもんで、一般的に継承を使うクラスではコピー禁止にすることが多い。
>>709 それじゃなんのための仮想関数ってことになるじゃないか。
>>711 見ただけ?
得た知識を元に実際に何か役に立ちそうなプログラムを一度自分で作ってみるべき
714 :
711 :2008/09/01(月) 19:11:56
>>713 オセロは人対人のものは作りました。
それではまだだめでしょうか。
>>714 自分がやりたいと思うことをやればいいじゃない。
716 :
707 :2008/09/01(月) 19:37:55
出来たんだけどもう1つ教えてください B *b = new B(); list.push_back(b); だといけるけど void add(A *a){ list.push_back(a); } B *b = new B(); add(b); list[0]->method(); ってあるとやっぱりAに行く 追加はメンバ関数で隠蔽したいんだけどこれはどうしたらいいの?
#include <stdio.h>
#include <vector>
class A { public: virtual void method(){ printf("A::method\n"); }};
class B : public A { public: virtual void method(){ printf("B::method\n"); }};
class Foo {
std::vector<A*> list;
public:
void add(A *a){ list.push_back(a); }
void foo(){
B *b = new B();
add(b);
list[0]->method();
}
};
int main() { Foo().foo(); }
実行結果
B::method
>>716 そんなことにはならないが・・・
ほんとつかえねーやつらだな
初心者歓迎スレで何を
>>711 ほかになんかC関係のサイト一つ眺めてみてスッと読めるようなら、
知識としてのCはいいんじゃない?
さっさとC++覚えて、いろんなもの作ってみればいいよ
721 :
707 :2008/09/01(月) 19:59:27
あれほんとだ なんでだろ
722 :
711 :2008/09/01(月) 20:02:40
デザインパターンのObserverパターン実装サンプルコードで、 //observerの抽象クラス class Observer { protected: virtual ~Observer() = 0 { }; public: virtual void update() = 0; }; //observerの具象クラスが共通に持つインターフェースのクラス class DisplayElement { protected: virtual ~DisplayElement() = 0 { }; public: virtual void display() const = 0; }; //observerの具象クラス(の1つ) class ConcreteObserver : private Observer, private DisplayElement { ... }; こういったものがあります。 (subject側のクラスは、protectedなデストラクタを持つ抽象クラスを、public継承した具象クラスという形でした。) ・基底クラスのデストラクタがprotectedである理由 ・具象クラスがprivate継承している理由 がよく分からないのですが、よろしければ教えていただけないでしょうか。
・基底クラスのデストラクタがprotectedである理由 は基底クラスのポインタでdeleteされた時に派生クラスのデストラクタが呼ばれる様にするため ・具象クラスがprivate継承している理由 ConcreteObserver以外のクラスからupdate()やdisplay()を呼ばれたくないとか
726 :
711 :2008/09/01(月) 22:34:18
>>725 では具体的にどういうサイトを見ればいいですか?
つ[ここ] 宿題スレの宿題でも解いてみたら?
テンプレート関数で template<template<class T, class A=std::allocator<T>>class C, class T> void func(C<T> arg); vector<int> v; func(v); このように引き数に渡されたコンテナを、コンテナ型と中身の型とに 分けて知ることができますが、 template<template<class T, class A=std::allocator<T>>class C, class T> class separator { //C<T>のTの型が知りたい typedef T param_t; } separator<vector<int>>::param_t val; //引数の数が合わない テンプレートクラスでテンプレート引数に渡されたコンテナを分解することが 上手くできません。どう書けばいいのでしょうか?
これで十分だよ。 template<class C> class separator { typedef typename C::value_type param_t; };
vectorだけならそれでもいいのですが、 テンプレート型全般に適用できる方法が無いか 知りたかったんですが。
>>724 は違うと思うな。
>>・基底クラスのデストラクタがprotectedである理由
>>は基底クラスのポインタでdeleteされた時に派生クラスのデストラクタが呼ばれる様にするため
→これはデストラクタにvirtualがついている理由。
protectedにするとObserver型のポインタに対してdeleteできなくなり、Observerクラスを以下のようにポリモーフィックに使えなくなる。
Observer* p = new ConcreteObserver;
p->update();
delete p;
・具象クラスがprivate継承している理由は、上記と同じ。private継承すると、デストラクタをpublicに変えても上記コードはコンパイルエラーになる。
Observerクラスをポリモーフィックに使われないようにこうしてると思う。
732 :
731 :2008/09/01(月) 23:09:06
>>731 >>protectedにするとObserver型のポインタに対してdeleteできなくなり、Observerクラスを以下のようにポリモーフィックに使えなくなる。
間違えた。ポリモーフィックには使える。
Observer* p = new ConcreteObserver;
p->update();
delete p; //ここでコンパイルエラー
ちなみにprotectedデストラクタはvirtualつけない方が普通(推奨)と思うけどね。
>>730 なら部分特殊化。
template<class>
class separator;
template<template<class, class> class C, class T, class A>
class separator<C<T, A> > {
public:
typedef T param_t;
};
separator<std::vector<int> >::param_t val;
734 :
731 :2008/09/01(月) 23:21:53
分かりづらいかも知れないので補足。 Observer* p = new ConcreteObserver;//private継承によってこれを禁止 p->update(); delete p; //protectedデストラクタによってこれを禁止
735 :
724 :2008/09/01(月) 23:26:02
うひょ盛大に間違えてたぜ
NULLポインタにアクセスすると普通フォルトしますが、 int* i = NULL; int x = *i; // フォルト 以下のようにするとフォルトが発生しません。 どうしてなのでしょうか? int* i = NULL; int& Int() { return *i; } // ここでフォルトが起きるはずでは? int main(void) { int* x = &Int(); // xにはちゃんとNULLが入っている return 0; }
737 :
723 :2008/09/02(火) 00:47:57
レスありがとうございます。
検証コードを書きつつ、なるほどと納得させていただきました。
ついでに、もう少し突っ込んでお聞きしたいのですが、
>>734 で書いていただいたように、new/deleteからの多態性が禁止されている事は分かったのですが、
ConcreteObserver co;
Observer* pco = &co;
pco->update();
といった形での多態性は、サンプルコードでも肝として使用されています。
作者の意図がいまいち分からないので、もし自分がObserberパターンをコーディングするとしたら、
抽象クラスの仮想デストラクタをpublicにして、それをpublic継承して具象クラスを書くと思うのですが、
それではまずい事態を招きうるのでしょうか?
>>736 空ポインタをデリファレンスしたときの動作は未定義だから。
>>736 参照を返すとき、実際に中身にアクセスするわけではありません。
従って、ポインタのポイント先の実体の参照を返すときにもポイント先にアクセスせずに、参照を返せるのです。
g++ で、何故か関数のプロトタイプの宣言が変数として認識されてしまいます。 例えば以下のようなファイルをコンパイルしようとすると ----hoge.h------- #ifndef h_hoge #define h_hoge #include "some_class_flags.h" void check_error(some_class_flags err); #endif ----hoge.cpp----- #include "hoge.h" #include <wx/wx.h> void check_error(some_class_flags err){ if (err!=0) wxMessageBox(wxT("ERROR"),wxT("err"),wxOK); } --------------- hoge.h:4: error: variable or field ‘check_error’ declared void hoge.h:4: error: ‘some_class_flags’ was not declared in this scope というエラーが出てきます。どこがいけないのでしょうか?
some_class_flagsが型として認識されてないんだろ
743 :
741 :2008/09/02(火) 02:45:46
>>742 私もそうだと思ったのですが、クラス名(またはTypedef名)に打ち間違いはなく、
実際のところ some_class_flagsは広く使われているライブラリのヘッダなので、
some_class_flags.h 自体に間違いが有る可能性も低いと思います。
>実際のところ some_class_flagsは広く使われているライブラリのヘッダなので、 >some_class_flags.h 自体に間違いが有る可能性も低いと思います。 だってコンパイラが文句言ってんだろ 一度ヘッダファイル覗いてみ
some_class_flagsをintに置換したらどうなるの?
746 :
741 :2008/09/02(火) 02:51:32
>>742 すいません、自己解決しました。
小文字のlと数字の1の読み違いだったようです。
自分の視力にWarningを吐くべきなのでしょうか。
(#^ω^)
フォントを変えろw
メンバ関数の引数に列挙型を指定して、その内容によって オーバーロードされたうちのどれかを実行する…なんてことはできませんか?
>>749 内容によってって、同じ型なんだからオーバーロードでは無理だろ
値によって関数を呼び分ける関数作ればいい
>750 ありがとうございます!その方法を利用させていただきます
テンプレートの数値特殊化でもできるよね
>752 こういった使い方もできるのですね ありがとうございます。
sprintf みたいな引数の数がいくらにでも増やせる関数ってどうやって作るんですかね?
va_start va_arg va_end を使って作る
Python の yield のようなことは C++ では不可能なんでしょうか? ジェネレータ自体は関数オブジェクトとして代用できると 思うのですが、ジェネレータを書くに当たって yield のような 仕組みがあったら便利だなぁと思っています。
SwitchToFiberとか
ヘッダオンリーのライブラリが最近は多いみたいですが、 自分で作る場合どこまでヘッダオンリーで我を通していいものなのでしょう? なんらかの指針、判断材料があったりするものでしょうか?
>>760 そこに書いてある関数呼出の手法はva_*を使うものではない。
そもそもC++ではva_*での可変個引数が論外だから取り上げられていないだけ。
>>759 コンパイル時間が気になるかどうかじゃね?
764 :
731 :2008/09/02(火) 20:07:22
>>737 >>ConcreteObserver co;
>>Observer* pco = &co;
>>pco->update();
これってできないんじゃないかな。VC9だと以下のエラーになるよ。
error C2243: '型キャスト' : 'ConcreteObserver *' から 'Observer *' の変換は存在しますが、アクセスできません。
作者の意図は確かによく分からない。
public仮想デストラクタ&public継承でも大きな問題はないと思います。
>>759 それ用の名前空間に収められるかどうか。
つまりそのヘッダに、実装のためだけに必要な、
#include<sys/socket.h>
とか入ってて、よその名前空間やグローバルを撒き散らすなら、
.cppに移すべき。
766 :
765 :2008/09/02(火) 21:26:40
もちろん、自クラスの引数にTCHARがあるときに、 そのヘッダに#include<windows.h>があるのは良い、 実装だけでなく、インターフェイス部分で使っているため。
767 :
765 :2008/09/02(火) 21:28:19
#include<tchar.h>に訂正しとく。
>>737 通常は public な仮想デストラクタを持つ抽象クラスを public 継承すれば
問題ない。ただ、update メソッドが Subject 以外からも呼ばれ得ることを
危険視するなら、private 継承して this を Subject に渡すことで多態する
トリックが使える。こんな感じ(脳内コンパイル)。
class PrivateObserver : private Observer {
virtual void update(Subject* sub) {
// Subject 以外からは呼んで欲しくないメソッド
}
public:
PrivateObserver(Subject* sub) {
// private 継承している内部からは Observer として振舞える!!!
sub->AddObserver(this);
}
// ...
};
疑心暗鬼で眠れないあなたに。でもそのサンプルは謎だね。
>>762 可変長引数の仮引数は格上げされてしまうのですね。
char, short --> int
float --> double
あれ、でもそもそも %s 用な文字列ってどう処理しているのでしょう?
'\0' まで va_arg で進めるとかなんですかね?
んにゃ、たんなるconst char *として処理される。 まぁ、ポインタはvoid *に格上げされてしまうと解釈しておけば。
>>770-771 なるほど。じゃあ std::string str を渡そうと思ったら、
sprintf("%s", &str);
--
va_arg(ap, std::string*);
みたいな?確かに &str は嫌ですね。
773 :
723 :2008/09/02(火) 23:50:22
>>764 ,768さん
レスありがとうございます。
最初にお詫びしなければいけないのは、
>>737 で出来ると書いたコードですが、出来ませんでした。
検証中、一時的にpublic継承に書き換えた部分を戻すのを忘れててコンパイルが通った、
という初歩的なミスで、大変申し訳ないです。
実際には、
>>768 で書いていただいたような形で実装されており、
それを出来るだけ簡易に不要な部分を省いて、と思いつつ、
"クラス内部からの呼び出し"という条件が抜けたまま、public継承のままだったためにコンパイルが通ってしまいました。
大人しく、サンプルをいじらずにそのまま書くべきだったと、猛省しています。
ぐだぐだな質問にも関わらず、分かりやすい解説をしていただいて、すっきりしました。
今の自分には理解がいっぱいいっぱいで、public継承でもとりあえずは問題ないという事で安心しつつ、
とてもいい勉強になったと思っています。
お付き合いいただいてありがとうございました。
>>772 マジレスすると、std::string strを渡すのはprintf("%s", str.c_str())になるからやっぱりポインタ。
775 :
デフォルトの名無しさん :2008/09/03(水) 03:36:03
VS2005を使っています。 '型キャスト' : ポインタを 'BYTE *' から 'DWORD' へ切り詰めます。 とWarningが出るのですが、sizeofしてみると同じ4byteなのですが、 なぜ切り詰めますになるんでしょうか?
x64とIA-64ではBYTE *の大きさが8バイトになっている。 VC++2005では、64ビットで問題のある型変換も警告を出すオプションが標準で有効になっている。
そうそう、それでx64/IA-64では8バイト、32ビットx86では4バイトになる整数型が色々ある。 Windows APIならそういう型を使うようにいつの間にか変わっているはず。 自分で書いた部分ならまあ好きなの選べ。 size_t, ptrdiff_t, (u)intptr_t, [WL]PARAM, LRESULT (U)INT_PTR, (U)LONG_PTR, etc...
778 :
デフォルトの名無しさん :2008/09/03(水) 03:50:13
なるほど、じゃあこの警告がでるということは64ビットOSだとまずいって事なんですね。 ULONGLONGにしてみます。ありがとうございました。
779 :
デフォルトの名無しさん :2008/09/03(水) 03:51:30
あ、リロードせずにすみません・・・ size_tでもいいんですね。
>>774 えーと、実用的な例として string をもちだしたけど、
なんらかの構造体のポインタを渡すときは
func("%s", &struct);
va_arg(ap, struct*);
みたいな?ということをききたかった。
こんなかんじになってしまうんですかね?→ &
で、& がいやだったりするから、 boost::format % std::string % std::string みたいな形で引数とろうとしたのかなぁと。
>>778 ULONGLONGだと32ビットでも8バイトのままだからそっちで無駄になる。
>>778 本質的にはポインタ型で受けてないのが問題だと思う。
意図的にやってるならC++のキャストとコメントで意図を明示。
C99ならポインタを入れても安全な整数型(ptr_tだっけか)を使う方法もあるが、細かい状況が分からないと何が最適解かはわからない。
784 :
デフォルトの名無しさん :2008/09/03(水) 13:04:41
Atlas C++の使い方が詳しく載ってるサイトってありますか?
785 :
デフォルトの名無しさん :2008/09/03(水) 14:45:00
時代は64ビットマシンに移行しつつありますが、 その場合Cで扱うintも64ビットになりますか?
786 :
デフォルトの名無しさん :2008/09/03(水) 14:45:50
64ビットになります
>>785 OSがWindows7になるまで当分無理です
時代を先取りしたい人はLinuxでも使いましょう
今のところ64ビットCPU+64ビットOSでもintは32ビットのままが多い longは64ビットになったりならなかったりしてる ILP64 LP64 LLP64 でぐぐってみるといいかもしれない
789 :
デフォルトの名無しさん :2008/09/03(水) 15:30:06
>>788 ポインタだけ64ビットになって、intは32ビットのままだと困るなぁ。
WindowsのComboBoxとかListBoxとかのintパラメータに
ポインター入れて使ってるのに。
>>789 そういうのはいつの間にやら書き変わっていて大抵int型でなくなっている。
int32 とか int64 の類を使えばいいと思うよ
俺はdouble使う
Win32 APIのソースファイルの拡張子は.cか.cppのどっちを普通は使いますか。 ちなみにC言語でやっています。
なら.cでいいだろ
拡張子で Cコンパイラ C++コンパイラ 走らせるか区別してる系だと Cで記述するのなら .c で、C++で記述するのなら .cpp ときっちり対応づけしたほうが良い 呼び出し規約まわりで変なことになるかもしれないしね (stdcall と cdecl)
796 :
デフォルトの名無しさん :2008/09/03(水) 18:30:48
VC++6.0を使ってC言語の課題をやっているのですがディレクトリ作成で詰まりました。 .Netflameworkを使い、_chdirでディレクトリを作ろうと考えているのですが、このプログラムはUnix上では動かないのでしょうか?
VC++6で.NET Frameworkはおかしいだろ。 仮にそうだとしてもMonoでもWin32なネイティブコードこみのプログラムを実行できるとは思えない。 VCのディレクトリ作る関数と言えば_mkdirだけど、Unixだとmkdir。 そこらへんマクロとかでなんとかすればなんとかなる。
799 :
764 :2008/09/03(水) 19:38:58
>>773 あ、そういうことね。
768はスーパーエスパーさんだね。
768のコードは確かPrivate Interfaceパターンと呼ばれる。
***Scene.h*** // メッシュ LPD3DXMESH m_pMesh; // LPD3DXMeshインターフェイスへのポインタ LPD3DXBUFFER m_pD3DXMtrlBuffer; // メッシュのマテリアル情報を格納 DWORD m_numMtrl; // 属性情報の総数 ***Scene.cpp*** // デフォルトコンストラクタ Scene::Scene() : m_pMesh(0), m_pD3DXMtrlBuffer(0), m_numMtrl(0L); { } デフォルトコンストラクタにあるm_numMtrl(0L);のLってどういう意味ですか?
64bitOSになっても doubleは64bit、floatは32bitのまま?
だいたいそう思っていいと思う。 今時みんなIEEE 754準拠。
サンクス
GNUのリンカ(ld)に関する質問です。 class A { public: func_a(); func_b(); // 外部のライブラリが必要な関数 } このようなクラスがあり、とあるプログラムでA::func_a()のみを使いたいのですが、 このような場合でもfunc_b()が必要としているライブラリをリンクする必要があるのでしょうか? (ちなみにfunc_a()はfunc_b()に依存していません。また両関数ともstaticではありません。) とくにオプションをつけなければ undefined reference to (外部ライブラリの関数) というエラーが 出てリンクできないのですが、不必要な関数をリンクから外すオプションがあれば教えてください。
>>805 不要なコードを削除するオプションがあったかどうかは覚えてないんだ
けど、A::func_a()の実装とA::func_b()の実装を別のオブジェクトファ
イルにして、ライブラリに突っ込んでおけばいと思う。
807 :
デフォルトの名無しさん :2008/09/04(木) 21:54:58
DLLを、LIBに変換してDLLを不要に出来ますか?
たぶんWindowsだろうが環境を書けよ
>>807 DLLをLIBに変換しても、不要にはならないと思いますが?
810 :
デフォルトの名無しさん :2008/09/04(木) 22:37:03
中身のあるLIBにできるかです。 WindowsXPです。
C++とvisualC++は何が違うんですか?
そのDLLのソースを持ってるならLIBに作り直しましょう 持ってないなら犯罪なのでやめましょう
Windowsでlibつうと普通インポートライブラリのはなしになってしまうな
>>805 たぶん、だけど
一般的に、メンバ関数と普通の(Cの)関数との違いは、
単に暗黙の引数thisを持つ事と、名前をマングリングしている事だけ。
で、libのラベルに関係するのは後者だけど
これは普通のCの関数と同様、objさえ別であれば使わないものはリンクしないようにできるはず。
ただし。
仮想関数は、vtblに載せる必要上、普通は全部リンクされるはず。
(もしかしたら賢いコンパイラ/リンカもあるかもしれないけど)
「vtblの何番目のエントリは呼び出されてない」なんて情報、
普通はobjに含まれることはないだろうから。
>>811 C++ → 言語の名前
Visual C++ → MSが開発・販売している開発ソフトの名前
816 :
デフォルトの名無しさん :2008/09/05(金) 00:40:20
与えられた任意の整数の階乗を求めるプログラムを書いたのですが、筆算のやり方で素直に乗算を計算しているため、 13500! を求めるのに48秒ほどかかってしまいます。 どうすれば、乗算の結果を素早く得られるのでしょうか? どなたか教えて下さい。よろしくお願いします。
スターリンの公式使っても近似値しか出んよ
818 :
デフォルトの名無しさん :2008/09/05(金) 00:47:31
>>816 適当に作った同一ソースにて
C3 600MHz で 38秒
Core2Duo 2.66GHz で 2秒
環境が分からないとなんともいえない
scheme(gauche)で書いてもathlon64 3000+で2秒かからんかった
822 :
デフォルトの名無しさん :2008/09/05(金) 01:50:45
Acrobat9.0 ProfessionalのプラグインをAcrobat9.0 SDK + VS2005 Pro + Acro9PIWiz (Acro9PIWiz:Acrobat9向けプラグインのプロジェクトテンプレート作成ツール。Acrobat9.0 SDKの中に入っている) という環境で作成しています。 Acro9PIWizはデバッグ構成のテンプレートを作成するのですが、VisualStudioでリリース構成に 変更しビルドするとプラグイン自体は生成されても、Acrobat上で動作しません。 リリース構成でビルド、動作させるために必要な設定項目等をご存知でしたら教えてください。
a.hに記述されているクラスAは、メンバ変数としてb.hのクラスBのインスタンスを持っています。 この状態で、B内でもA型のインスタンスを保持しておきたいとしたら、どうすれば良いのでしょうか? a.hはすでにb.hをインクルードしてしまっていますので、b.hはa.hをインクルードできず、 そのままではB側で、Aは定義されていない識別子とされてしまいます。
class Y; こういうのを前に書いとけばよかろう たぶん
>824 関数のプロトタイプ宣言と同じことができるわけですね! ありがとうございます
>>816 それって何桁求めているの?
つーか、多倍長演算は自作? それとも既存ライブラリ?
long double精度程度でいいならc99で標準になったtgamma()で求められるけど。
827 :
デフォルトの名無しさん :2008/09/05(金) 08:27:52
自作クラスを使ってるんだけど、13500!(49899桁)を求めるのに48秒もかかるっておかしいですね。 ちなみに、基数は10です。 プログラミング初心者なので、色々と無駄なコードが入ってるのは確かだと思うけど、 それにしても遅いですね・・・
828 :
デフォルトの名無しさん :2008/09/05(金) 08:35:46
829 :
デフォルトの名無しさん :2008/09/05(金) 09:24:32
初心者の質問です。 関数がint型を参照で返したとき、++演算出来ますか?
#include <stdio.h> #include <gmp.h> int main(int argc, char *argv[]) { mpz_t n; mpz_init_set_ui(n , 0); mpz_fac_ui(n, 13500); mpz_out_str(stdout, 10, n); return 0; } そのものズバリですね あと速すぎです、多分一生頑張ってもこの速度には追い付けないわ
831 :
デフォルトの名無しさん :2008/09/05(金) 09:27:54
自己解決しました #include <stdio.h> int &f(int &n){ n=n+10; return n; } main(){ int n=1; f(n)++; printf("%d\n",n); }
832 :
デフォルトの名無しさん :2008/09/05(金) 09:42:28
一つのクラスが何メモリ使っているか調べる方法ありませんか?
ありません
まぁまてw
>>832 一つのインスタンス分のサイズ?
それとも実行時の該当クラスの全インスタンス分のサイズ?
835 :
デフォルトの名無しさん :2008/09/05(金) 10:16:56
クラスとして定義された変数のサイズです おねがいします
コンストラクタ、デストラクタで 静的変数相手に±sizeof(*this)すれば良くね? あ、継承されると話がややこしくなるか。
837 :
デフォルトの名無しさん :2008/09/05(金) 10:22:12
ポインタで繋ぐ多分木とかのクラスも求まりますか?
840 :
デフォルトの名無しさん :2008/09/05(金) 10:47:04
mapのメモリの開放方法教えて下さい。 swapで出来ないです。 main(){ int n,m; map<unsigned int, unsigned int> q; for(m=0;m<1000000;m++)q[m]=0; cout<<"input key...\n";getchar(); q.swap(map<unsigned int, unsigned int>()); getchar(); return 0;}
>>840 clear() じゃダメなのか?
swap() が使いたいなら
map<unsigned int, unsigned int>().swap(q)
じゃね?
842 :
デフォルトの名無しさん :2008/09/05(金) 10:55:21
すべて解放してません。 clear() map<unsigned int, unsigned int>().swap(q) q.swap(map<unsigned int, unsigned int>())
解放してるかどうかどうやって調べてるの?
844 :
デフォルトの名無しさん :2008/09/05(金) 11:00:26
タスクマネージャで、プログラム実行中と終了後を比べます。 25Mほどかわります。
あーそりゃいけないな プロセスがシステムにメモリをいつ返すかは最小ブロック単位があって あまり小さいのは返さないよ システムからメモリ持ってきたり取ってきたりするのは大きなオーバー ヘッドがかかるから
それよりも他のmapかvectorか何でもいいけどサイズを肥大させて std::bad_allocを投げるまでの余裕を比較した方がいいよ
847 :
デフォルトの名無しさん :2008/09/05(金) 11:34:14
実際にメモリが解放出来るやり方おしえてください
C/C++からやってるならヒープ領域は触らぬ神に祟り無しだ
横レスですが、ヒープ領域には触れないのが主流なやり方なんですか?
>>847 mallocやデフォルトのnewを使わずに、
環境依存のシステムコールで、直接メモリを確保・開放すれば良い。
windowsならHeapAlloc。
>>851 HeapAllocは
>>845 の処理を代行してくれるAPIだから、
直接GlobalAlloc使わないと
>>851 VCのmalloc/newはHeapAllocに丸投げしてる
>>852 VirtualAllocをお使いください
>>853 見てきた。
前はmalloc内でノード管理してた気がするけど、
今ほんと丸投げなんだな。
NTカーネルなら確かにOS任せで十分か。
855 :
デフォルトの名無しさん :2008/09/05(金) 12:12:56
mapの機能が使いたい場合はどうすれば良いですか?
話題がWin32のアセンブラの領域に入って来てるのか。 これ以上はWin32スレに行った方がいいと思うよ。 だいたいOSが平衡二分木なんて高級な機能を提供 しているのは見た事がない。
Win32のアセンブラって何?
アセンブラは取り消しだ C/C++からWin32を扱うと読み替えてくれ
APIの実装なんて話してるスレはあるのか?
ここ行っても何も もう話終わってるけどなw
>851-854 ありがとうございます newを使う意味は薄いのですね
しかしC/C++のランタイムシステムが管理しているヒープ領域に 直接VirtualAllocを適用すると、どう考えてもピープ領域が 破壊されて辻褄が合わなくなってエラー吐くだけだと思うが。 それでもどうしてもやりたいのならお好きなようにとしか言えない。
>>860 そこはAPIの仕様、使い方のスレだろ
mallocやカーネルのメモリマネージャの実装の話とは別
>>851 もwinを例に出しただけだしな
>>863 ちょっと待て、逆だ
866 :
デフォルトの名無しさん :2008/09/05(金) 12:34:17
WindowXPだと良いSTLのアロケータありますか?
boost::pool 実測してみたけどあまり大差ないけどな
>>844 何の数字見てるの?「かわる」って増えるの?減るの?
プログラム実行中に 25M 使ってた分がプログラム終了後に返ってくるってことなら、
あたりまえな感じなんだけど。
プログラム終了後の数値をどうこうしたいなら、 malloc だろうが HeapAlloc だろうが
VirtualAlloc だろうが、どうにもならないよ。
>>865 >>853 は多分、GlobalAlloc/GlobalLockが既に古いAPIで
VirtualAlloc/VirtualLockに
置き換えられたってことを言ってるだけで、
HeapAllocの代わりにって意味じゃないと思うぞ。
870 :
869 :2008/09/05(金) 12:47:12
871 :
デフォルトの名無しさん :2008/09/05(金) 12:47:54
はじめまして C++を仕事で使ってる人に質問なんですが マイクロソフトで無料でインストールできるコンパイラあるじゃないですか? 名前なんだったかな? ビジュアルベーシックみたいな名前ですが 仕事でもあーゆー類いの物をつかうんですか?
使う VS Expressは商用利用可なので
>>871 そうだよ。
他にも色々ツール買うと年間云十万するけど
874 :
デフォルトの名無しさん :2008/09/05(金) 13:07:00
MSはOSを売るための宣伝みたいにして無償で提供するんでしょ。ただでもOSの利用者がふえれば元が取れる。 でもMS以外の会社だと無償はきびしいだろうとおもう。
875 :
デフォルトの名無しさん :2008/09/05(金) 13:12:08
そーなんですか! みなさんご丁寧にありがとうございます perlとphpを少しだけやるんですが テキストエディタに書いていくじゃないですか? あーゆーのイメージしてたので みなさん どれぐらいのメモリのパソコン使ってらっしゃるんですか?
2G
Visual C++ はテキストエディタに書いていくイメージそのままだよ Visual BASIC と同じだと思ったら大間違い メモリは1G、でも最近不足ぎみ 4G欲しいと思ってる
878 :
デフォルトの名無しさん :2008/09/05(金) 13:25:49
最近のVC++はC#みたいな機能がついてるぞ
879 :
デフォルトの名無しさん :2008/09/05(金) 13:26:36
NETの機能をGUIで貼り付けるやつ
880 :
デフォルトの名無しさん :2008/09/05(金) 13:42:48
中国語や韓国語やフランス語にも、EUC,JIS,SJIS,UTFのよなコード体系が複数ありますか? あと世界標準のコードに変換するメジャーなライブラリはありますか?
PHPとCは似てると思うよ 同じような関数もいっぱいあるし 基本的にエディタで書いていくのは同じだね コンパイラで実行ファイル作成という処理が追加されるだけ フォームアプリだと確かにVisualって感じはするな
>>880 少なくとも現地で従来用いられてきたものが少なくとも1つ、
それに加えUTF系が加わると言えば、どこも複数だな。
文字コード変換のライブラリは決定打がない気がするけど、
ICUが1番、Posixのiconv、IEのIMultiLanguage (mlang)が結構なんでもいける感じ。
884 :
デフォルトの名無しさん :2008/09/05(金) 13:56:41
クアドコアのCPU使ってるんですが、コアの1つが100%になります。 どうやったら4つのコアとも使ってプログラムを実行できるんですか?
MinGW developer オヌヌメ VC++6.0の模倣品 今となってはこれ選ぶ意義は皆無ですか、そうですか(´・ω・`)
>>884 マルチスレッド
本気で4コア生かすのは素人にゃ無理
888 :
デフォルトの名無しさん :2008/09/05(金) 14:05:30
889 :
デフォルトの名無しさん :2008/09/05(金) 14:06:29
>>884 intel c++コンパイラで良いのでは
890 :
デフォルトの名無しさん :2008/09/05(金) 14:21:18
>>887 やっぱり無理ですか・・・
>>884 今使ってます。
ちょっと調べてコード書き直してみます。
891 :
デフォルトの名無しさん :2008/09/05(金) 15:27:49
すみません。文字コードを自動判別できるソフトはマイクロソフトのIMultiLanguageしかないんですか? 主要な世界各国言語の場合です。 それとも各種判定ルーチンを組み合わせたライブラリなんかありますか?
892 :
デフォルトの名無しさん :2008/09/05(金) 15:31:34
世界各国言語をその現地の人に提出してもらって、ベイズ理論で特徴を求めておけば簡単に作れそうな気はします。無いですか?
893 :
デフォルトの名無しさん :2008/09/05(金) 15:46:42
894 :
デフォルトの名無しさん :2008/09/05(金) 16:08:02
C++でDLLを作っているのですが、 DLLからVCを立ち上げ、コンパイルして実行をやろうとしています。 コンパイルして実行まではできました。 ですが、実行が終わった時のイベントを取得することができません。 でWaitForBuild()メソッドを使って取得を行おうとすると、 何故か取得をすることができません。 WaitForBuild以外にも実行終了のイベントを受け取る方法はあるのでしょうか? 教えてください。 環境は Visual Studio 2005 Standardです。
895 :
894 :2008/09/05(金) 16:13:58
すいません。間違えました。 コンパイル終了のイベントが取得できていません。 の間違いでした。
>823です。 お答えいただいてから、試行錯誤してみたのですが、 class B; と先行宣言してAで保持すると、AがBの構造を把握できないため、 B内のメンバ関数にアクセスできませんでした。これを、相互にメソッドを呼び出したいとすると、 一方のヘッダファイルなりソースファイルに関数定義の記述を移動するしかないのでしょうか? できれば、異なるクラスのメンバ関数は分けて記述したいのですが…
> (注:すべての方が1週間でマスターできることを保証するものではありません)
>>897 そんなもん個人差だ
くだらん質問すんなアホ
a.hとa.cみたいに宣言と定義分けたら?
a.h: class A{ class B*b;void foo();} b.h: class B{ class A*a;void foo();} a.cpp#include <a.h> <b.h> void A::foo(){ b->foo(); }; b.cpp#include <a.h> <b.h> void B::foo(){ a->foo(); }; みたいな話。
903 :
デフォルトの名無しさん :2008/09/05(金) 17:39:00
縦固定、横可変2次元配列の作り方教えて下さい。 ここまで出来たんですけど・・・p[0]などに配列を追加するのがわかりません。 vector<vector<int>*> p(N,NULL); Nは十分に大きく、使わない番号も多くあり、vector<vector<int>>にするとメモリを圧迫してしまいます。
904 :
デフォルトの名無しさん :2008/09/05(金) 17:41:01
C言語の入門書を買ったばかりの初心者です。(OSはVista) 足し算をするだけのプログラムを作って、試しに実行してみようかと思っていますが、PC上で実行するにはどうしたらいいでしょうか? いくつかのフリーコンパイラを調べてみたのですが、以下の理由でできませんでした。 LSIC-86試食版(配布中止になっていた) C++ Compiler 5.5/Turbo Debugger(ダウンロードできなかった) lcc-win32(使用方法が分からなかった) どなたかお願いします
905 :
デフォルトの名無しさん :2008/09/05(金) 17:41:49
vector< vector<int> > p(N); では初期に550M使います。 vector< vector<int>*> p(N); は55Mくらいですみます。
>>904 フリーでもまだまだある。Visual C++ 2008 ExpressとかCygwinとかMinGWとか。
907 :
デフォルトの名無しさん :2008/09/05(金) 17:49:19
これだと最後の行でエラー出ます。どうしたらいいでしょうか? typedef vector<int> vec; vector<vec*> p(N); p[0] = new vec; p[0]->resize(10,3); cout<<p[0][9]<<endl;
908 :
デフォルトの名無しさん :2008/09/05(金) 17:50:51
自己解決しました。 cout<<(*p[0])[9]<<endl; でした。
909 :
904 :2008/09/05(金) 18:34:02
>>906 Gygwinをダウンロードしてみます。ありがとうございました!
>>909 初心者ならCygwinはやめとけ……
Visual C++ ExpressかDegital Marsを薦める
>>909 ギグウィンなんてねぇよw
>>910 の言う通りVC++Expressにしておいた方が良い
912 :
904 :2008/09/05(金) 19:36:36
>>910-911 まさに暗礁に乗り上げていたところです…
了解しました、そちらで試してみます
例外のクラスの中で std::stringとかstd::vector使ってもいいですか?
違法
<stdexcept>否定する気ですか runtime_errorとかみんなコンストラクタでstring引数に取っていますよ。
例外が無限ループするとかなんとか
// 4つの頂点からなら頂点バッファを作る if(FAILED(pD3DDevice->CreateVertexBuffer(4*sizeof(MY_VERTEX), D3DUSAGE_WRITEONLY, MY_VERTEX, D3DPOOL_MANAGED, &m_pVB, NULL))) { return E_FAIL; } \001\scene.cpp(45) : error C2275: 'Scene::MY_VERTEX' : この型は演算子として使用できません エラーがでます どうすればいいでしょうか。。。
918 :
デフォルトの名無しさん :2008/09/05(金) 22:07:32
DarkGDKにする
吊るしかないんじゃね?
すいません解決しました 第三引数にFVFを設定していませんでした
>>920 トンマ ドベ アンポンタン ダボ アホ
ここは酷いインターネットですね
template<class T> class HogeException : T { //なになに }; こんなクラスで テンプレート引数が何であれ、HogeExceptionなら 一箇所のcatchで受信する方法はないですか?
catch (...) で全部ひっくるめて受け取る以外にない
class Foo {}; template<class T> class HogeException : T, public Foo { //なになに }; catch(Foo& foo) { ... } というので、どう
そのそもテンプレートパラメータから派生するのは規格で認められてないんじゃなかったっけ?
んなことねぇべ
動くならいいんじゃないの
>902 ありがとうございます! 単純なことだったんですね
>900 はい。書いてるうちにグチャグチャになってしまって… ありがとうございます
>
>>926 規格ではなく法律で禁じられています(嘘
規格でNGならコンパイルできないのでは
そんなことはない
関数の引数の型にenumを指定すると、 そのenumに定義している列挙値しか指定できなくなるので、 保守しやすいかなと思ったんですが、これはどの環境でも "unsigned int?" になるんでしょうか?
>>934 どの環境であってもならない、なぜなら
そもそもenumには負の整数も入られるから
Cで組まれたシステムにC++で開発されたサブ機能をマージすることになったんだけど なんかプロトタイプ宣言でエラーになります。 で、困ったことにOSがVxWORKでコンパイルエラーがシンタックスエラーw 具体的には short func(CInput &in, COutput &out); というふうに宣言されてて、どうも&が気に入らないようです。 で質問なのですが、C言語関数のプロトタイプ宣言が書かれているヘッダーファイルに C++のプロトタイプ宣言を混在することはかのうでしょうか? (コンパイラはC++に対応しています)
extern "C"
extern Cで参照型も無問題になるんですかね 明日休日出勤なので試してみます;; レスありがとう
ならないだろ。
無問題になるっつーか、寧ろ顕在化するなw
あと、その関数を使う側もC++でコンパイルしないとまた&でエラーになるだろ。 x86のWindows/LinuxとかだとCでは単にポインタにすればいいけど、 VxWORKでもそれが可能かどうかは知らない。 C++でポインタを引数に取るラッパを作って、 Cではそっちだけを使うようにするってのが(規格合致という点からは)安全。
その辺を突き詰めて考えていくといつのまにかCOMやCORBAや.NETの話に
そのCOMでは、こんなことをやっている。 #ifdef __cplusplus typedef IID& REFIID #else typedef IID* REFIID #endif
popen()とpclose()を使いたいんです ググったりmanで引いたりしたところ、どちらもstdio.hにあるっぽいんですが popen()は暗黙の宣言と言われてしまい、(ヘッダにはないけどリンクはしてるってことかな?) pclose()は見つからず、コンパイルできません (まぁpclose()だけ消せば動くことは動くんですが) popen()とpclose()で読み込むべきヘッダの別パターン知りませんか? もしくは別な勘違いをしているのでしょうか? 環境は コンフィグオプション: ../configure --prefix=/usr --mandir=/usr/share/man --info dir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable -java-awt=gtk --host=i386-redhat-linux スレッドモデル: posix gcc バージョン 3.4.6 20060404 (Red Hat 3.4.6-3) といった感じで OSはCentOSです
popen()の方は大丈夫でしたどうもすいません
Visual C++ 2008 Express Edition を使っています。 Cの勉強中です。 サイズが120byte有る構造体を100000個並べた配列が有ります。 stract abc{ …… }; stract abc b[100000]; これをバイナリで以下のように書き込むと、26個目までしか書き出されません(もしくは読み込まれません)。 FILE *fp; fp=fopen("ファイル名","wb+"); fwrite(b,sizeof(abc),1,fp); fclose(fp); どのように対策すれば良いのでしょうか?
948 :
デフォルトの名無しさん :2008/09/06(土) 04:44:50
すみません、sizeof(b)でした。
949 :
デフォルトの名無しさん :2008/09/06(土) 04:45:44
fwiteがいちどにたくさんかきこめないんでしょ 一つずつか、1M程度ずつるーぷすればいいのでは
950 :
デフォルトの名無しさん :2008/09/06(土) 04:53:04
ありがとうございます。 ループしたものを作ってみたのですが、 同じ問題が発生しました。 具体的には以下のようなプログラムです。 改善点は有りますか? stract abc{ …… }; stract abc b[100000]; FILE *fp; fp=fopen("ファイル名","wb+"); for(int i;i<100000;i++){ fwrite(b[i],sizeof(abc),1,fp); } fclose(fp);
分割しろよwwww
952 :
デフォルトの名無しさん :2008/09/06(土) 04:57:20
……分…割…?
その前に誰かstractに突っ込めよ
>>947 最初のはたぶんfwrite()の第2引数の方の範囲を超えて整数オーバーフローでもしているか、書き込み可能最大Byteを超えているんだろう。
適度に分割したほうがいいと思うけど、ファイルアクセスは重たい処理だから、10個単位とか。
当然知って使っているとは思うけど、構造体はコンパイラによってCPUが扱いやすいように勝手に詰め物されるから(たとえば4Byteの倍数とかに)。
>>950 >>struct abc b[100000];
>>for(int i;i<100000;i++){
>>fwrite(b[i],sizeof(abc),1,fp);
>>}
for ( int i = 0; i < 100000; ++i ) {
fwrite(&b[i], sizeof(struct abc), 1, fp);
}
とか
for (int i = 0; i < 10000; i += 10 ) {
fwrite(b+i, sizeof(struct abc), 10, fp);
}
とかな
あとファイルが正常にオープンできたかちゃんとチェックしないとだめ
fwrite()の戻り値チェックとかC++でやっているみたいだからstruct abcがメンバ関数持ってたりな(読み込み時に死亡フラグがたつ)
まぁ、ネタとは思うけど
>適度に分割したほうがいいと思うけど、ファイルアクセスは重たい処理だから、10個単位とか。 fwrite()もバッファリングされるからトータルサイズがオーバーしていなければ分割する必要が無いし、 分割する場合も10分割程度でいい。10個単位で10000回ループなんて阿呆すぎる。
956 :
デフォルトの名無しさん :2008/09/06(土) 08:44:10
test.exe > log.txt というコマンドラインで、ファイルではなくてメモリに出力を格納するにはどうしたらいいですか?
958 :
デフォルトの名無しさん :2008/09/06(土) 08:46:59
よくわからないのでもう少しおしえてください
ググレカスといいたいところだが、メモリに書き出してその後どうするんだ?
960 :
デフォルトの名無しさん :2008/09/06(土) 08:51:38
出力内容に応じて処理するんです。 ファイルに書き出して読み込めばいいんですけど かなり繰り返すため、そのロスをへらしたいです。
マルチプロセスでググッたらいいと思うよ
962 :
ネットより本 :2008/09/06(土) 09:25:18
テラパッドにたどり着くまでに長い道のり・・・ いやあ、本によっては、ダウンロードのしかたまでくわしくのっているのだ。 導きが大切なのだ。
その長い道のりの先にあるのが大いなる思い違いだとは……
>>958 dir | grep txt
見たいな感じかな
data.txtの中身が 111111 だったとして,これを 221111 と書き換えるにはどうすればいいでしょうか。 つまり,最初の2文字だけを2に書き換えて, それ以降は最初のデータをそのまま残しておきたいのです。 FILE *fp; char newdata[2] = {2, 2}; fp = fopen("data.txt", "wb"); fwrite(newdata, sizeof(char), 2, fp); fclose(fp); とすると,結果は 22 となってしまい,最初のデータが完全に消えてしまいます。。
"rb+"
>>966 ああ完璧にいけましたありがとうございます!
うちは成果主義だから R&Dプログラマーのできるやつは50万くらいもらってるなぁ
Repeat and Destroy ?
トップでそれってしょぼくね?
1日50万円じゃね?
そろそろ次スレだ
いやまだ早い
974 :
デフォルトの名無しさん :2008/09/06(土) 15:17:55
ある配列の先頭番地 p と、個数 s が与えられるとき、 コピーコンストラクタを使ってこれをコピーしたい。 コンストラクタ+代入演算子は使えない。 結果は配列の先頭番地と個数でほしい。 メモリ上で連続していないとまずい。 どうやったらいい?
わかんね
std::vector<T>(p, p+s)
X *q = static_cast<X*>(malloc(sizeof(X)*s)); while(s--) new(q++) X(*p++);
試していないけど多分こんな感じ。delete[]で解放できるように作るのは無理だと思ったからmalloc使っている。 #include <new> #include <memory> #include <cstdlib> template<typename T> std::pair<T*, std::size_t> array_copy(T* src, std::size_t n) { if (T* p = static_cast<T*>(std::malloc(sizeof (T) * n))) { try { std::uninitialized_copy(src, src + n, p); } catch(...) { free(p); throw; } return std::make_pair(p, n); } throw std::bad_alloc(); } これを解放するにはこうする。Tには型名を入れて。 for (std::size_t i = 0; i < n; ++i) p.first[i].~T(); std::free(p.first);
そろそろ次スレだ
981 :
デフォルトの名無しさん :2008/09/06(土) 20:25:16
質問なんですが、関数templateのDLL化って可能なんでしょうか。 オーバーライド関数のように、名前修飾の問題とかあって、ダメなんでしょうか。
無理です。.hppでソースごと提供して下さい。
>>981 ソースなしにどうやってインスタンス化するんだよ?
984 :
デフォルトの名無しさん :2008/09/06(土) 20:32:01
ありゃまっ・・・。
>>982 ありがとう、ございます。
985 :
デフォルトの名無しさん :2008/09/06(土) 20:33:21
おお、ソイソース
987 :
デフォルトの名無しさん :2008/09/06(土) 20:34:32
>>986 しっ、しもた・・・。
醤油も使えないのか・・・。
988 :
デフォルトの名無しさん :2008/09/06(土) 20:53:12
Visual C++ 2008 Express Editionを使ってC++でプログラミングしてます。 Windowsフォームアプリケーションテンプレートの作成をして、 タイマーのTickイベントの中でWindowsAPIを使いたいのですが、 WindowsAPIはともかく #include <windows.h>とコールバック関数はどこに書けばよいのでしょうか?
Visual C++ 2008 Express Editionを使ってるんですけど、リソースファイルを追加しようとしても項目が見つかりません。 また、ほかの項目を選んでそれを強制的に.rcにすると「リソースの編集は Visual C++ Express SKU ではサポートされていません。」となってしまいます。 猫でもわかるWindowsプログラミングという本では、リソースファイルを追加する項目があるんですけどどういうことなんでしょうか。
>>988 <windows.h>のインクルードはstdafx.hにまず1つと
あとそれ以外のヘッダに必要に応じて。
コールバック関数は普通のC++と同じで基本.cppファイル。
ただし、メンバ関数ならクラス定義内に書いてもよし。
>>990 Expressにはリソースエディタがついていない。
無理やり追加はできるはずだが、テキストファイルとしての編集しかできない。
>>990 言われたとおり
express editionにリソース編集機能は無い
外部のリソースエディタを使え
じゃあ猫の本のは一体…
よく見たら猫の本の後ろのほうにも注意が書いてありました。
995 :
デフォルトの名無しさん :2008/09/06(土) 21:53:19
WINDOWのログイン名とパスワードってC++でとれないですかねー
日本語でおk
998 :
デフォルトの名無しさん :2008/09/06(土) 22:45:58
l^ヽ'"'"~/^i、..、 ..、、 ヾ ∧__∧``;: ミ ´ ∀ ` (´・ω・)..:;:; チュンチュンの時間です ッ _ (つ|⌒|⌒|..;ミ みなさんそろそろ寝ましょう (´彡,. (,,_, ヽ(~^),(^~).ノ "'"'゙''""''''゙""´
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。