【初心者歓迎】C/C++室 Ver.103【環境依存OK】
■ このスレッドは過去ログ倉庫に格納されています
エスケープシーケンスやWin32APIなどの環境依存なものもOK そのような質問は必ず環境を書きましょう 半角空白やタブでのインデントはスレに貼ると無くなります コードを貼れる所 http://codepad.org/ https://ideone.com/ 前スレ 【初心者歓迎】C/C++室 Ver.102【環境依存OK】 http://mevius.5ch.net/test/read.cgi/tech/1509780815/ ああ、goto labelのところ、continueでいいのか forだけじゃなくwhileが後ろにくるパターンでも使えるのですね でも、 label: が ) の前に使えないってのはなんででしょうね continueは、 { } の最後に飛ぶのではなく頭に飛ぶものだと思ってましたが、 コンパイラは、} の方に飛ぶようにつくるのですね。 for でもそうなのか。 頭に飛ぶものと思ってました > ret = ret; <---- ここ ! ちなみにコレ なにやってんの 要するにになにもしたくなかったワケか だったら余計なことしないで空文でいい >>492 ありがとう。 } の直前にジャンプしたかっただけです。 で、 label: と コロンでとめるとエラーになったので ダミー文と入れました。 やってないけど、 セミコロンだけでよかったのですね >>関数へのポインタの利用用途がスラスラと言えるレベルで中級 と書いてしまいましたが誤りでした 正しくは、以下でした Cプログラミング診断室 第2章 これでもプロ ポインタ より C言語中級レベル認定問題 関数へのポインタの配列とはどういうもので、どういう使い方があるでしょうか。 藤原先生の名誉のためにも訂正しておきます スレ汚し失礼しましたm(_ _)m std::tuple<hoge, fuga> std::tuple<hoge, hage, ...> std::tuple<fuga, hoge, hage, ...> という具合に<>の中が何パターン(ほぼ無限)もある場合 template<typename T>と std::tuple<T> で代表させるみたいなこと出来ますか? 出来るなら template<typename *> std::tuple<*> こんな感じが嬉しいです >>495 やりたいことがよくわからんけど……。 欲しいのは variadic template かな? MSVC 専用らしいのですが _For_each_tuple_element の引数として指定されたλ関数の中で _For_each_tuple_element を呼ぶ前に宣言した変数にアクセスするにはどうすれば良いですか 外 int i = 0; std::_For_each_tuple_element(tuplevaluse, [](auto&& v){ fprintf(stdout, "%d: ", i++); // ← ここの i でエラー fprintf(stdout, "%d\n", (int)v); }); 解決しました int i = 0; std::_For_each_tuple_element(tuplevaluse, [&i](auto&& v){ fprintf(stdout, "%d: ", i++); fprintf(stdout, "%d\n", (int)v); }); VC++6.0 MFCを使っています。 数秒間、処理を止めたいのですが、C言語のsleepという関数がありますが、これを使うのが一般的なのでしょうか 心配なのは、これを使って10秒とか時間を止めると、その間CPU時間が100%になったりしないのかという点です。 MFC環境で上手に処理を止めるのにはどうしたらいいのでしょうか。 OnTimerを使うとかしないとダメですか 自己解決 MFCで、sleepという関数は使えませんでした その代り、Sleepという関数が提供されていました >>501 MFCに限らず、UIスレッドの関数内で10秒もSleepで待つのはダメ。 そのウィンドウをユーザーが操作したら「応答なし」と表示されてしまう。 OnTimerで定期的に監視し続けるなり、 独自のメッセージを送って終了を通知するなりしないと。 もちろん、その間は ×ボタンを含めてすべてのコントロールを操作不可にしたり、 ユーザーが閉じられない別ダイアログをモーダルで出したりする対応も必要。 いまどきのSleepは他プロセスを止めたりはしないぞ 本来ダメなんだけどエクセルとかも盛大にUIスレッドで長期間マクロ実行したりするからね 数秒くらいならいいんじゃないの 金とってプログラム作ってる風でもないし >>506 Sleepで待ちたくなるということは、処理自体は 別スレッドなり別プロセスなりで動いているのだと思ったが 俺はメインスレッドでそのまま何かやってると感じたな sleep の挙動を5ちゃんで質問する人がすでにワーカスレッドを使ってるとは全く想定しなかった 本人解決したと言ってるのにいつまでもマウント取りたがってんじゃねーよ なんかえらい反感買っちゃったな Sleep知らなくてもワーカスレッドは使ってるだろうという>>507 の方が普通の感覚なのかな みなさん判りましたか 条件後出しするとこうなります tupleの要素取り出すときstd::get<>以外の方法ありますか? tuple[index]みたいに取り出せたら良いんですけど テンプレート特殊化を使えば出来るけど、そういうのは汚いコードだね。 >>515 tuple の要素が char * だとして std::vector<char *> vec; int i = 0; std::_For_each_tuple_element(t, [&h, &i](auto&& v){ printf("%d: %s\n", i++, v); vec.push_back(v); }); >>519 求めていたのはこれでした ありがとうございます すごく初級の質問なんですが、 int * x =3; auto y=*x; としたときに、コンパイラがyの型をintと推測するのはなぜでしょうか? ポインタのポインタになるので、最初の*でint型の変数のアドレスを示すことになるまでは分かるのですが、 その後の*でアドレスのアドレス?を指すことになるので、元のint型の値を指すのは違うように思えてしまいます。 x は 0x00000003をアドレスとして認識 y(*x) は int型アドレス0x00000003にある値を指す アドレス(x)のアドレスを指す場合は &x になる 多分、変数yの型が省略されているから、 デフォルトのintと推定して処理しているのだろう >>522 ありがとうございます。 ということは*がついてる変数は、変数がアドレスのときはそのアドレスに収納されてる値を指し、変数がアドレスに収納されてる値のときは、そのアドレスを指すという理解でよろしいんでしょうか? >>525 違うよ。 型名の一部としての*と、式の中の演算子としての*が別物だと言うのは分かる? 1行目の方は「intをさすポインタ」という型を表すためのもの。 2行目は「xというint型の変数の値に対して、その値が指しているメモリ領域上にあるint型の値を参照する」という演算を行うというもの。 この変数はポインタです 宣言の * ポインタで指している先の内容を得ます 式の * C++コードの部分を間違って読み込んだとか? エンコードはEUC-JPだね Firefox だと右上メニューからエンコーディングで明示的に EUC-JP 指示で化け解消 (unicode にチェックが入ってたが、自動だとそっちに誤爆判別してた?) Chrome での明示的なエンコーディング変更は拡張プラグインつっこまないとできないっぽい C/C++ のポインタの表現が分かり難いってのは確かにあると思う。 宣言のときも * は変数名の側にくっついているものと考えれば理解しやすいんじゃないかな。 int * x; と宣言したとき、 *x が int であるような x を宣言したことになる。 Cの頃は int *hoge; と書くことが多かったのに、 C++になってから int* hoge; と書く人が増えた。 悪い習慣だと思う。 Javaとかから入る人が増えたからかね? その習慣はあかん。 ポインタは型じゃないから、例えば int* a,b; って書くとaは「int型のポインタ」で、bは「int型の変数」になる。 >>532 いや、そこらへんは C/C++ のおかしなところで、ポインタはあくまでも型だ。 その上で文法上は * は変数名の側と結合するの。 もういっそ std::add_pointer<int> a, b; のスタイルを普及させればいいんじゃないのかなーと思う。 C++ だとなるべくスマートポインタを使う習慣が出来つつあるから、 その記法とも一貫性があるし。 >>532 ポインタは型じゃないって言ったとき じゃあなんて言うんだっけ 仕様でも厳密にはなんか型とは別のカテゴリとして扱われてたよな 仕様に詳しい人教えて 型変換は (型)式 と書くわけで型を単体で書く書き方はあるのに変数宣言は 型 変数[, 変数]... じゃないからねえ void f(void); void (*f_ptr)(void) = f; // ふむ void (*g_ptr)(void) = (void(*)(void)) f; // 関数ポインタ型の記法はこうか… void (*)(void) h_ptr = f; // 型 変数で書いてみた→エラーかい! みたいな 初期化リストで二次元配列を0で初期化したいときはどう表記したら良いですか? 初期値式リストの個数が足りない場合残りの要素は0で初期化されるので int a[5][6] = {}; でok >>538 CやC++では、ゼロクリアされるのか。されないと思っていたが 初期化値リストをつければ足りないところは0で埋められる 付けなければ初期化されない 太古から変わらない仕様 あ、でも c だと空の初期化リストは書けないから {} じゃなく {0} にしなきゃダメか >>535 変数宣言の基本的な形式 型指定子 宣言子1, 宣言子2, …; で言うと * は宣言子の一部ということになるが、 型指定子でないから型 (の一部) ではないというわけではない。 これは文法上の呼び名に過ぎず、 意味論的にはポインタは型の一部だよ。 視点の問題ではあるが宣言の構文上のポインタは型の種類ではなく入れ物の種類ともいえる int *a, b; は int pointer a, int variable b; を意味する省略構文であり意味論的に variable:値をいれるもの pointer:間接的に他の入れ物を指すもの と区別されてると見ることもできる >>544 そういうのは単純なポインタ(foo*)の時にだけ通じる話で、配列や関数ポインタや引数込みでのそれらの再帰的な組み合わせとかも考えたら、きちんとBNFで理解して型の宣言の構文を定義通りに覚えるのが一番誤解がなくてシンプルだと思うよ。 >>543 レスサンクス 自分でも調べてみた 手元のc99ドラフト版から適当に抜粋 declaration: declaration-specifiers init-declarator-list ; declaration-specifiers: storage-class-specifier declaration-specifiers type-specifier declaration-specifiers type-qualifier declaration-specifiers function-specifier declaration-specifiers init-declarator-list: init-declarator init-declarator-list , init-declarator init-declarator: declarator declarator = initializer declarator: pointer direct-declarator pointer: * type-qualifier-list * type-qualifier-list pointer 宣言時の * は declarator なんやね構文としては >>535 詳しい人とかハードル上げられるとな。。。 プログラミング言語C売っちゃったから、厳密な仕様は記憶の彼方だが、ポインタは厳密なカテゴリ的にもポインタだったと思う。 ここからは私の解釈だが、ポインタはアドレスを入れる「変数」。 当たり前じゃんと言われればそうなんだけど、感覚的にも型というより変数って感じ。 ポインタに型があるとすればOSがアドレスを扱うビット数と同じになる。 intとかの型はポインタが指す先にどの大きさのどういう扱いのデータがあるかを知る為で、ポインタ型そのものの大きさは変わらない。 んで、普通の変数とポインタはCだと大分違うように思うけど、アセンブリ言語だと LD GR0,TEXT ; 変数TEXTの内容を読む。 LDA GR0,TEXT ; 変数TEXTのアドレスを読む。 程度の違いしか無いわけね。 この場合、内容もアドレスもレジスタが読むけど、Cにレジスタに相当する変数を用意する為にポインタが生まれたんだと思う。 >>547 私の解釈? ポインタが生まれた理由? なんでその内容を俺にレスしたのか意味不明 x Cにレジスタに o CにLDA使用時のレジスタに carとcdrに付いて小一時間 こちらの方が先だべ >>538 ありがとうございます説明が足りなかったかもしれません メンバ変数の配列をコンストラクタでリスト初期化する場合どうしたらいいですか? Hoge::Hoge() : mPiyo(0) ←これの二次元配列版を知りたいのです >>551 同じだよ {} で初期化すればいい。 Hoge::Hoge() : mPiyo{} { ほにゃらら } ってことね。 >>547 言語実装ベースの思い込みが過ぎる。 言語規格中のポインタは型だし、変数ではない値もあり得るし、ポインタの指す先の型の違いは大きさだけではない。 ↓「ポインタ型」で検索して確認されたし。 http://kikakurui.com/x3/X3010-2003-01.html > void (*)(void) h_ptr = f; // 型 変数で書いてみた→エラーかい! 当然知ってると思うけど void (*h_ptr)(void) = f; これは * と () の優先順位が原因だ よく * と [] で混乱してるひともいるけど char **hoge; char *hoge[]; char (*hoge)[123]: char (*hoge)[]: // エラーかい! >>551 今では (C++11 以降では) 宣言時に初期化も書けるから、 struct Hoge { int a[10][10] = {}; public: Hoge(void); }; って感じでも書ける。 複数のコンストラクタがあるときに、 どのコンストラクタが起動したときでも初期化はしないといけないみたいなときには、 この方式で書いた方が何度も同じことを書かなくてよいので面倒くさくなくて良いかも。 >>556 なるほど コンストラクタにつらつら書くよりもヘッダで宣言時に初期化した方が綺麗ですね アセンブラとかから C に入門したら色々と自動化されてて ありがたいなーってなってポインタで躓いたりしづらいけど、 レイヤが違うという意識を持ってないと変に機械の理屈に引きずられることもある。 言語の理屈だとポインタはアドレスを入れるものじゃなくて、 ポインタを値として見たものをアドレスと呼んだりもするってだけ。 結局はポインタにアドレスが入ってるんだけど、まずポインタありき。 ポインタに対する演算ってのは指す先をいくつ進めるとか、 指す先の間隔がいくつだというものであって、 アドレスを演算して実現するってのは実装上の都合。 アドレスが連続しているということさえ保証はない。 たとえば char a[2]; とあったときに (intptr_t)(&a[1])-(intptr_t)(&a[0]) が 1 になることは言語仕様では保証されない。 (これが 1 にならないような変な環境はまず無いと思うんだけど。) 具体的に機械でどう動いているかから見ると肌感覚として理解しやすい場合もあるのはわかるが、 言語の理屈と混同しないように、一旦それは抽象の壁の向こうに押しやる必要もある。 ラムダ式でthisを指定してそのクラスのメソッドを呼び出したところ、そのクラスのメンバ変数がすべて0になっててコンストラクタも動作してない状態になってたのですが、使い方間違ってますか >>559 インスタンスが既に破棄されているのでしょう c++ ではオブジェクトの寿命管理は自分でやる必要があります (参照があるから破棄されないということはない) >>559 [&*this] こうしたっていう意味? ラムダ式にはthisを指定しました インスタンスは生きています ラムダ式内から直接呼ばずにグローバル変数に保持したインスタンス変数経由で同じメソッドにアクセスしたら正しい値が読み取れました auto f = [this]() {... }; てな感じにキャプチャはしてるんだよね。してないとコンパイルエラーになるし。 デバッガでみておかしいだけならデバッガがうまく動いてないだけでは? cout << this->hoge; とかして見てみたらどうでしょう。 >>562 >ラムダ式内から直接呼ばずにグローバル変数に保持したインスタンス変数経由で同じメソッドにアクセスしたら warning読み飛ばしてるだけだと思うが warningにそうしろって書いてあるはず あとグローバルにしなくても ラムダ式を呼ぶ側の関数内のローカル変数で保持しても多分いける 複数のファイルをコンパイルするとき、ソースファイルの読み込み順番ってc++ではどのように決定されるのでしょうか? 読込み順番ってのが何を言おうとしているのかよくわからんぞ。 >>566 それぞれ別の翻訳単位として、独立に処理されるぞ。 依存関係があって先に読み込ませる必要があるファイルは、#includeで明示的に指定した順に読み込ませる必要があるよ。 先に読み込ませれば (ヘッダを include したり宣言を書いたりしなくても) 定義したものが利用可能になると思ったってことなのかな? ソースファイルの読み込み=ソースのコンパイルとして makeなり 統合環境なりが 依存関係チェックして必要と思われた順にコンパイラを起動しコンパイルしてる >>571 >makeなり 統合環境なりが 依存関係チェックして必要と思われた順 別に make による依存度チェックが必須だとは思っていません 最悪、アプリケーションを構成する全ソースを全部コンパイルしたっていい やっていることがよくわからないのなら、全部再コンパイルするバッチを書いてもいい、と思っています >>572 確かに、時間が無駄になるだけで、それにより動作が変わってしまう等の害を及ぼすことはないからなー 結局 >>566 が聞きたかったことは皆目見当がつかんけどもw vectorで複数のstd::stringの各要素を収納して管理してみたいのですが、 実際、vectorの特定の要素にアクセスしてstringのデータを入れようとするとエラーになってしまいます。 例えば、次のようなコードの場合です。 std::string A = "bookA"; std::string B = "bookB"; std::vector<std::string> booktitle; booktitle[0] = A;//コンパイルエラー vectorで複数のstd::stringのデータを収納したい場合にはどうしたらいいのでしょうか? >>574 booktitle.push_back(A); >>573 FreeBSD 2, 3, 4 (くらいかなあ) 時代には、OS カーネルを再度コンパイルすることはあたりまえだったんですけれども、最近はそういう話はすたれてしまいましたね… >>575 ありがとうございます。 例えば、vectorにpush_backで100個のstd::stringのデータを入れたけれど、38個目のデータを別のものに変更したいという場合、 38個目のstd::stringのデータを直接指定して別のものをいれるということはできないんでしょうか? >>577 38個以上格納した後なら、 booktitle[37] = A; で書き換えられる。 >>577 c の普通の配列みたいに中身に拘らずとりあえずサイズ100の配列を用意したい場合は v.resize(100) でいけるのでその辺りも併せて覚えておきましょう 関数の中でポインタ変数を作ったら、その関数から出る時、ポインタ変数は消えるけど、ポインタ変数の中身はどっか別にあって消えないってことで良いんですかね? その中身を消すのがdelete関数ってことですか?ややこしいな・・・ ありがとう。すみませんもう一つ。 ポインタ変数のアドレスを格納するのに、なぜ二重ポインタが必要なのかがいまいちわかりません。 単に”番地”を格納するだけなら普通のポインタでも良いような気がしてしまいます。 それは、32ビット浮動小数点のビットパターンを32ビットintに入れておけば float型とかいらないと言ってるようなもの アドレス値がほしいとき 引数でアドレス入れる変数のアドレスを渡すことがある >>582 情報量としては実際のところメモリアドレスなので同じだけれど型が違う pがint へのポインタなら *p はアドレス位置にある int を返すし、 p++ すると int のサイズ分増えるし、 p[i] はintのサイズかけるiのメモリ位置にある int になる 上記の int を char やポインタ型に入れ替えると動作が異なることがわかる。 なんの型で読み書きするのかとかサイズの計算なんて人がコードで書けばいいじゃん、 という流儀もあるだろうがcは違う 例外としてなんの型だか不明なものを扱うときには、 とりあえずvoid*で保持しておいて計算やアクセスするときに 明示的に型を指定して用いることもある アドレス渡さないと変数(今回の場合アドレスを格納する領域)に値を格納できない コレはどんな変数でも同じ アドレスを格納する変数もただの変数だからな >>580 >ポインタ変数の中身はどっか別にあって消えないってことで良いんですかね? (ポインタ変数の中身はポインタだが、ポインタが指してる先と読み替えよう) 指してる先はどっか別にあってって、言語が自動で作ってくれるわけじゃないよ ポインタが指す先もプログラマが作らなきゃならない だから消える所に作れば(自動変数な)消えるし、消えない所に作れば(静的変数やnewな)消えない >>582 二重ポインタ(って表現もナニだが…)も ポインタを指してるってだけの普通のポインタだから ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる