【初心者歓迎】C/C++室 Ver.106【環境依存OK】
■ このスレッドは過去ログ倉庫に格納されています
エスケープシーケンスやWin32APIなどの環境依存なものもOK そのような質問は必ず環境を書きましょう 半角空白やタブでのインデントはスレに貼ると無くなります コードを貼れる所 http://codepad.org/ https://ideone.com/ 前スレ 【初心者歓迎】C/C++室 Ver.105【環境依存OK】 https://mevius.5ch.net/test/read.cgi/tech/1556142878/ >>178 私のコメントに興味を持ってくれて嬉しい しかし、今、リアルの私は終わりのない忙しさで連日睡眠時間が 3 時間という有様だ… おそらく 11月1日2日3日の連休までにはこの忙しさも収束するだろうから、それまで気長に待っていてくれ給へ >>181 PASCAL と C を一緒にしてはいけない PASCAL は LL(1)パーサですべてが記述されている、という C にはない独自の美しさを誇っている C はセマンティクスに妥協しまくっておりシンタックスはボロボロだ、こんなものは私の求める美しさではない 高みを目指すのなら、C/C++ の「なあなあですませる」態度に決別するべき >>182 それは大変ですね。 便所にラクガキする時間をぜひ永眠もとい睡眠に使ってください! struct { char x; struct { char a : 4; union { char b : 2; char c : 2; }; char d : 2 }; }; こうやるとabcdは正常なんですがxの値がおかしくなります xの最初4ビットがa xの最後2ビットがd xの残り2ビットがbとcで共有 どうやればできますか? >>185 x も union に入れるといいかもしれない。 「xの残り2ビットがbとcで共有」については、間に union 挟む形だと ビットフィールドの割り付けが途切れちゃうから、 struct {a, b, d} と strunct {a, c, d} に 分ける必要があるかもしれない。 でもこんなことやりたくなるのはハードウェアレジスタの操作やバイナリフォーマットの操作ぐらいな気がして、 そうなると残念ながらビットフィールドや union 使った方法には移植性に難があるのであまりお勧めできない。 >>186 185じゃないけど、レジスタ設定でおすすめのやりかた教えてください。 ハードウェアありきでレジスタ構造再現するより、目的や意味で分類するソフトありきの方が読みやすいように思えたんですが このやりかたの利点てなんだろう。処理が早い? ポインタって*pは指し示したアドレスの先の値なのに 宣言のときに初期化するとchar *p=xxxx;はアドレスが入るって整合性取れてないなと思ってたら char* p=xxxx;って意味なのね >>187 符号なし整数型にビットシフトとビットマスクで。 移植性を考慮する必要が無いなら、出力コード見ながら調整したビットフィールドで望みの動作に できることも多くて、できてしまえばレジスタの定義も楽でレジスタアクセスするコードも読みやすいから、 それで済ませたくなる気持ちはわかる。 「目的や意味で分類する」というのはレジスタアクセスするコードの上に関数を作る話になると思うので、 レジスタアクセスの方法(ビットフィールドかシフト&マスクかなど)に関わらず好きに関数作って読みやすくすればいい。 >>186 > 間に union 挟む形だとビットフィールドの割り付けが途切れちゃう 納得しましたありがとう! >>188 そうだけど、宣言の文法上の結合規則では * は p の側に結合する。 宣言は char という型指定子と *p という宣言子から成り立っているのであって、 しかし char* という型の p が宣言されるので整合性という意味では やっぱりなんだか微妙という感はちょっとある。 もちろん慣れたら問題無い char a[] = "A\n"; char *p = a; *p = 'B'; char *q; q = a; printf("%s", q); >>191 VS2019がchar *p;をchar* p;に勝手に変更するので おかしいなと思ってたんだけど知ってみれば納得できるというか >>192 ポインタ難しい論の実際ってポインタより配列、文字列のせいって気がする。 char *p; か char* p; かでごねてる人って char *p[]; とか char (*p)[N]; とかはどうしてるんだろ >>195 どっちでもいいけどどっちかには揃えたくない? 自分で揃えりゃいい話だし 他人がどう書こうが関係ないし vsならvsに任せる 人間がやったらミスするんだから機械に任せる vs標準のフォーマットが嫌なら変えればいいが、変えた時点で標準ではないと認識しといて >>197 自分ではどう書くかは決めてるってことなんだよね? ソースの一部が入ると書き込めないな 何が琴線に触れてるんだろ #define LIST { \ { "a", "b", "c" }, \ { "aa", "bb", "cc" }, } char *(list[][3]) = LIST; これは便利 1. char *p; 2. char* p; 自分は(1)派だけど (2)を許すとしたら 3. char* p[]; (3)とか気持ち悪くない? 4. char(*p) [8]; (4)とかは? 破綻してるよね? ()を半角で書くと書き込めない? 普通に半角で書いてるよ >>202 とか()()()とか char(*p) [8]; 合わせ技がダメなんかな >>203 1で書くと>>188 がキモい件は? どっちもキモいんだからどっちでもいいだろ >>204 *の位置よりも、小分けに何度もレスするのが気持ち悪い。まとめて1回で書いてくれ。 好きにすればいいじゃない。 世の中的にはCは右、C++は混在が多いんじゃね。 C++なら生配列の使用はなるべく避けるし。 >>203-205 ワイは C++ では char* p; と書く派 (C では char *p と書く派) やけど char* p[]; とは書かんな。 ごく単純な char *p; の場合に限って char* p; の方がマシな気がするという話であって、 全体としてはもうどうにもならんほどグダグダやと思うておる。 >>217 結局、複合型とかconst修飾とか出てくると破綻するんだよね。だから右派。 たまに頑固な左派が「そんな変なものは使わない」とか言うけど、だったら*も止めてスマポだけ使ってろとw char* p, *q; ってなるやんって思うから右派 意味的にchar* p, q;がpもqもchar*型になるなら左 char *p 派の人は p を const にしたいときは char *const p になるの? >>221 右派にも親米と反米の二種類がありまして‥‥ 左派の破綻誤魔化しのために typedef が廃止されて using とか本末転倒過ぎる #include<stdio.h> void main() { int a = 9; double b = 2.3; printf("%d", a + b); } これを実行すると-1717986918になるんですがおかしくないですか %fだと想定通りになりましたが%dのときは11が出るんじゃないかと思うんですけど a + bはdouble型 %fはdouble型を出力する書式だから意図通りに表示される 一方%dはint型を出力する書式だからそこにdoubleを突っ込むとおかしな表示になる %dで正しく表示したければ次のようにa+bを明示的にintに変換する必要がある printf("%d", (int)(a+b)); >>225 丁寧な説明ありがとうございます %dにしても勝手に整数にはしてくれないんですね、なんか不便な気が。 それにしてもマイナスはどこから出てきたのやら 9+2.3=11.3 これの double の bit 表現が int だと敢えて勘違いして観ると MSB 1 で負の数になるんだろ %dなのに引数がdoubleなら今どきのコンパイラなら警告出すはず 見てないだけだろ #include <stdio.h> typedef union { unsigned char u[8]; double d; int i; } U; int main(void) { U x; x.d = 11.3; printf("%f\n", x.d); printf("%d\n", x.i); for(int i = 0; i < 8; ++i) printf(" %02x", x.u[i]); return 0; } /* 11.300000 -1717986918 9a 99 99 99 99 99 26 40 ttps://ideone.com/SNupdr */ ちなみに -1717986918 は 32bit int で 0x9999999a つまり big endian - little endian で byte 順が入れ替わって さらに 8 byte -> 4 byte で切られてる 謎解き、魔法を見せられたような鮮やかさでありました doubleやfloatはビットがこう並んでる ttps://upload.wikimedia.org/wikipedia/commons/d/d2/Float_example.svg 平たく言うと、その%dはこのfloatやdoubleのビットの並びを無理矢理整数にしてしまう つまり、書いた通りにしか動かない 忖度やお察しが起こって無いのが良いところ これが不便だと思うなら便利な言語を使うと良いよ 便利ってことは高機能ってことで、高機能ってことは裏でいろんな処理が走る必要があるってこと そんな処理走ってほしくない環境があるから今でもCが現役なだけ このばあい言語でなくライブラリの仕組みね 中で(int)vする指定子が用意されてればいいだけ >>224 この場合は double のビットパターンが整数として読み替えられたということで説明がつくみたいだけど、 言語仕様としては未定義なので別の結果になる可能性もある。 Windows では x86_64 上での引数の渡し方 (呼出規約) は浮動小数点には xmm レジスタを使うが、 引数が浮動小数点だけのときは整数レジスタの方にも値を入れておくというルールがある。 https://docs.microsoft.com/ja-jp/cpp/build/x64-calling-convention?view=vs-2019#varargs このおかげで浮動小数点を整数として読みだしても一応の整合性はとれるようになってる。 Linux などで使われる規約 (いわゆる System V ABI) ではそういう予防措置っぽいものがないように見える。 http://refspecs.linux-foundation.org/elf/x86_64-abi-0.95.pdf たぶんそのときにたまたま整数レジスタに入っている値が得られるだけなんじゃないかな。 英語がそんなにわからんから見落としがあったらすまぬ……。 手元に Windows しかないからオンラインコンパイラで試してみたんだけど、 実行のたびに違う値になる。 https://wandbox.org/permlink/voLHWPQmgwYDoSfT 未定義なものが未定義な結果になるのはある意味では「書いた通り」なんだが、 各環境の事情が絡んでくるから読み解くのは難しいね。 C++を使ってシューティングゲームを作ろうとしているものです。 https://bituse.info/game/shot/ こちらのサイトを参考にしてDXライブラリも使って作業をしているのですが https://bituse.info/game/shot/5 ただいまこちらの章でエラーが出てしまい行き詰っています。 背景を線画する章なのですがサイトの指示通りに新しいクラスを作って実行すると 1>------ ビルド開始: プロジェクト: gamegame, 構成: Release Win32 ------ 1>back.cpp 1>C:\Users\rikua\source\repos\gamegame\back.h(17,7): error C3861: 'LoadGraph': 識別子が見つかりませんでした 1>C:\Users\rikua\source\repos\gamegame\back.h(19,10): error C2065: 'MARGIN': 定義されていない識別子です。 1>C:\Users\rikua\source\repos\gamegame\back.h(23,22): error C2065: 'FALSE': 定義されていない識別子です。 1>C:\Users\rikua\source\repos\gamegame\back.h(23,2): error C3861: 'DrawGraph': 識別子が見つかりませんでした 1>control.cpp 1>main.cpp 1>プロジェクト "gamegame.vcxproj" のビルドが終了しました -- 失敗。 ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ========== このようなエラーが出てしまいます。 こちらが現在作成しているファイルの全てです。 http://whitecats.dip.jp/up/download/1603336402/attach/1603336402.zip パスワード1234 どなたか分かる方お願いします・・ すまん 398MBとか見てそっ閉じしたわ・・・ 各ヘッダが何をincludeしてるのか構造見てみて 他人だけど1234で削除したら削除出来ちゃったωωω >>242 申し訳ありません! ヘッダは今全部で5つありまして back.h control.h define.h pch.h player.h の5つです back.h includeなし control.h include "player.h" include "back.h" define.h include <windows.h> pch.h include "DxLib.h" include "define.h" player.h #include "pch.h" #include "player.h" それぞれは今このような形になっています 最後の #include "pch.h" #include "player.h" こちらの#は貼るときに消し忘れなので気にしないでください >>244 back.hにpch.hを追加で player.hのplayer.hはいらない でやってみて hoge.hファイルに#include "hoge.h"ってできたんか・・・ >>248 帰宅したらすぐに試してみます!ありがとうございます!! >>249 コンパイルエラー選手権でそんなんあったな >>248 すみません! player.hの内容は元々includeが一つもありませんでした! なのでback.hにpch.hを追加して実行してみると このようなエラーが出てきました 1>------ ビルド開始: プロジェクト: gamegame, 構成: Release Win32 ------ 1>back.cpp 1>control.cpp 1>C:\Users\rikua\source\repos\gamegame\define.h(16,13): error C2011: 'SHOT': 'struct' 型の再定義 1>C:\Users\rikua\source\repos\gamegame\define.h(16): message : 'SHOT' の宣言を確認してください 1>main.cpp 1>C:\Users\rikua\source\repos\gamegame\define.h(16,13): error C2011: 'SHOT': 'struct' 型の再定義 1>C:\Users\rikua\source\repos\gamegame\define.h(16): message : 'SHOT' の宣言を確認してください 1>player.cpp 1>プロジェクト "gamegame.vcxproj" のビルドが終了しました -- 失敗。 ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ========== >>252 すみません先ほどのエラーは 違ったものでした こちらが現在出ているエラーです >------ ビルド開始: プロジェクト: gamegame, 構成: Release Win32 ------ 1>back.cpp 1>control.cpp 1>main.cpp 1>pch.cpp 1>player.cpp 1>control.obj : error LNK2005: "public: void __thiscall BACK::All(void)" (?All@BACK@@QAEXXZ) は既に back.obj で定義されています。 1>control.obj : error LNK2005: "private: void __thiscall BACK::Draw(void)" (?Draw@BACK@@AAEXXZ) は既に back.obj で定義されています。 1>control.obj : error LNK2005: "public: __thiscall BACK::BACK(void)" (??0BACK@@QAE@XZ) は既に back.obj で定義されています。 1>main.obj : error LNK2005: "public: void __thiscall BACK::All(void)" (?All@BACK@@QAEXXZ) は既に back.obj で定義されています。 1>main.obj : error LNK2005: "private: void __thiscall BACK::Draw(void)" (?Draw@BACK@@AAEXXZ) は既に back.obj で定義されています。 1>main.obj : error LNK2005: "public: __thiscall BACK::BACK(void)" (??0BACK@@QAE@XZ) は既に back.obj で定義されています。 1>main.obj : error LNK2005: "public: void __thiscall PLAYER::All(void)" (?All@PLAYER@@QAEXXZ) は既に control.obj で定義されています。 1>player.obj : error LNK2005: "public: void __thiscall PLAYER::All(void)" (?All@PLAYER@@QAEXXZ) は既に control.obj で定義されています。 1>C:\Users\rikua\source\repos\gamegame\Release\gamegame.exe : fatal error LNK1169: 1 つ以上の複数回定義されているシンボルが見つかりました。 1>プロジェクト "gamegame.vcxproj" のビルドが終了しました -- 失敗。 ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ========== >>252 エラーが出る度に頭空っぽのまま教えてくださいって繰り返すのか? teratailで指摘されてる通り、まずは#includeとかヘッダファイルがどういうもので何のためにあるのか、何故エラーになるのか、解決するにはどうするか、入門サイトなり入門書なりで勉強してきなよ。 それで分からないことが出てきたら、またここで具体的な質問をすれば誰かが回答してくれると思うぞ。 たびたびすみません! control.hの中にお手本にはない同じ文列が2つあったので一つ消すと エラーがだいぶ減りました! 1>------ ビルド開始: プロジェクト: gamegame, 構成: Release Win32 ------ 1>control.cpp 1>C:\Users\rikua\source\repos\gamegame\control.cpp(11,1): error C2600: 'CONTROL::~CONTROL': コンパイラで生成された特殊メンバー関数を定義できません (クラスで最初に宣言されなければなりません) 1>プロジェクト "gamegame.vcxproj" のビルドが終了しました -- 失敗。 ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ========== >>254 ありがとうございます! もう少し勉強してみてまた質問したいと思います。 ヘッダのインクルード順に依存するようなプログラムになってるとか? C言語、C++の基本のヘッダファイルの役割は理解していますか? もし判らないのであれば、そちらの勉強を先にした方がいいと思います。 参考にしているサイトも、 > このページで学習するには、 > C言語とC++についての知識がある程度必要になります。 > 心配な方はトップページなどから、該当言語のページを選んで基礎を学んできてください。 と前置きがありますよ。 基本を理解せずに始めても、何度も同じような質問を繰り返して遠回りになるだけです。 >>246 有賀豚 >>253 の原因は player.c の中に back.c の中身がそのままコピーで繰り返されてるから >>257 それ以前の問題 こんなソース描いてる香具師が同じプロジェクトに居たら殴る 引っかかってるところよりずっと前で理解してないパターンは面倒くさい。 前提部分からの説明が必要だがそれを学ぶ気がないからこそこういう質問になるわけで、 親切に答えても徒労に終わるパターンなのが見えてる。 Java から C++ に流れてきた者ですが、Javaのインターフェース的なものは 多重継承で実現、ですかね? class Rectangle : pubilc Polygon {...}; みたいなクラス(他にも Polygon を拡張した Triangle とか Hexagon とかあるとします)で面積を返す area() の実装を要請して、 そういうオブジェクトだけに適用できるメソッドを定義したい場合、 class Area { virtual int area() = 0; } class Rectangle : public Sharpe, public Area { int area(); ..}; 的な? その後 doSomething(Area& area); といった呼び出しでこれらのオブジェクトを引数に? この場合 Polygon に area() を追加する手もありますが、Polygon でない図形のクラス でも area() の実装を要請する場合もあるならば、多重継承ということになるのかなと。 多重継承以外でも何かありますでしょうか。 >>263 仮想関数は動的ポリモーフィズムのためにある。 (最適化で消えることもあるけど) 実行時にディスパッチする仕組みなので、 使わないで済むならその方がいい。 つまり、その例なら doSomething をテンプレートにして型に制約 (メタ関数かコンセプトで) を付ける方が好ましい。 >>262 >学ぶ気がない >親切に答えても徒労に終わる 触っちゃいけない質問者って臭いで判るよな いきなりどこかのサイトのソース持ってきてコンパイルできません系が怖い オンラインゲームとかでも初心者狩りとかしてそうw 学ぶ気がないとか他人に原因を押し付けてるけど じゃあこのスレでインクルードやら宣言やらの仕組みから解説しろってのかい? それはさすがに入門書のひとつでも読んでくれなきゃ困るよ。 単純に説明の分量的にもね。 別にインじゃねえの 答えたくなきゃ答えなきゃいいだけだし マジでそれ 答えたくないならスルーすればいいのに余計な事を言うのが害悪 >>264 テンプレートですか、C++っぽいですね。メタ関数とか、いろいろ自分には新しいトピックが。 area() を実装しているかどうかは... is_callable とかでしょうか。 最悪制約をつけなくても area() がなければコンパイル時にテンプレート展開でエラーに なって、駄目なことはわかることはわかるんですよね? >>265 それはルートクラスの設計の話に見えるのですが、今回の場合はもう既に あるクラスの場合の話でして。その場合はインターフェースクラスを多重継承する のかな? というのが元の質問です。 >>272 まあ仮想関数使って多重継承でいいんじゃね 機能的には必要十分かと それより設計上の問題として Polygon : public Area{} という構造が適切なのかどうなのか疑問 分かりやすさとしては Rectangle : public Polygon{},Triangle: public Polygon{}・・・ という単なる形状のみの継承クラスと Graph {Polygon poly; int area();・・・} という別の目的で機能するクラスに分けたほうが整理されてる気がする >>272 制約を付けなくてもテンプレートを展開してダメだったらエラーになることは保証される。 まあ当たり前っていうかそうせざるを得ないもんね。 でも「(制約を満たさないので) マッチに失敗した」と「マッチして展開した結果にエラーがあった」は意味が違っていて、 結果的に失敗させることを意図するならなるべく前者で失敗させた方が使い勝手はいい。 答えたくなきゃ答えなきゃいいし 余計な事を言いたきゃ言えばいいよ ここをどこだと思ってんだよw >>276 は? 学ぶ気がないことが露骨なやつは嫌だよねって話をしてるんだろうが。 初心者叩きとか話をすり替えるなよカス >>276 初心者で一括りにしたら「やる気のある」初心者に失礼 こいつには質問しても得るものないから目合わせないでおこう と思うやつに限ってこういう反応してくるんだよなw >>277 >>277 >学ぶ気がないことが露骨なやつ ほんとこれにつきる リンカーの話とかもここでおkですか? とりあえずlinux系で、 動的ライブラリlibA.soが、別のライブラりlibB.soに依存しているときには, libA.so作成時、libA.soにlibB.soをリンクしておけば依存性が解決されますよね? (libA.soを使うプログラム作成時には、libA.soだけ指定すればよい) 諸般の事情で静的ライブラリlibC.aがあり、これがlibD.soに依存するのですが、 この場合、libC.aにlibD.soをリンクしてlibC.aを生成することはできない? ですか? libD.soは、libC.aを使ったプログラムの作成時にリンク、ということでおkですかね? これが正解だと、静的と動的で依存性を解決する場所(?)が違うんだなあと。 ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる