1 名前:デフォルトの名無しさん [2010/03/05(金) 16:51:13 ] エスケープシーケンスやWin32APIなどの環境依存なものでもOK。 ただしその場合、質問者は必ず環境を書きましょう。 ※sage禁止です(と代々スレに書いてありますが自己判断で)。 【前スレ】 【初心者歓迎】C/C++室 Ver.71【環境依存OK】 pc12.2ch.net/test/read.cgi/tech/1264774545/ 【アップローダー】(質問が長い時はココ使うと便利) kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm codepad.org/ (コンパイルもできるし出力結果も得られるのでお勧め) ◆ソースのインデントについて 半角空白やTABでのインデントはスレに貼ると無くなります。 そのため、アップローダーに上げるのも手ですが直接貼る場合は、 全角空白か に置換すると見栄えだけはよくなります。
239 名前:デフォルトの名無しさん mailto:sage [2010/03/28(日) 01:47:39 ] すみません.環境依存の質問なのですが longやintのサイズが64bitや32bitで変わる例はよく見るのですが shortやlong longが変わる実例ってあるのでしょうか? よろしくお願いします
240 名前:デフォルトの名無しさん mailto:sage [2010/03/28(日) 02:21:23 ] >>239 short は -32,767 〜 +32,767 を表現できることが保証されている → 16bit 以上 long long は -9,223,372,036,854,775,807 〜 +9,223,372,036,854,775,807 を表現できることが保証されている → 64bit 以上 それ以外は決められていないから変わるかもしれない 実例は…… short が4バイトなコンパイラを自分で作ればいい
241 名前:デフォルトの名無しさん mailto:sage [2010/03/28(日) 03:30:55 ] >>203 コンストラクタ・コピーコンストラクタ・代入演算子を定義したクラスで試してみた。 少なくともcodepadのgccは、デストラクタの有無のみ見てるみたい。 ttp://codepad.org/VXfU6shz
242 名前:デフォルトの名無しさん mailto:sage [2010/03/28(日) 03:43:49 ] >>239 charのサイズが9ビットとか32ビットという環境は実在するので、たぶん shortやlong longもそれなりに変なサイズになると思う。 一般的なWindows/Linux/Macの開発環境では、64ビットターゲットであろ うと 16bit short、64bit long long しか見たことないね。
243 名前:デフォルトの名無しさん mailto:sage [2010/03/28(日) 04:29:53 ] >>240 >>242 これは困りました・・・ ともあれ参考になりました ありがとうございます.
244 名前:デフォルトの名無しさん mailto:sage [2010/03/28(日) 08:30:09 ] 困る・・・のか? stdint.h の int16_t, int64_t を使えばいいという話ではないのか
245 名前:デフォルトの名無しさん [2010/03/28(日) 15:29:14 ] C++でのメモリ確保について教えて下さい。 要素数が変動する配列の塊の為の領域を膨大な数確保するとします。 データ1[70] データ2[1] データ3[36] データ4[12] ・ ・ ・ そしてそれらを管理するアドレスの配列を作ります。 データ1の開始アドレス データ2の開始アドレス データ3の開始アドレス データ4の開始アドレス ・ ・ ・ このとき、領域確保はひとつずつnewとかで確保したほうがいいのでしょうか? それとも巨大な領域を自分で確保し、その中に隙間を詰めるようにデータを詰め込んでいく 管理クラスを自作するほうがいいのでしょうか? 前者のほうが簡単そうではあるんですが、C++の動作の知識があまりなくて以下の不安があります。 ・膨大な数こまごまと領域確保することで何らかの処理負荷が発生しないか? ・もしも適当に確保出来る空き領域見つけて確保する場合、隙間がまばらになって メモリが断片化され、本来可能な確保量よりも確保出来る容量が少なくなってしまわないか? データ領域は数万から最悪数百万個単位で確保し、頻繁に消したり、追加するとします。 宜しくお願いします。
246 名前:245 [2010/03/28(日) 15:32:43 ] なお、vectorなどの存在は知っているのですが、その場合、準備している容量を超えた場合、 領域の再確保によってデータのアドレスが変わってしまいます。 プログラムはデータのアドレスを記憶して情報をやり取りする部分が多いのでvectorは考えていません。
247 名前:デフォルトの名無しさん mailto:sage [2010/03/28(日) 15:38:42 ] >>245 データは単独でnewすればかまわない。よっぽど多い場合はプールなどを使うが、たいていの場合はnewで事足りる。 そこへのポインタをvectorに保持すればいい。ポインタだけを保持するならベクターの伸張じの問題は関係なくなる。 vectorに直接ポインタを入れるとdeleteが面倒なのでshared_ptrを使うのが楽だ。
248 名前:デフォルトの名無しさん mailto:sage [2010/03/28(日) 15:43:19 ] int main() { int *p = new int; cout << p << endl; p = new int; cout << p << endl; delete p; return 0; } は間違ってますか? 最初のpはリークになる?
249 名前:デフォルトの名無しさん mailto:sage [2010/03/28(日) 15:46:00 ] >>248 リークする。 2回newでdelete1回だから確実。
250 名前:デフォルトの名無しさん mailto:sage [2010/03/28(日) 15:49:13 ] >>245 データの要素数に関する統計情報がないことには、 newで十分としか言えない。 ただ、要素数より余分に確保して、決まったサイズの倍数に揃えることで、 一般的には断片化を減らすことはできると思う。
251 名前:デフォルトの名無しさん mailto:sage [2010/03/28(日) 15:49:15 ] >>249 即レスありがとうございます。 同じ変数は使いまわししないのが基本ですか?
252 名前:デフォルトの名無しさん mailto:sage [2010/03/28(日) 15:58:57 ] >>251 うん。 使いまわしても一切メリットがないばかりか、読みにくいし最適化の妨害になる。
253 名前:245 [2010/03/28(日) 16:10:23 ] >>247 有難うございます。ただやはり不安なのは、OSから見てプログラムがメモリのここからここまでを使用したいと予約(newで確保)すると思うのですが、 その予約した領域のデータ(ここからここまで)を保持しないといけないと思うのですが、最悪数百万個のデータを確保する場合、 前者では開始(アドレス+終了アドレス)*数百万個分のメモリを占有してしまい、後者だと(開始アドレス+終了アドレス)の一個のみで済み 前者だとそれだけでメガ単位のメモリ消費してしまわないのでしょうか? >>250 有難うございます。なるほど、例えば要素数を10区切りで判定してその区切りで確保することにより、 一度開放されて歯抜けになった領域に新しいデータがすっぽりはまる可能性が高まるということですね? 参考にします。
254 名前:デフォルトの名無しさん mailto:sage [2010/03/28(日) 16:17:03 ] >>253 ヒープの管理領域のこと?100万でも10数メガだしwindowsなら問題ないだろう。 それよりもヒープの最大サイズを気にしたほうが良くないかな。
255 名前:デフォルトの名無しさん mailto:sage [2010/03/28(日) 16:22:51 ] >>253 先ずは愚直に作ってみたら? それを動かしてみれば問題点もより判り易いだろうしデバッガで追うなどして知見を得られるチャンスも増える。 始めから高性能を目指したら、デバッグの段階で二進も三進もいかなくなるぞ。
256 名前:デフォルトの名無しさん mailto:sage [2010/03/28(日) 16:34:33 ] データは後ろに追加するだけなわけ? それならdequeを使うといいよ。 dequeは後ろに追加するだけならメモリの再配置は起こらない。
257 名前:245 [2010/03/28(日) 16:48:23 ] >>256 有難うございます。 データ群の中間から抜いたりも行いますが、別の箇所では使えるかも知れません。 >>254 >>255 有難うございます。 実験的というか自分のプログラム技術の向上の為のトレーニングを兼ねて以下の仕様にしようとおもいます。 ・メモリプールで大きな領域を確保する。 この領域を超える場合は段階的に追加確保する。 ・要素数は5個、10個、15個などの単位で確保する。 これは開放により歯抜けになったところにすっぽりはまりやすくするため。 またメモリプール使用により他のアプリケーションによる妨害がなくなり よりはまりやすくなる。
258 名前:デフォルトの名無しさん mailto:sage [2010/03/28(日) 17:05:40 ] vector<T*> data; deque<T> pool; queue<T*> recycle; を用意して、 ・データは基本的にpoolから取ってきてdataにアドレスを入れて使う ・使い終わったデータはdataから削除してrecycleにアドレスを入れる ・recycleにデータが残ってる場合はpoolを無視してrecycleからdataにアドレスを移す こんな感じでいいんじゃない
259 名前:デフォルトの名無しさん mailto:sage [2010/03/28(日) 17:14:24 ] メモリプールって汎用化するより目的別に頭ひねってそのつど最適化した方が良くね?
260 名前:デフォルトの名無しさん mailto:sage [2010/03/28(日) 17:15:09 ] >>257 技術を向上させたいと思うなら先にこれを読んでおけ。 ja.wikipedia.org/wiki/%E6%9C%80%E9%81%A9%E5%8C%96_%28%E6%83%85%E5%A0%B1%E5%B7%A5%E5%AD%A6%29 不安や想像をもとにコードを複雑化させるのは優れた技術者のすることではない。
261 名前:デフォルトの名無しさん mailto:sage [2010/03/28(日) 17:18:00 ] 有難うと言いながら、>255を無視してて笑える。
262 名前:デフォルトの名無しさん mailto:sage [2010/03/28(日) 17:18:46 ] 百万単位でnew/deleteが頻繁に行われたらそりゃ試すまでもなくパフォーマンス落ちるわ
263 名前:デフォルトの名無しさん mailto:sage [2010/03/28(日) 23:09:23 ] だいたい、何を学習したくてそんなもん作ろうと思ったのか 百万のオーダーだと、メモリ云々よりレスポンスのほうが問題になりそうだが
264 名前:デフォルトの名無しさん mailto:sage [2010/03/29(月) 10:22:58 ] 百万単位でnew/deleteを頻繁に行うプログラムって何? どこかの人気サーバーでも扱ってんのかな?
265 名前:デフォルトの名無しさん mailto:sage [2010/03/29(月) 13:26:29 ] プリコンパイル済みヘッダーを使う際、中に defineで中身が変化するテンプレートを入れても 問題ないでしょうか? やはり読み込み方によっては問題あり?
266 名前:デフォルトの名無しさん mailto:sage [2010/03/29(月) 19:04:37 ] newに対してdelete[]はしちゃいけないもの? もしくはポインタの中身を何らかの方法で単体か配列か区別する方法は無いものですか?
267 名前:デフォルトの名無しさん mailto:sage [2010/03/29(月) 19:10:31 ] コンパイル前にノーマルnew/deleateを配列new/deleteに置換えるスクリプト走らせればいい。
268 名前:デフォルトの名無しさん mailto:sage [2010/03/29(月) 19:10:40 ] >>266 単体ならスマートポインタを、配列ならSTLコンテナを使えばそんな心配は要りません。 つーか、JavaScriptの悪夢の再現になるからポイント先が配列かどうかを判定するなんてことは考えない方がいい。
269 名前:デフォルトの名無しさん mailto:sage [2010/03/29(月) 19:11:21 ] >>266 > newに対してdelete[]はしちゃいけないもの? だめ。未定義の動作。鼻から悪魔が出るかも。 > もしくはポインタの中身を何らかの方法で単体か配列か区別する方法は無いものですか? ない。 T* p = new T; T* p = new T[10]; T a(0); T* p = &a; pがこの3つのどれなのかすら判定不可能。
270 名前:デフォルトの名無しさん mailto:sage [2010/03/29(月) 19:14:08 ] > 配列ならSTLコンテナを使えば boost::shared_arrayってのもあるぜよ!
271 名前:デフォルトの名無しさん mailto:sage [2010/03/29(月) 22:05:27 ] boostのプールって纏めてとる→足りなくなったらまた纏めてとる→まとめて破棄ってしてるの? 最後のまとめて破棄をしなかったら延々とメモリ食付していくのかな?
272 名前:デフォルトの名無しさん mailto:sage [2010/03/29(月) 22:10:18 ] make_sieve内のfree(sieve)で死ぬんけど何が原因? kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/10555.txt 環境 コンパイラ:VS2008 OS:XP SP3 その他:BCCだとエラーを吐かない 今気づいたけど終了時にprimesを開放してないのは気にしないで・・・
273 名前:デフォルトの名無しさん mailto:sage [2010/03/29(月) 22:40:24 ] >>272 Error 00001. 0x130610 (Thread 0x0EEC): Access overrun: Attempt to access 4 byte(s) at 0x00B8F550+4000, that is at offset 0+4000 in heap block 0x00B8F550 which is only 4001 bytes long. | sieve1.c line 27: | if(sieve==NULL) exit(1); | |> for(i=0;i<=limit;i++) sieve[i]=0; | for(i=4;i<=limit;i+=2) sieve[i]=1; | for(i=3;i<=limit/2;i+=2){ Call Tree: 0x0040123C(=sieve1.exe:0x01:00023C) sieve1.c#27 0x004011A3(=sieve1.exe:0x01:0001A3) sieve1.c#13 0x32AD8D9E(=CC32100MT.DLL:0x01:0D7D9E) The memory block (0x00B8F550) [size: 4001 bytes] was allocated with malloc | sieve1.c line 24: | void make_sieve(int limit){ | int i,j,idx,cnt; |> int *sieve=(int*)malloc(sizeof(int)*limit+1); | if(sieve==NULL) exit(1); | Call Tree: 0x0040121A(=sieve1.exe:0x01:00021A) sieve1.c#24 0x004011A3(=sieve1.exe:0x01:0001A3) sieve1.c#13 0x32AD8D9E(=CC32100MT.DLL:0x01:0D7D9E) なんか一杯エラー出る 範囲外をアクセスしてるみたいだね
274 名前:デフォルトの名無しさん mailto:sage [2010/03/29(月) 22:41:25 ] はーん malloc(sizeof(int)*(limit+1)); の間違いじゃねーの?
275 名前:デフォルトの名無しさん mailto:sage [2010/03/29(月) 22:47:02 ] int x = 0xXXXXXXXX; unsigned int y = static_cast<unsigned int>(x); このキャストで最上位ビットは標準で必ず維持されますか?
276 名前:デフォルトの名無しさん mailto:sage [2010/03/29(月) 22:59:13 ] >>273-274 それだ!!指摘されるまで気づかなかった俺アホすぎるw サンクス
277 名前:デフォルトの名無しさん mailto:sage [2010/03/29(月) 23:27:22 ] >>265 プリコンパイルヘッダーをインクルードする前に、意味のある文を書いてはだめ。 だからdefineによる変更はできない。
278 名前:デフォルトの名無しさん mailto:sage [2010/03/29(月) 23:49:30 ] >>265 例えばVCではこんな制限がある。 ttp://msdn.microsoft.com/ja-jp/library/fey8ayyf.aspx defineを変更するたびプリコンパイルをやり直せばいいんじゃない?
279 名前:デフォルトの名無しさん mailto:sage [2010/03/29(月) 23:55:26 ] 別人だが横レス。 つまりプリコンパイルヘッダを複数用意しろ、と?
280 名前:デフォルトの名無しさん mailto:sage [2010/03/30(火) 01:14:17 ] プリコンパイル使うのをやめるという方法もある
281 名前:デフォルトの名無しさん mailto:sage [2010/03/30(火) 01:41:18 ] プロジェクトのフォルダ構成でいいやり方ないかな boostをマネしようかと思ったけどソース見てもboostがどういうルールでやってるのかわからんかった・・・
282 名前:デフォルトの名無しさん mailto:sage [2010/03/30(火) 02:11:54 ] >>281 今がどんな構成で、それの何が気に入らないのか述べよ。
283 名前:デフォルトの名無しさん [2010/03/30(火) 15:53:11 ] WindowsでCPUの周波数を取得する方法を教えてください
284 名前:デフォルトの名無しさん mailto:sage [2010/03/30(火) 16:20:33 ] T& GetT(); T const& GetT() このようにメンバ関数の返り値がconstと非constのオーバーロードは可能なのでしょうか?
285 名前:デフォルトの名無しさん mailto:sage [2010/03/30(火) 19:31:15 ] T& GetT(); T const& GetT() const; これなら可能。 obj.GetT() として objがconstならば後者が、 そうでなければ前者が呼ばれる。
286 名前:デフォルトの名無しさん mailto:sage [2010/03/30(火) 21:07:04 ] >>277-278 やはり問題がありそうですね。 実際使ってるのはBCBなんで、VCを真似して 専用のヘッダー作って同一になるようにしときます。 ありがとう。
287 名前:デフォルトの名無しさん mailto:sage [2010/03/30(火) 22:07:09 ] char (*a)[4] = new char[10][4]; のdeleteはdelete(a)、それともdelete [] (a)? 自分delete [] (a)と思うんだけど、どう? delete(a)だとメモリリークにならないの? これでも全て開放されるの
288 名前:デフォルトの名無しさん mailto:sage [2010/03/31(水) 00:52:34 ] >>287 delete[]を使いましょう new char[10][4]; の10は変数でもよく、char (*)[4]、つまりchar型の 要素数4の配列へのポインタを配列確保する演算子なので、deleteは []を付けないとメモリリークします、というより未定義の動作です
289 名前:デフォルトの名無しさん mailto:sage [2010/03/31(水) 17:26:59 ] C/C++について基本的な事かもしれませんが、ポインタと配列について質問させて下さい。 int[] a; int* p1 = a; はわかるのですが、 int* p2, p3; p2 = a; *p3 = a; の違いがいまひとつはっきり理解できません。 また、次のようにした時、ポインタはどこのアドレスを指すのか想像がつきません‥ p2 = &a; *p3 = &a; よろしく御指南のほどお願いいたします。
290 名前:デフォルトの名無しさん mailto:sage [2010/03/31(水) 18:12:46 ] >>289 aがint型の配列だとして、 p2はaのアドレスをintのポインタからアクセスできるように コピーしている正常な記述。 *p3は、確保もされていないどこかの領域を指す不定なポインタに、aから取得できるアドレス値を 書き込んでいる不正な記述。 &aの方は、多分処理系が把握しているどこかのアドレスをそれぞれコピーしたり 不正な書き込みをしようとしているっていうかヤメロ
291 名前:デフォルトの名無しさん mailto:sage [2010/03/31(水) 18:16:07 ] int *p2 ,p3 ってint型ポインタp2とint型変数p3の確保じゃないか?
292 名前:デフォルトの名無しさん mailto:sage [2010/03/31(水) 18:20:08 ] >>289 そのコードは、いくつかコンパイルが通らないところがある。 > int* p2, p3; あとこれもp2がintへのポインタ、p3がintになるC/C++の罠。 p2 = a; ポインタが指すアドレスを変えるのはこれ。 p2 = &a; これはポインタへのポインタみたいなことになる。 *p3のように間接参照演算子をつけると、ポインタが指すアドレスを参照する。 つまり、*p3=aのような代入は、ポインタのアドレスを変えるのではなく、ポインタが指すメモリ(変数)の値を変える事になる。
293 名前:デフォルトの名無しさん mailto:sage [2010/03/31(水) 18:50:32 ] >>289 基本的な事と前置きがあり、たまに誤解して覚えてる人、また間違った説明をする人がいるので 念のためついでに書いておくと、 C/C++ には、例えば 「intのポインター"型"」 のような物は存在しない。これ重要。 あくまで、「int として扱われる、どこかのメモリ領域を指すポインタ」 であって、これは型じゃない。 つまり読み方として、その例は 「int*」 の 「p2」 でなく、「int」 の 「*p2」。 実際の用法については >>292 氏のレスを参照してもらうとして、老婆心だけどメモしておくと、 そもそも変数の宣言は、 int x; とあったとき、最初の int は(例えば整数が32bitだとすると)、「intとして扱う、4バイトの領域」 という意味でしかなく、 まだこの瞬間には物理的にどこかのアドレスには何も確保されていない。 そして次に x と、変数名が来たとき、 どこかにメモリが4バイト分確保され、それをあらわす名前として x が割り当てられている、という動きになる。 これを踏まえて、 int *y; は、最初の int で int として扱う4バイトの領域という型が宣言され、その次の * は、ワイルドカードの * と似た意味で、 「どこかのアドレス」 という意思を表している。 つまり int * だ。 で、しかしこれだけだと流石にその後扱えないので、その次でこれ自体に名前を求めている。これが y 。 そんな訳で、この例の場合、型としてはあくまで int。 そして変数として、それはポインタと宣言されているって意味の記述になるから、 int* z; ではなく、 int *z; でなければならない。 こんな基礎。
294 名前:デフォルトの名無しさん mailto:sage [2010/03/31(水) 18:56:39 ] もう一つ追記しておくと、つまり int x; は、どこか物理的な格納先が割り当てられたもので、それを指す名前が x という意味であり、 int *y; は、どこだかわからない(どこでもいい = *)格納先を示すもので、それを指す名前が y って事。 そしてどちらかも型としては int 。 ・・・って、 でも実際には int のポインター型 みたいに扱えないと不便なので、まるで型のように振舞ってはいるんだけど。キャストとか。
295 名前:デフォルトの名無しさん mailto:sage [2010/03/31(水) 18:58:08 ] 仕様書にpointer typeは出てきますが。
296 名前:デフォルトの名無しさん mailto:sage [2010/03/31(水) 19:02:50 ] 自殺してくる
297 名前:デフォルトの名無しさん mailto:sage [2010/03/31(水) 19:03:07 ] C++では int[] a; 表記OKになったんだ これはint配列を指すポインタ aを表すの? まさか参照じゃないよね
298 名前:デフォルトの名無しさん mailto:sage [2010/03/31(水) 19:05:23 ] Java臭いな
299 名前:デフォルトの名無しさん mailto:sage [2010/03/31(水) 19:07:03 ] どこかのスレで「ポインタ」と「ポインタが指す先」を「宝箱の地図」と「宝箱」で解説しているのを思い出した。 int x; // 「int型の宝箱」 int* y; // 「int型の宝箱」の地図 y = &x; // &でxの地図を取得してyに代入 *y = 10; // 地図であるyが指す宝箱への代入
300 名前:デフォルトの名無しさん mailto:sage [2010/03/31(水) 19:25:24 ] >>293 型が無いって断言しちゃうのはあれだけど、大体言いたいことは合ってる。 何々型の、何々 って記法で、何々=変数名の方を修飾する・・・例えばポインタをあらわす*や配列を表す[5] のようなものは、 なんて言ったらいいのかな・・・ 型の宣言が2段構えになってるようなイメージで捉えればいいんじゃないかな。 ただJavaやC#のような言語の場合は、その辺すっきりまとめて全部同じような型としちゃう傾向があるから、 そっちと混同すると混乱する可能性はあるような気がする
301 名前:デフォルトの名無しさん mailto:sage [2010/03/31(水) 23:11:53 ] >>288 ありがとうございます。やっぱりそうですよね。 >要素数4の配列へのポインタを配列確保する演算子なので 演算子はどれを言っているんですか?
302 名前:デフォルトの名無しさん mailto:sage [2010/04/01(木) 00:09:46 ] >>301 「new」演算子
303 名前:デフォルトの名無しさん mailto:sage [2010/04/01(木) 01:26:50 ] >293 型について間違ってるよ。 C/C++では、ある識別子の型は、その宣言から識別子を省いたものと定義されている。 だから以下のようになる。 int i; => iの型はint int *p; => pの型はint* int a[10]; =>aの型はint[10] あと変数の宣言(かつ定義)についての説明も誤り。定義された時点でメモリは確保される。 宣言の説明も出鱈目すぎる。以下訂正版を挙げる。 int x; 「intとして扱う領域」 が確保される。auto変数なら、値はゴミ。 int *y; 「int*として扱う、領域」 が確保される。auto変数なら、値はゴミ。つまり出鱈目なところを指している。
304 名前:デフォルトの名無しさん mailto:sage [2010/04/01(木) 13:25:00 ] あるクラスを実装するためだけに使うヘルパクラスがあったとして、普通に考えると namespace{ class HelperClass {...}; } を実装したいクラスのソースの頭らへんに書くと思うんだけど、これをファイル分割したい場合どうすればいいだろうか
305 名前:デフォルトの名無しさん mailto:sage [2010/04/01(木) 13:46:09 ] >>304 namespace detail
306 名前:デフォルトの名無しさん mailto:sage [2010/04/01(木) 14:39:16 ] WinAPIのRectangleってright-left<=0の場合って未定義?
307 名前:デフォルトの名無しさん [2010/04/02(金) 07:52:17 ] コンピュータ言語を何か覚えたくて疼うずしつつも、一歩踏み出せていない初心者です。 やっぱりCかなと思い、ここに来ています。今は特に作りたいものがないんですが、 プログラムが書けるようになったらやりたいことは沢山ありそうです。 勉強のために、10分くらいで出来そうな練習問題を出してくれませんか? モチベーションがあがりそうです。
308 名前:デフォルトの名無しさん mailto:sage [2010/04/02(金) 08:09:37 ] TopCoderでもやれ あるいはICPCの過去問探し出してやれ
309 名前:デフォルトの名無しさん mailto:sage [2010/04/02(金) 08:17:07 ] 初心者がいきなりそれはどうかと思う 1-nまで足すプログラム 文字列を逆順にするプログラム 好きなほうをどうぞ
310 名前:デフォルトの名無しさん [2010/04/02(金) 08:28:27 ] >>308 www.acm-japan.org/past-icpc/domestic2006/contest/all_ja.html こんなやつですね。 たしかに面白そうですね。 やったら添削していただけますか?
311 名前:デフォルトの名無しさん mailto:sage [2010/04/02(金) 12:05:24 ] class Foo{ Hoge* hoge } このhogeに多態的に要素を持たせたいのですが templateをつかうか、コンストラクタに要素をしていさせるかどちらがよいでしょうか?
312 名前:デフォルトの名無しさん mailto:sage [2010/04/02(金) 12:25:24 ] >>311 ポインタはスマポにしたほうがいい templateだったらhogeをポインタにする必要が無いな。
313 名前:デフォルトの名無しさん mailto:sage [2010/04/02(金) 15:00:21 ] すみません、考え方の整理をしたいので質問させて下さい。 自分は普段、Java と C# をメインに開発している者なのですが、趣味の範囲で C/C++ を真面目に 使いたいと思い、ここしばらくずっと勉強を続けています。 質問内容は、「C++ で言うクラス"名" は、C で言う構造体のタグ名と同じ捉え方でいいのか」 です。 具体的に言うと、C(/C++) の構造体について、現在自分はこのように捉えています。 struct { 内容 } 変数名A, 変数名B; は、その内容を構造として持った複合体のような変数として、宣言している。ちょうど、 int 変数名A, 変数名B; での、型名 int の部分が、{ 内容 } の形で表現されているような状態。 そして実際の記法としては、それが構造体の宣言である事を明示するため、struct と最初に書いてコンパイラに伝えている。 さらに、あとでこの同じ構造を再度利用したい(新しい変数を使いたい)場合に備え、 ここに一発で同じ内容を示す為の 「タグ名」 を、書くことも出来る。 そしてそれは、 struct タグ名 { 内容 } 変数名A, 変数名B; と、ある時、 struct タグ名 変数名C; のようにして簡易に使うことが出来る。 で、C++ になってからこの再度宣言する際の struct の一文は省略できるようになったので、 まるで Java や C# で言うクラス名のように見えているけど、 実はこれは元々再呼び出しの為の、タグ名だった。 そして、C++ になって今度はより仕掛けの拡張された class が登場したが、この時の class 名前 { 内容 } 変数名; にある "名前" の部分は、上記理解中にあるタグ名と同様に捉えておいていいんでしょうか、という事です。 よろしくお願いいたします。
314 名前:313 mailto:sage [2010/04/02(金) 15:02:41 ] 誤解を招きそうな表記をしたので訂正します ×実はこれは元々再呼び出しの為の、タグ名だった。 ○実はこれは元々再度宣言する際に記述を省略する為の、タグ名だった。
315 名前:デフォルトの名無しさん mailto:sage [2010/04/02(金) 15:25:13 ] >>313 俺もそんな感じに理解してた。こういう記述が出来る訳だからな class Foo { public: void bar() { class { public: int add(int x, int y) { return x + y; } } calc; int a = 1; int b = 2; printf("%d", calc.add(a, b)); } }; 厳密に同じなのか、については裏を取らないと自身無いが
316 名前:デフォルトの名無しさん mailto:sage [2010/04/02(金) 15:33:35 ] 深く考えすぎ。全部型だよ。 int型、float型、struct foo型、class bar型 int ってのは組み込みの型 class bigintと書けば自分でbigintという型を定義できる。 int a = 0; bigint b = 0;
317 名前:313 mailto:sage [2010/04/02(金) 15:47:49 ] >>315-316 レスありがとうございます。そもそも気になったきっかけが、C/C++ でのこの構文を見たせいなのです。 class 名前 { 内容 } 変数; Java や C# での感覚だと、この位置に "変数" が来るのが理解出来ませんでした。 そしてそれで使えるって、いったいコンパイラはこれをどう解釈してるの? と疑問に思った事がきっかけでした。 一応、>>316 さんが言うように、「それはそういう型。全部ただの型だ」 はわかるのですが、 上記の点で、どう言う意図でこのような構文になっているのか理解できず、その為色々調べた所、 C での struct が >>313 にあるような内容だと知り、それならば C++ で増えた class についても同様なのかなと思いました。 上記の構文から、「ただの型だ」 では曖昧に思ってしまう所があり、質問させて頂きました。すみません。
318 名前:デフォルトの名無しさん mailto:sage [2010/04/02(金) 15:57:04 ] CとC++で違いがあるからその影響かな。 struct xx { ... } ; typedef struct xx xx; // C++ではこれが省略できる。 xx v;
319 名前:デフォルトの名無しさん mailto:sage [2010/04/02(金) 16:06:19 ] >>317 C++ではstructとclassはほとんど同じってのは知ってる? 違いはメンバのアクセス指定を明示しないときのデフォがstructはpublic、classはprivateって所だけ。
320 名前:313 mailto:sage [2010/04/02(金) 16:26:55 ] レスありがとうございます。 >>318 typedef struct { 内容 } 名前; 名前 v; なら、そのまま名前の定義になるのでわかるのですが、 struct のタグ名と class のクラス名と言われている場所の名前について、同じかどうかが気になったのです。 >>319 質問にも書かせていただきましたが、むしろ同じかどうかを知りたかったのです。 では変な言い方かもしれませんが、同じと思っていいわけですね。 ただ、C++ に変わって「タグ名」という言い表し方は、ただのC時代からのレガシーと思えばいいという感じでしょうか。
321 名前:デフォルトの名無しさん mailto:sage [2010/04/02(金) 16:50:24 ] 何が疑問なのか分からなくなったが、規格上の話をしたいならそれはTagということでいいよ。 ただ考え方としては型名で、Cとの互換からTagとしての属性を残していると考えてよい。
322 名前:313 mailto:sage [2010/04/02(金) 17:00:48 ] >>321 ありがとうございます! >ただ考え方としては型名で、Cとの互換からTagとしての属性を残している この一言ですっきりしました。 あと >>315 さんの calc の行と合わせて、>>319 さんの言う 「ほとんど同じ」 も合わせて、 すっきりしました。 ありがとうございました。
323 名前:デフォルトの名無しさん mailto:sage [2010/04/02(金) 17:53:27 ] なぜboostには動的削除子付きの非共有スマポがないの?
324 名前:デフォルトの名無しさん mailto:sage [2010/04/02(金) 22:32:56 ] >>323 それは君がまだライブラリの提案を出していないからじゃないかね?
325 名前:デフォルトの名無しさん mailto:sage [2010/04/03(土) 15:29:48 ] スマートポインタを使うにしろ自作するにしろ 過去の蓄積との整合性を保つのが面倒だし一度使い出すと今後ずっと縛られることになるしなぁ 標準で実装されてるならともかく、 いくらboostみたいな有名なライブラリとはいえ非標準に依存するのはちょっと違和感あるなと時々思う
326 名前:デフォルトの名無しさん mailto:sage [2010/04/03(土) 16:49:37 ] >>325 > 非標準に依存するのはちょっと違和感あるなと時々思う 外部ライブラリもAPIすら使わないで 標準C/C++の範囲だけで書かれた有名なソフトウェアは 俺は一つもしらんのだが。 C/C++の限界でしょそれは。
327 名前:デフォルトの名無しさん mailto:sage [2010/04/03(土) 19:02:31 ] >>326 フレームワークみたいな使い方になっちゃうってことじゃない?
328 名前:デフォルトの名無しさん mailto:sage [2010/04/04(日) 02:34:35 ] メンバ変数のないメンバ関数だけのクラスのサイズは0でよいのでしょうか?
329 名前:デフォルトの名無しさん mailto:sage [2010/04/04(日) 02:37:59 ] >>328 そうとは限らない。
330 名前:デフォルトの名無しさん mailto:sage [2010/04/04(日) 02:48:38 ] >>328 C++では0ではない事が規格で保証されている 理由を聞くとアドレスを取るためだと
331 名前:デフォルトの名無しさん mailto:sage [2010/04/04(日) 10:28:12 ] 何故クラスのサイズが0だと思ったのか
332 名前:デフォルトの名無しさん mailto:sage [2010/04/04(日) 12:02:22 ] Cでは空の構造体のサイズが0になるからだろ C++は仮想関数などポインタに入れて使う使い方もあるので (もっともvtableなどで元々0ではないかもしれないが)空の 構造体やクラスでも0にはならないように設計されている
333 名前:デフォルトの名無しさん mailto:sage [2010/04/04(日) 12:25:49 ] >>328 > メンバ変数のないメンバ関数だけのクラスのサイズは0でよいのでしょうか? むしろほぼ間違いなく0にはならないことが保証される。 例外はEBOが働いた時のみ
334 名前:デフォルトの名無しさん mailto:sage [2010/04/04(日) 12:31:20 ] じゃあ空の構造体はCとC++で互換性が無いのか
335 名前:デフォルトの名無しさん mailto:sage [2010/04/04(日) 12:43:37 ] ( ・∀・)つ〃∩ へぇ〜初めて知った EBO (Empty Base Optimization) 空の基底クラスの最適化。 メンバ変数を一個も持たない、空のクラス、というものが出来ることがあります。 しかし空のクラスであっても、アドレスは一意に決めなくてはならないので、 izeof( EmptyClass ) は 0 にはなりません。 EmptyClass arr[100]; assert( &arr[0] != &arr[1] ); // アドレスは違ってて欲しい単独で使う時には この無駄は仕方のないところですが、 例えばこの空クラスから他のクラスを派生 するときは、EmptyClass の分のサイズは 0 にして、派生クラスのメンバ変数の 分だけを確保する、という最適化が可能です。 C++の規格で許されているこの 最適化のことを、Empty Base Optimization と呼びます。
336 名前:デフォルトの名無しさん mailto:sage [2010/04/04(日) 12:43:45 ] >>334 sizeof(空の構造体)が0になることがC言語の標準規格で保証されていたかは 記憶にないけど、もしそうならC++と互換性が無い点になるだろうね。 でもsizeof(空の構造体)==0に依存したソースってどんなんだ?
337 名前:デフォルトの名無しさん mailto:sage [2010/04/04(日) 16:00:36 ] >>332 ISO C 6.2.6.1 p2 > Except for bit-fields, objects are composed of contiguous sequences of one or more bytes, ... C でもサイズは 0 にならないよ。
338 名前:336 mailto:sage [2010/04/04(日) 16:14:04 ] >>337 ほー。 じゃあむしろEBOが特例でサイズが0となり、 それ以外は標準C/C++では必ず1 or more バイトはかかるわけだ。 ありがとう。
339 名前:デフォルトの名無しさん mailto:sage [2010/04/05(月) 00:47:17 ] struct hoge {}; struct hoge fuga[42]; で&fuga[0] < &fuga[1]でないと色々厄介だからね。