【初心者歓迎】C/C++室 Ver.102【環境依存OK】
■ このスレッドは過去ログ倉庫に格納されています
エスケープシーケンスやWin32APIなどの環境依存なものもOK
そのような質問は必ず環境を書きましょう
半角空白やタブでのインデントはスレに貼ると無くなります
コードを貼れる所
http://codepad.org/
https://ideone.com/
前スレ
【初心者歓迎】C/C++室 Ver.101【環境依存OK】
https://mevius.5ch.net/test/read.cgi/tech/1500329247/ 4ビットCPUだとcharは4ビットと思ってんのか? >>341 >>346
不都合と言う程の不都合か分からないけど、
単なる char が signed char のコンパイラで、例えば str[i] == -1 の時、
printf("%02X ", (unsigned char)str[i]); なら表示は "FF "
printf("%02X ", str[i]); だと表示は "FFFFFFFF " (intが32bitの環境)
てな具合に表示結果が指定桁数とずれて見苦しい、という現象が起きる。
ただし void DumpCode(const char* str) でASCII文字列しか扱わないなら、
意図せずASCII以外(漢字など)を含んだ文字列を引数に与えたときに
「見苦しい表示結果」のおかげで関数の使い方の間違いに気付きやすい。
よって (unsigined char) のキャストをしない方が好ましい、て考え方もある。
>>360
ARM で GCC だと、単なる char は unsigined が普通みたい。
元のCPU設計で符号付8bitが拡張機能だったことと関係あるとかないとか。 4bitのcharか、アルファベットが表現できないな
まぁ、341の例だと渡されるポインタ配列が文字コードの範囲内ならキャストは要らんね
なんかの理由で文字コード外の数値が入ってきた時に文字揃えがズレる事を嫌って一応キャストしたって感じだとは思うけど int *p = new int[100];
delete[] p;
delete[] p で int 100個分の領域を解放するのだと思いますが、
どうやって、 p が int 100個分の領域を指していると分かるのでしょうか?
p は単なる int 型へのポインタです。 >>366
つ -fsigned-char/-funsigned-char スタックオーバーフローが起こった時に、すぐにエラーが起こらない可能性がある
そうですが、なぜ、エラー終了にしないのでしょうか? >>368
良くある実装としては
newが返すアドレスの前にヘッダ情報がある 素人考えだと並のOS環境ではスタックオーバーフローは自動伸長に失敗してアドレスを割り当てられない時に起こると思うから直ぐにエラー終了しそう
バッファオーバーフローの場合は割り当てたメモリとバッファ境界がミスマッチなら直ぐにエラー検出できないとしても仕方がないけどこれは質問とは別の話 配列への添え字アクセスの計算量はO(1)の定数時間とのことですが、これは通常の変数へのアクセスと同じということでしょうか?
例えばint型配列のfooとint型変数のbarがあったとして、
int n = foo[10000]; と
int n = bar;
の速度は同じですか? 添字の値にかかわらず一定
foo[10000] と foo[1] が同じって話だぞ >>375
ありがとうございます
だとすると、同じ添え字に何度もアクセス(読み取りのみ)する場合、一旦変数に待避させてその変数を参照した方がいいですかね? レッツ実測&吐き出したコードを確認
最適化具合でも全然ちがう >>377
吐き出したコードってどうやって確認するんですか? >>371-372
ありがとうございました。
そのあたりのことを詳しく書いてある本はありますか? >>377
確かにそうですね
ありがとうございます、やってみます >>378
使っている環境による
機械語一歩前のアセンブラも出力するオプションで出てきたアセンブラとデータシートから推定する
もっと前のアルゴリズムの検討は済んでて、
もはや、枝葉を削ってでも速度を出さなきゃいけないという最終段階の話だよね? >>343-344
char 型が符号付きであってもなくても格納可能な範囲という意味では 0 〜 127 であると思って使ってれば間違いないのは確か。
あと、厳密にはマイナスの表現に 1 の補数を使ってる環境は有りうるので
char が符号付きだとしても -127 〜 127 しか表現できないかもしれない。
>>345
言語仕様では文字がアスキーコードとは保証してないんだ。
ほとんどの環境ではアスキーコードかそれと互換な文字コードだろうけど、
EBCDIC とかでも言語仕様には違反しない。 >>373
並のOS環境って何だよwww
一般的なMCUのほとんどは
アドレス変換テーブルの仕組みがなく
スタックオーバーフローを検出するハード的仕組みも無い 二つスレッドがある
片方はstd::queueにつんで、もう片方はそれを取る
これで詰まれた瞬間に取るにはどうするのがいいのかな?
簡単に作るなら、無限ループでスリープ挟みながら取り続けることだけど、無駄も多いから積んだのをトリガーに取りたい
環境はg++とVC++です >>379
stackoverflow で、たまたまアクセスしたメモリに、
どんな値が入っているかは、誰にも分からない。
単に前に入っていた値が、入っているだけだから
その値が、たまたまCPU 命令にあれば、CPU を実行するから、
エラーになるのは次の命令以降になる
一方、CPU命令に無ければ、不正な命令となり、即座にエラーとなる スタックのメモリ領域がこの範囲からこの範囲というように管理はしていないのですか? >>387
昔汎用メッセージポンプを検討したときのサーベイにstd::condition_variableと書いてある。
注意としてspurious wakeupというのも書いてある。
もうすっかり忘れてしまって何のことだか自分でも思い出せないのだが、「条件変数」というのがキーワードになるようだ。 >>389
ページ単位ではしていることがある。
OS がメモリの割付を管理していて、
足りなければ追加で割り当てたりもする。
割り付けてないメモリ空間に変に触ったら検出できる。 >>389
スタックエリアの管理は当然してる
オーバーランの監視は環境次第
ハード的に仕組みがあるものもあし
ソフトで(コストをかけて)やる場合もあるし
全くしない環境もある 今のWindowsとかLinuxとかならもちろん瞬時にわかる 最近のC++ってかなり進化していてTaskとかLinqなんかもできるんだろ? PCだとC#があるから
C++は使わないが組み込みだとC++を使いたい。CからC++に変えてみようとおもっってテスト
してみたことがあるが、メモリーを食い過ぎてStringはつかえなかった。
どこまでなら使えるんだろ? なにか目安はないか? 組み込みなら自分で書いたものだけ使うというか
STLは一切使わないのが普通じゃないか? new/delete
例外
ラムダ式
は使わない
もちろん規模によるけど 組み込みってピンキリだからなんとも言えんわ
業務用複合機なんてそこらのパソコンより凝ったハード積んでたりするし STLってC#のLinq並みに表現力があるんだろうか? Linqは最初嫌いだったが使い始めて
見ると非常に便利で驚いた。C++のSTLは全然しらなかったがWikiを読んだらなんかかなり魅力
的に見えてきた。 内部で new / delete 使用している stl は使わないリストに入れず
new / delete は使わないリストに入れんのかよ… STLコンテナとSTLアルゴリズム
どっちの話をしているんだ コンテナ使わない有用なアルゴリズムってあるか
あるなら使いたいからご教授ください
min とかあるか >>403
内部でnew/deleteしてるものは当然含まれる
当たり前
そもそもヒープエリア自体無かったりするし
あってもアロケートのみで解放機能が無かったりする
小規模組み込みでメモリを確保出来ないなんてことは想定しないし
確保解放のコストもバカにならない
アドレス変換が無いから隙間だらけで連続領域が取れなくなるなんてことも心配したくない ヘッダファイルを作るときに、2重インクルードを防止するための対策を書けと本に書いてあります。
注意していれば、2重インクルードをせずに済むにもかかわらずなぜ、このような
対策をしなければならないのでしょうか? >>410
人間の注意力なんてクソザコだからだよ。 >>410
複数のヘッダで共通のヘッダの定義が必要な場合を考えてみようか header_1
header_2
…
header_n
で共通に必要なヘッダ header_a がある。
header_1
header_2
…
header_n
のそれぞれの中で header_a をインクルードしている。
header_i と header_j (i ≠ j) が必要なファイル file1 がある。
というような状況でしょうか? 👀
Rock54: Caution(BBR-MD5:0be15ced7fbdb9fdb4d0ce1929c1b82f) あなたはstdlib.hとstdio.hの作者です
stdlib.hとstdio.hの両方でerrno.hが必要だとします
あなたはstdlib.h stdio.hの中でerrno.hをインクルードしますか?しませんか? >>416
入門書にこう書きます
「studio.h や stdlib.h をインクルードする際には、事前に errno.h をインクルードすること」
どうかなとは思うが実際こういう流儀でヘッダーファイル書く人も見かける 関数名にしろヘッダーにしろ6文字の縛りって何か歴史的理由があったのだろうか? vfprintfは八文字。文字数削るメリットがあった時代だったからな。 >>423
FORTRAN77は識別子の長さが6文字以下とかの制限があったからそれに倣ったんじゃないかな >>416-417
プリコンパイルヘッダが汚れたり無駄にでかくなったりするからな 以下のboost::factoryを使う練習用コードにおいて
https://wandbox.org/permlink/K1TIhC61VQztTbOd
map<string, boost::function<base* (int)>> factories;
とするとコンパイルエラーになり、ググって見つけた方法で
map<string, boost::function<base* (int const&)>> factories;
とすると何故かコンパイルが通り、問題なく動作します。
コンストラクタの引数が実際の int ではなぜ駄目なんでしょうか? >>417
実装依存のヘッダファイルの場合とか、ユーザに事前にincludeしろとは言えないケースもあるよ stackoverflow では boost::factory が引数の参照渡しを前提にしてるから、とあるな。
実際 factory 以外の普通の関数なら問題ないし dxd9みたいにincludeすると可笑しくなるヘッダもあるしなーω >>423-424
先頭6文字だけ見て一意に決まることが条件で、名前の長さ自体に制限はない、
じゃなかったかな。大文字小文字は同一視で。 _st とか _s とかごちゃごちゃ付き始めたころからつまらなくなった >>433
公式ドキュメントにはさらりと「技術的理由によりfunction objectに渡す引数はlvalueでないと駄目」と書いてあるのみなので、さっぱり理解できませんでした。
そもそもコンストラクタbase (int const&)は定義していないのにコンパイルが通るのが不思議・・・
結局 boost::bind(boost::factory<derived*>(), _1); が何しているのか理解しないと先に進めなそうですね。 >>439
引数のある関数の場合はboost::bindを使うのではないでしょうか?
いちおう公式にもその例が書いてあります。
ちなみにどんぴしゃな質問がstackoverflowにあり、Answerには親切にDemoまで付けてくれてて、
速攻で解決したと糠喜びしたんですが見事にコンパイルエラーでした。
https://stackoverflow.com/questions/37137117/passing-arguments-in-constructor-with-boost-factory >>440
引数を部分的に何かにbindしたfunctionを作るのがbindなわけで、
(add(a,b) の a だけ1にbindしてadd1を作るとか)
何もbindせず引数の順序も同じなら
factories["derived"] = boost::factory<derived*>();
で良い >>441
確かにbindのそもそもの目的はそれですよね>(add(a,b) の a だけ1にbindしてadd1を作るとか)
仰る通りの書き方でコンパイルも実行も通りました。
ただ、ググった限り引数のある場合はbindをかます例しか見つからなかったです。
「bindが必要」と明言してる人すらいて、結局よくわからないです・・・
その後、いくらコンパイルも実行も問題ないとはいえ実際のコンストラクタとは違うのを
boost::function<〜> に指定するのはなんとも気持ち悪く思い、試行錯誤したところ
boost::forward_adapter を使う方法を見つけました。
https://wandbox.org/permlink/D3Q75cgRNR43Nulc
ヒントとなったのは以下のサイトでした。
https://lists.boost.org/Archives/boost/2017/02/232695.php
正直なぜこれで通るのか完全には理解していませんが、とりあえずの解決とします。
ご助言どうもありがとうございました。 >>442
公式にドキュメントがあるだろう。
なんでググりまくるんだ? >>443
公式ドキュメントはこれです。
https://www.boost.org/doc/libs/1_66_0/libs/functional/factory/doc/html/index.html
ここに以下のような「stringキーzとコンストラクタのmapにコンストラクタを登録」するという方法が書いてあればよかったのですが・・・
map<string, boost::function<〜>> factories;
factories["derived"] = 〜
でもboostの公式ドキュメントはこんなものというか、隅から隅まで説明しないわからない素人はお断りってやつですよね。 質問です.
以下のようなことが書いてあるファイルを読み込んで,
文字列,数値,...,数値,数値...数値
...
str, a[0],...a[n-1],b[0],...b[m-1]
という配列に入れたいです.
nとmは可変の場合,どうすればよいか教えてください.
スッキリとした書き方が知りたいです.
std::string str;
double a[n],b[m];
です. std::string知ってるなら
std::vectorを使えば早かろう
std::vector<double> a, b;
a.resize(n);
b.resize(m);
a[0] = ... 可変の n, m が読み込む前に確定するのか
ファイルの記述内容から n, m が確定するのか >>447
今回はstringを見て,nとmを決めます.
str="a"ならn=2,m=3のような感じです.
>>448
読み込み方が分かりません.すいません.
Google先生に聞いてこんな感じのプログラムを書いてます.
std::string line;
std::ifstream infile("hoge.dat");
std::getline(infile,line);
sscanf(line.data(),...//どう書くの? void Show(const IntArray& array){
...
}
というような関数内で、 array の const メンバ関数ではないメンバ変数を変更しないメンバ関数を
使っているとコンパイルエラーになりますが、それはなぜでしょうか?
コンパイラーはarrayのメンバ関数がメンバ変数を変更していないことはソースコードから
分かるのではないでしょうか?
そういうチェックをするコンパイラを作るのは難しいからということでしょうか? const メンバ関数の中でメンバ変数の内容を変更しているとコンパイルエラーになります。
ということはどのみちメンバ変数を変更しているかどうかはチェック可能ということですよね? void Show(IntArray& const array) >>449
コンパイル単位を越えたらチェックするのは難しいし言語の壁を越えたら不可能に近いから
中途半端な事をするくらいならconst明示されてるかという線引きの方が分かり易い >>449
難しいというか不可能だからですよ
呼び出す関数はまだコンパイルされてないかもしれないしまだソースコードもないかもしれない >>449
メンバ変数を変更しないなら素直にメンバ関数にconst付けれや >>449-450 の質問者は、分割コンパイルにまだ慣れてないと思えるなぁ。
ソースファイルを分けてみればピンと来るかと。
片方をソースなしのオブジェクトやライブラリにしないとダメかな。 C#のフォームからオフィスを立ち上げ、オフィスを終了したら立ち上げたフォームに
戻るようにするにはどうした出来ますか? >>457
COM使えばできるけど、スレタイも読めないお前にできるかどうかはわからん そんなことは当たり前ですね。その方法が説明できますか? C#のことはC#のスレッドで尋ねればいいでしょ、てお話。
C/C++のスレッドに質問を持ち込むより確実で早いと思うよ。 あ、ごめん。++が#に見えた。でも普通は++を#に書き間違ったんだろうと判断すると
思うが。 ところでC++のフォームからオフィスを立ち上げ、オフィスを終了したら立ち上げたフォームに
戻るようにするにはどうした出来ますか? ■ このスレッドは過去ログ倉庫に格納されています