【初心者歓迎】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/ >>199 ありがとう。『C++の設計と進化』はタイトルは知ってるけど 読んだことはない(お高いのでなかなか買う踏ん切りがつかない)。 『プログラミング言語C++』第4版の中でも何回か言及されてるから いつか読もうとは思ってる。 …とか言いつつ、先刻まで「進化と設計」と覚えていた。 確かに「設計と進化」、設計して作ってさらに進化、じゃないと 話が合わないね。 何故そうなっているか?を書いているから良書だよ 丸暗記以外はしない人には不要かも知れないけど noexceptについてなんですが、標準ライブラリのコンストラクタとかって 実装が勝手にnoexceptを付けたりできますか? cppreferenceによるとunordered_map()のデフォルトコンストラクタはnoexceptが付かないことになってますが noexcept(unordered_map<string, int>()) の値を見てみたら、ideone.comではtrueになっていました。 Visual C++だとfalseです。 安全側、制約の強い側になるので実装によって異なっていても問題ないということですか? >>207 のリンクにあるような、 ユーザー・システム環境変数の画面のPATH をわからない人は、プログラマーにはなれない。 プログラマーになれない、Excel エンジニアが多いのは、PATH の仕組みがわからないから 数十ある、基本コマンドを勉強していないから シェル(PowerShell・コマンドプロンプト)で、 「ruby 引数」のようなパス無しの「コマンド名 引数」でなぜ、 実行ファイルが探し出されるのか? ruby で起動される実行ファイルは、ruby.exe, ruby.dll, ruby.sh なのか? それらが同じフォルダにあれば、どれが起動されるのか? こういう質問に答えられない人は、何十年プログラミングしていても環境構築できない こういう人は、単なる土方プログラマーで、 コンピューターリテラシーがないから、企業が採用したくない人! 土方プログラマーはいらない! コンピューターリテラシー、つまりシステムの知識がある人が求められている 土方も重要だ BIOS, ドライバ, OSのカーネル, ... >>212 問題ない。 https://timsong-cpp.github.io/cppwp/n4659/res.on.exception.handling#5 > An implementation may strengthen the exception specification for > a non-virtual function by adding a non-throwing exception specification. 詳説 Cポインタ、2013、オライリー・ジャパン ポインタの仕組みだけで、1冊出てるぐらいに難しいw >>216 よく、スレで宗教戦争を起こしているでしょ C言語がポインタの表記について混乱しているから、難しい。 に一票かなぁ >C言語がポインタの表記について混乱しているから、難しい。 混乱してるようには思えないんだが、どう混乱してるの? まあ確かに関数のポインターの型表記 などは難しいといえば難しいな。それを言うならC#だってラムダの型表記などはautoしてみないと 分からないようなことがある。ラムダもポインターに似たようなものだからね。 Cは凄くいい言語だと思う。シンプルで綺麗で分かりやすい。ただC++は失敗作だ。しかし C11あたりからその駄目部分をカバーしてきている。つまり使い方を選んで使えばC++は 非常に便利に使えるようになってきている。 本を読んでもC++の作者が書いた本は混乱していて分かりずらい。物事を複雑に考え過ぎて 混乱している。こういう人には綺麗な言語を作るのは難しいだろうと思う。今のC++はC#やJava が作り出した成果を取り込んで、精神を叩き直されたC++だから元々のC++とは違うものだと思う。 >>215 ありがとうございます。 明示的に許されていたのですね。 今回はVisual C++でコンパイルできないコードをideone上でミニマムに 再現しようとしたところコンパイルできてしまって躓いていました。 >>221 >C11あたりからその駄目部分をカバーしてきている。 私は C++11 以降は「進んで追わない」と決心してしまった敗者ですが、 そういう敗者であっても、C++11 が以前の欠点をカバーしている、というのなら、それをおききしたいです C++11 later の改良点をひとことでいうと、何なんでしょうか? 【C++11の改良点のおさらい】 autoキーワードにより、イテレータの型名の指定を省略できるようになった。 std::map, std::setの高速版のstd::unordered_map, std::unordered_setが使えるようになった。 初期化リストにより、初期化が楽になった。 ムーヴにより、所有権の移動を高速化できる。 範囲for文が使えるようになった。 constexprキーワードにより、さらなるコンパイル時計算の最適化が可能になった。 例外の扱いが改善された。 noexceptがブロック単位で指定できると面白いかも。 noexcept { int f(int n) { return n + 1; } } Javaのsynchronizedみたいなキーワードが使えないかなあ。 C++11の改良点は、性能と使いやすさを両立させるものである。 例えば、初期化リストを使えば、要素をまとめて確保できるので高速化が期待できる。 ムーヴは、コピーよりも高速である。 >>226 素人考えだけど vector<int> vec = {1, 2, 3}; for (auto elem : vec) { cout << elem << endl; } みたいなことが出来るのは実用的にはものすごくありがたいよ 濫用して読みにくくなるのは問題だけど、決まりきった処理を簡潔に書きたい場合はむしろ読みやすくなるわけだし >>236 そういうところが凄く便利になったね。 でも過去の負の遺産も引きづっている。なかでもcoutは特に嫌いだ。 coutは使わないことにしている。コードが汚くなって台無しだ。 スレ頭なんだけど ルート2っていうのがそもそも代数的に定義されたもので、有理数の加減乗除で表すのは不可能 じゃあルート2が何で存在するかっていうと、その代数的性質を満たす仮の数(!)にどこまでも近づけるから どこまでも近づくっていうのは、好きなオーダーで誤差を小さくすることが出来ることを言う 結局ルート2っていうのは任意の誤差で二乗して2になるような性質に近づく手続きのこと 誤差のオーダーを与えればそれを満たす数をただひとつ返す関数があれば それはルート2 と数学的に同値 あんま役にたたないけど 要するに数表だろ 実用的なのはデータベースで100TBくらいじゃねえの 0.0から6.24...まで0.00000000000000000000000000000001刻みで計算しとくんだろ あとはルックアップテーブルに丸投げ 計算速度は、CPUが計算するか、 CPU近くの独自回路のハードウェアで計算させるか、 CPUが三角関数の値を欲しがって遥か遠方のDBに問いかけて遥か遠方のDBから数表の値が返ってくる莫大な時間か 6.24...てなんだ? ルートの計算なんて除算と同程度に速いんだから タイムクリティカルな場所じゃなければ 毎回計算すれば良いよ 少なくともわざわざ>>13 みたいにプログラマが計算しなくて良い const WCHAR* const p = L"aaaa"; というconst WCHAR*を指すポインタ定数があるとき、 typedef const WCHAR* LPCWSTR; と型宣言がされていると、 const LPCWSTR p = L"aaaa"; と書けるけど、このときなぜ後ろのconstが前に出てくるんでしょうか。 後ろでもいいはずだけど なぜ前に出て“これる”か、ということなら ポインタを修飾してることが明確だからかな typedefしてないと*の後にしか書けない >>248 これ後ろのままでもコンパイル通るんですか。 で、前でもコンパイラが理解できるからどっちでもOKと。 ただそれなら、 const const WCHAR* p = L"aaaa"; という記述も特別OKにしてもらいたかったです。 >>239 え? 一辺の長さが 1 の正方形を書けば、その対角線 √2 が静的に可視化されている、のですけれども >>249 それだと*が2つ以上の時に困る const const WCHAR** p が const WCHAR * const * p const WCHAR * * const p WCHAR * const * const p のどれになるか分からん。 >>250 スレチだしレスするの迷ったんだけど 1辺が1の正方形を本当にかけるのか、対角線を引いたときに本当にルート2なのか、可視というが何が見えてるのか って感じで、1を正確に測りとれるとか三平方の定理とか、対角線の長さを測りとれるとか いろんな仮定が入ってる 結局仮のルート2に収束する数列とか、>>244 の言う数表(ただし無限に続く)とかと同じ議論が起きちゃう おまいら何百年前にされ尽くしたような議論をはじめるつもりか? ルートなんて学校で習っただろ 1/3というのはどうなんだろう 正確に三等分なんて、分子レベル素粒子レベルまでたどり着いても不可能だってことにならない? コンピューターで扱う上では除算と非常に近い (一般的には)近似値しか計算出来ないのも同じ 実は計算方法までそっくり >>252 スレチも山の賑わい… 正方形も、その対角線も、静的に存在しており無限の過程を認識する必要はないでしょう? その対角線を、例えば 10 進法表記に対応させるときに、無限の過程が発生するだけで アキレスと亀の話と似ている気がします もちろんデータとして扱う時は十進対応させなきゃ行けないので、有理数の加減乗除の届く範囲で近似が必要になる ただ実数と有理数の間には実際にでかい隔絶があって、自然数からの加減乗除による拡大は有理数で止まる あと本物の正方形を誰が見たこともないように、正方形や円っていうのは仮定の上にあるもの 実数の存在を正方形や円(パイ)に求めるのは、結局その仮定を無意識のうちに使用しているだけ もちろんデータとして扱う時は十進対応させなきゃ行けないので、有理数の加減乗除の届く範囲で近似が必要になる ただ実数と有理数の間には実際にでかい隔絶があって、自然数からの加減乗除による拡大は有理数で止まる あと本物の正方形を誰が見たこともないように、正方形や円っていうのは仮定の上にあるもの 実数の存在を正方形や円(パイ)に求めるのは、結局その仮定を無意識のうちに使用しているだけ 脱線ついでに、 3次元の立方体はイメージ出来るけど、 4次元の立方体ってイメージ出来る物なのかな? 訓練を積んだ数学者なら出来るの? 例えば3次元立方体を2次元平面で切断したときに出来る図形と同様に 4次元立方体を3次元空間で切断wしたときに出来る立体をイメージ出来るの? >>261 イメージ出来るって言うのを、頭のなかで回転したり任意の方から光を当てて影を見たり切断面かいたり 出来ることだとすれば四次元は比較的いける。その辺が専門の大学院生ならイメージできる 正多胞体(多面体、多角形の四次元ばーじょん)も発見されてるし、だいぶ見えてると思う 五次元もいける数学者が数人いるという噂もある 高次元だとイメージよりアナロジーが先行するかな自分の場合 立方体より単体のほうがイメージしやすいが 立方体だと[0,1]^nに微分同相とかきっとそんなん >>262 やはりスゴイと言うしかない そういう人なら、ゴムボールを切らずに裏返しにする事も出来そうだ 勿論、頭の中でだけど >>239 √2は手続きではないだろう。 1に1を足した数に2ってラベルがついてるのと同じで、 (√2)^2=2となるような無理数にラベルがついてるだけ。当然2の平方根に完全に一致する。 そして誤差のオーダーを必要とする時点で近似的な取り扱いしかできないということになるのだから、 √2が必要であれば√2として持つしかないだろう。 10進小数点表記で任意精度で表すためにはその手続きが必要となるだろうけど。 2は自然数の加減乗除で表せる(というかそれが定義)けど、ルート2はかけない じゃあルート2の定義はっていうと、方程式の解であって、1と2の間に存在しそうだけど本当にあるの?って話 結局新しい仮定が必要になってきて、それが収束有理数列と同値で、この列は手続き=関数と同値 なんかスレチで荒らしてすまんな 困難わかってても実際はあまり役にたたたないし >>267 それは正の数の平方根数が実数上に確かにある存在の証明の手続きでしかないよね 実際に任意精度で√2を求められる関数を使って(√2)^2が2になるか確認するには無限の時間がかかるよね 正の数の平方根数が実数上に確かにあるという前提に基づけば単に√2は(√2)^2が2になる性質を持った無理数、 といった形で取り扱えば十分だし、「√2は手続きだ」は言い過ぎじゃないかな。 それを言い出したらほぼ全てが手続きになってしまう。「数学的に同値」というのは「√2は手続きでも表せる」ってだけでしょ。 >>264 4次元の立方体なんてイメージとしての意味をなさないだろ。w というか各辺が4mの 4次元立方体なら「各辺の長さ=4m」且つ「各々の辺が互いに直行する」というだけの話だから、 Leng(a,b,c,d) =(4,4,4,4) cross(a,b) =true ; cross(a,c,)=true: cross(a,d)=true; ってことだけだろ。 性質として体積は4^4 とか表面積は=ん?になるとか 一寸考えれば誰でもイメージを膨らませることはできる。 >>269 一応ね、 4次元超立方体同士がすれ違うときに 接空間を頭の中に描けるかどうかかな さらにそれらが自転していたらどうかとか モダンなC++はnewしたのdeleteしなくても自動でやってくれるって聞いたけどガセ? ちゃんとスマポ使わないと漏れますよね? プロセス終了させたときにdeleteされるとかそんなオチ デストラクタが走らないからそれもないか newしたポインタはスマポで管理して自分でdeleteを書く必要がないっていう話が 文章読めない人の中でねじまがったんだろ スマポは自分でメモリーを管理するが、GC方式は管理をGCに任せる。 入門書ロベールで使い方の説明もなくunsigned charという型をでキャスト演算してるのですが unsigned charはcharより沢山文字が格納できる型ってことであってますか? またsize_tは整数型ってことであってますか? あってないですか.. ロベールにもろくに説明ないので弱りましたね(+_+) Size_tはアドレスを整数値に直すのに使ってたり関数の戻り値に使ってる例題があったので 整数を表すなにかと思ってたんですが違ってます、か ググってみてもイマイチ分かりません https://www.wdic.org/w/TECH/size_t ロベールって人の本は読んだことない(ネット公開版は少し見た)けど、 もっと先に進めば unsigned の使いどころとか size_t の説明とかが 詳しく載ってるって構成じゃないの? この時点でコードの細かい部分まで理解する必要はない、てな感じで。 疑問は疑問として(忘れずに)保留しておいて、とりあえず読み進むのも手かと。 char ch='C' cout<<(int)(unsigned char)ch<<endl; これは何をやってるコードなんですか?キャストって2つ一変に使えるんでしょうか。 特にコード自体に意味はなく文字は数字で表現されてると伝えたかったんでしょうか? ロベール入門は章の冒頭から応用みたいな例題出すから意味がわからなくなります 符号つき整数や符号なし整数のビット表現とかわかってないと、難しいんちゃうか? でも、言語仕様的にはビット表現に関する規定ってあんまりないんよね。 未定義な部分や処理系定義な部分もあるので、 ビット表現で考えていたら言語仕様的には実は未定義みたいなのに引っかかってそれはそれでぐぬぬぬぬってなることもある。 char については歴史的事情でややこしいのは確かだと思う。 char が符号付きか符号無しかは処理系定義だが、 char が符号有りだったとしても符号無しだったとしても signed char とも unsigned char とも違う独立した型になっている。 >>283 char が符号付きとして定義されていた場合に int にそのままキャストすると符号拡張されるから、 それを抑制するためにいったん unsigned char を経由したのではないかと考えられるが、 入っている値が 'C' であることが確定しているならば負数ではない値で表されることは保証されているので、 unsigned char にキャストする意味なく、いきなり int にキャストしても結果は同じ。 charの変数chを(ASCII文字でなく)1byteの数値を格納するために使う場合、 単なるcharがsignedかunsignedかは処理系依存だから、 変数に格納された値を正整数(一般に0-255)としてダンプしたいときは いったん unsigned char にキャストしてから int にキャスト、 すなわち (int)(unsigned char)ch と書くのが確実であり良い習慣である。 ……てな感じかなぁ。おそらく初心者にはサッパリ分からないだろうけど。 static_cast<int>(static_cast<unsigned char>(ch)) じゃろとか そもそも 0-255 の範囲の数値なら unsigned char で変数宣言すべきとか、 ツッコミどころも色々あろうが、きっと後のページで説明されるよね。 unsigned charに変換しとけば intには勝手に変換される >>287 いや、その点は試したんだ。俺の環境では… char ch = 'C'; cout << (int)(unsigned char)ch << endl; // 67 と表示される cout << (unsigned char)ch << endl; // C と表示される 少なくとも unsigned char が必ず int に変換されるとは言えない。 自動的に変換される処理系もあるかもしれんが、それはそれ。 >>287-288 >>283 のケースで int への明示的キャストを外すと int へは変換されない。 std::operator<< がいくつかの基本的な型に対応するようにオーバーロードされている内には unsigned char のシグネチャを持つものも用意されているので、 unsigned char 型の引数が与えられればそのままマッチする。 変換が挟まる余地はない。 たびたび失礼。 「試すんじゃなくて規格でどう動くべきか語れ」と言われればその通りだけど、 俺の能力を超えているということで。より有能な人の援護を期待。 >>282 ->>285286 ありがとうございます せっかく回答貰ったのですがunsigned charがどういう型なのかとかそういった説明が 本書で無いのでやはり何度読み返しても理解できませんでした 今は文字を符号なしの整数に直すおまじないってことで覚えておこうと思います まず補数についてお勉強しなさい まずそっから そしてそれを8bit、16bit、32bitで表現するとどうなるか 考察しなさい わかった? https://ideone.com/gFxr1T どっかから拾ってきた関数のソース(なんかのlibcのソース)をコピペして signed charとunsigned charの2進表現をダンプしてやったから 補数のお勉強が捗ったら、あとで参考にしなさい 繰返すが、言語仕様上はビット表現についてたいした決まりがあるわけではない。 表現できる範囲に着目した方が理解しやすいんでないかなぁ。 決まりがなかったら ビット演算なんかできない バカのいうことなんか ほっといていいからな 実際に決まってないもんは決まってない。 1 の補数を使うようなのも許されるし、実際に存在する。 ポータビリティに配慮しなければなんでも出来るのが C/C++ の良いところだが、 ガチで規格を把握しようとすると未定義の罠だらけなんよな。 きっとバカのオツムでは リトルエンディアンとビッグエンディアンの計算機では ビット演算の結果がかわる もしくは変わるようなクソみたいなコードを書く もう察しがつくのが怖いわ。。。 少なくとも >>293 の結果は言語仕様的に保証されない uint32_t aho; unsigned char* baka = (unsigned char*)&aho; 知恵遅れはこんなことを平気でする そして計算機によって結果がかわっておかしいおかしいとかいうワケ 数値のビット表現に2の補数が使われるとは限らないってだけの話な。 >>292 キャストの必要性と負の数の内部表現は全く関係ないように思うけど 負の数の内部表現は 少なくとも以下の3種類は存在する 1の補数 2の補数 符号ビット マイナスゼロはトラップ値として使ったりする https://ideone.com/ub97A1 すいません↑の29行目のコードって何してるんですか? int size = sizeof student / sizeof *student; sizeofで studentと*studentが3に化けて 3,3で割り算して1じゃないんですか 意味がよく分かりません; >>304 配列の定義が見えてる場合 "sizeof 配列名" は配列全体の総バイト数になるのよ。 対して "sizeof *配列名" は "sizeof 配列名[0]" と同じで配列要素1個のバイト数。 配列全体のバイト数 / 配列要素1個のバイト数 == 配列の要素数 配列の要素数を知るためのイディオムだな。 ちなみに sizeof student も sizeof *student も 3 にはならないと思うよ。 むしろ sizeof student / sizeof *student の計算でようやく 3 が得られる。 >>304 配列の要素数を計算しているかと sizeof studentは、配列のバイト単位の長さ sizeof *studentは、student型のバイト単位のサイズ >>305-306 これ割り算じゃないんですね なんとなく理解できました。ありがとうございます この方法を使うと配列が増えてもループのとこ書き直さなくてもいいということですか >>307 割り算だよ バイト単位で配列のサイズ(個数)を算出しているだけ >この方法を使うと配列が増えてもループのとこ書き直さなくてもいいということですか そう ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる