【初心者歓迎】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/ C++じvtable参照することになるから遅いだろ >>216
セットする値の名称にする
例えば三角形を表すオブジェクトで底辺と高さをセットするのであれば、base()とheight()になる
プロパティとして使うのだから、setXXX()みたいに書かなくてもいい
setter単独で存在することはありえないからgetterも設けること
setterって余り必要ない
コンストラクタからの初期化で十分の場合が多い 2の累乗でないときのmod演算の高速化の方法、何かありませんか?
そこらへんはコンパイラで最適化されるんですかね >>225
法を2進数にしたときほとんど1かほとんど0なら手間の少ない方法はある。
法が固定で何度も剰余を取るならモンゴメリリダクションがある。
どちらも乗算はそれなりに必要。 ユニークポインターにキャラの可変配列をヒープからとってリセットしたはいいけど、デリーターって簡単に実装/定義できる?例が欲しい。 mutex g_Mtx;
int g_Val = 0;
int Func( int A, int B )
{
int Val = A * B;
lock_guard<mutex> Lock( g_Mtx );
return g_Val = Val;
}
void ThreadFunc0()
{
} mutex g_Mtx;
すみません、途中で送信してしまいました。
int g_Val = 0;
int Func( int A, int B )
{
int Val = A * B;
lock_guard<mutex> Lock( g_Mtx );
return g_Val = Val;
}
void ThreadFunc0()
{
int Val = Func( 2, 3 );
// Valを参照する処理
}
void ThreadFunc1()
{
lock_guard<mutex> Lock( g_Mtx );
// g_Valを参照する処理
}
上記のようなスレッド関数が非同期に実行されるとき、
Func()はスレッドセーフ(g_Val書き換え中に参照されない)でしょうか?
(1)lock_guard<mutex>によるミューテックスロック
(2)g_Valの書き換え
(3)戻り値を読み出し元スレッドにコピー(あるいはムーブ)
(4)lock_guard<mutex>がスコープから外れアンロック
というシーケンスを期待しています。 事情があって下記の型の関数を、
void Func1(char a);
下記の型の関数ポインタに代入して呼びたいと思っています。
int*(*p)(int*);
p = (int*(*)(int*))Func1;
p((int*)123);
動作としてはFunc1(123)と呼んだときと同じものを期待しており、
試したところそれっぽく動作しているのですが、
致命的な問題等あります?
"暴走の危険あり"など。 スタックに積むサイズは通常int
long longとかで無ければ実害は無い >>233
C11の6.3.2.3の8によると、the behavior is undefinedだ。
たとえばcharが4バイトに自動昇格して、ポインタが8バイトだったりすると、
どうなるかわかったもんじゃない。鼻からなんちゃらだ。
C++は知らん。 sizeof(int) != sizeof(int*)の場合(例えばx64)、どうなるかな? そうそう、undefinedのあとはほんとに何が起きるかわからんよ。
コンパイラが何をしでかしても文句言えない。
たまたま今の環境で動いても、明日コンパイラを更新したら挙動が変わりうる。 「事情があって」の事情を解消する方が安全だと思うけど…。
void Func1(char a); を呼び出すラッパ関数を使うのはどうだろ?
int* Func1_wrapper(int *p)
{
uintptr_t arg = (uintptr_t)p;
Func1((char)arg); // 縮小変換が危険
return NULL;
}
int* (*p)(int*);
p = Func1_wrapper;
p((int*)123); // 明らかに不正アラインメントだが >>233
関数ポインタ同士は互換で、お互いにキャストすることは許される。
が、呼ぶときは元の型にキャストしなおしてからじゃないとあかん。 C++で窓出してプログラム組みたい時ってどういう風にするもんなんでしょうか
windows.hで一つ一つボタンの位置を設定してハンドルやらコールバックと格闘するもんなんでしょうか
それとも何か気の利いた便利なライブラリとかがあるんでしょうか
というかこの手のライブラリやフレームワーク的なものを探したりしたい場合はどういう場所から情報を集めるものなんでしょうか
それっぽいキーワードでgoogleで検索して探そうとしても上手く情報を見つけられないのですが、根気よくページを確認していくしかないのでしょうか >>240
基本的には win32api を使うことになり、私は C++ からwin32api( ::DefWindowProc() とか)を個別呼び出している
気の利いたライブラリのことはよく知らない やっぱりそういう感じになるんですね
頑張って勉強します >>240
Windowsに特化するなら Win32APIのほかにMFCやWTLや.NET framework(C++/CLIで良ければ)などのライブラリを使う
サードパーティならC++ BuilderのVCLとかあとはクロスプラットホームのQtとかGtk+とかwxWidgetsとか他にもあると思うけど
最近はデスクトップアプリが落ち目なのでこれという定番はなくて目的に応じて分散しているのでは?
自力で情報が集められない程度ならC++でGUIなんて止めとけという気がしないでもない vs2010以降ならWIN32SDKベースでも雛型吐いてくれるだろうに >>240
ボタンの配置などは、リソースエディタでダイアログテンプレートを作ってDialogBox関数を呼べば、細かい調整ができる。
イベント駆動やメッセージ送信などについては、<windowsx.h>で提供されるメッセージクラッカーやマクロを使えば便利になる。
私が複雑なことをする場合は、MZC4という自作のクラスライブラリを使ってる。 HANDLE_MSGマクロによるメッセージクラッカーという仕組みを使えば、ウィンドウプロシージャやダイアログプロシージャの記述が楽になる。
私はさらに、HANDLE_MSGの呼び出し先の関数の入力を楽にする自作のMsgCrackというツールを使っている。 WinRT が綺麗にまとまってると思う。
https://github.com/Microsoft/cppwinrt
Windows API を現代的な C++ に合わせて整理したものなので、
C++ 的にある程度まともな感じがする。
昔は仕方がなかったんだろうけど、
今にしてみればメッセージクラッカーっていかにもクソダサい方法だよな〜。 Win32APIスレは限定的だからGUI一般スレみたいなのの方を紹介しようと思ったが面倒なので
次の方どうぞ
↓ 何度も呼ばれる関数内ではローカル変数をstaticにした方が速いのですか? >>254
誤差だ、
プログラミングスタイルを曲げてまですることではない 皆様はプログラムを遅くし過ぎない為に気をつけている事などありますか?
速さを突き詰める為の工夫というより、誤って異常に処理時間のかかるようなプログラムを作らないようにする為にはどのような事を意識すると良いのでしょうか staticの方が速い理由なんて一つも無いような
あまり呼ばれない場合はstaticの方が遅いよね、キャッシュ的に
マルチスレッドで邪魔だし、必要がある時以外は使うもんじゃないよ >>258
多分、メモリを毎回確保し直す事や、コンストラクタを何度も呼ぶ事により処理が遅くなると考えたのではないでしょうか >>257
実行速度は推測ではなく測定することが鉄則だから
出来ることは気になったときに正しく測定出来るようにすることくらいだ >>257
ファイルアクセスのような重い処理とか深いループの中の計算処理とかは必要に応じて適切なデータ構造やアルゴリズムをあらかじめ検討しておくけど、頻度が少なく問題にならない箇所は分かりやすさ実装しやすさ優先で無理に速度は追求しないかな。
あとは将来的に性能改善が必要になることもあり得るから基本的には柔軟性のある変更に強い設計を普段から意識しておくとか。 計算量とかメモリ使用量のオーダーは気にするけど、オーダーが変わらないレベルの差はそんなに気にしてもしょうがない。 待て待て、>>257は速度追求の話ではないだろう
無駄なループを通らせないとかそういう話でしょ? エッジケースで極端なことになってしまうって話かな?
そういうのは単に気をつけるしかしゃーない。
発覚したときに直せるような体制にしておけ〜 >>257
とりあえず注意すべきは線形探索かな
何も考えずに使われると素敵なことになる クラスAのメンバ関数へのアクセスをクラスBのみに許すにはどうすればいいですか?
(メンバ関数をfriend指定するのはBがAのプライベートメンバにもアクセスできてしまうのでNGです) 自己解決
passkeyイディオムを使えばいいんですね
言語仕様でサポートしてほしい気もしますが できる人にとってはくだらないことなんだと思うのですが、
char* c;
char *c;
この2つは一緒なのですか? char * c;
とか
char
*
c
;
も含めて一緒 >>270
>>271
ありがとうございます
どちらが正しいのか、機能が違うのか、よくわかっていなかったのがスッキリしました >>270
前者だと
char* a, b;
って書いたとaとbの型が変わっちゃうから常に後者方式で
char *a, *b;
みたく書くことをオススメする ワイはアスタリスクを型名の方に寄せて、複数の変数の宣言をまとめないスタイルを推しておるやぞ。
char* a;
char* b;
まあ人によって色々やね。 C++ なら std::add_pointer を使うのも手やぞ。
普段から使うには綴りが長い気もするな。 ワイも後ろに寄せるスタイルの方が好きやな
別に自由ではあるけど、前に寄ってるとなんか違和感あるわ この話始まるとスレが荒れるわけだが。
俺は
char *a;
int & ref;
だ。 C++ だとスッポスッポ先生が (というより D&E の文中にあるコードが) アスタリスクを型名にくっつけるスタイルで書いてあるから、
設計者的にはこれが推しなんやろなて思うたんや。 そもそもCならまだわかるがC++になってもこの謎仕様が改善されてないのがおかしいわな char *a;派だがキャストは(char*)だな >>274
それな
前者は誰が流行らしたんだハゲか 変数との間に空白を入れるか入れないか選択の余地がある あと数字の後ろにも置けるよな確か
x[2]は2[x]でも普通に動作するらしい、使ったことはないが >>293
宣言の中の型としての*の位置を問題にしてるのだから、式の中での*が使える位置については別の話でしょ。 インデントってタブ文字使うよりもスペース使った方がいいんですか? >>297
見た目とコンパイル速度のどちらを優先するかによる。 タブコードはエディタの設定に見た目が左右されるので使わない方がいい エディタの機能向上による要素が大きいな。
インデントやその削除にキーを何度も叩かなきゃならない状態だったらTABがまだ主流だったろう。 >>294
他にも変な仕組みは色々とあるけど、これはひとつとして使いどころが思いつかんよな。 int a[10]; で a[5] でも 5[a] でも同じようにアクセスできるのは、
a[5] と *(a + 5) が同等で + 演算子の交換可能性から *(5 + a) も可、
それなら 5[a] も同じじゃなきゃ片手落ちだよね、って発想というか、
過去のコンパイラの実装とも関係がありそうな気がする。
もちろん、古いCコンパイラとのソース互換性が問題になるほど
みんなが使ってた書き方とは思わないけど。 i++ と ++iって最適化すればほとんど変わらないか、あるいは++iの方がちょっと速いくらいですよね?
なんでi++の方がデファクトスタンダードみたいになってるんでしょう?
ほぼ無視できる程度のメリットしかないとしても、++iと書くデメリットがないと思うのですが >>307
インクリメントの対象が整数しかなかった C からの習慣がなんとなく引き継がれてるだけ。
後インクリメントは気持ち悪いと考える人は少なくはないし、
値を使わないなら前インクリメントにするのは C++ では良い習慣だよ。 >>308
なるほど、最初はちゃんと意味があったんですね
納得できました
ありがとうございます Cでインクリメントやデクリメントに後置が使われがちな理由は
a = *p++; みたいなポインタの使い方で手が慣れたせいもあるかと思う。
C++では性能的な理由で前置が好まれたのは指摘のとおり。
個人的には、どっちでも構わない場面ではCでは後置、C++では前置で書くかな。
特に単純なforで++iと打つと、途端にC++で書いてる気がしてくる。 GCC 6.4.0 最適化なしで計測してみたけど、平均的な差は無いな 単純な整数型のインクリメントなら前置も後置もさが無いだろうけど、C++ではユーザー定義のクラスでインクリメントを実装できるから、
基本的には更新前のオブジェクトの状態の退避などの処理が必要な後置インクリメントよりコストの少ない前置インクリメントが好まれるのだと思うよ。 結果が使われないことが明らかな場合には後インクリメントのかわりに前インクリメントを呼び出すとかいったことをしても
ほとんどのコードは壊れないと思うんだけど、そういうルールを言語仕様に追加するのはもう出来ないかなぁ? まぁ、出来るなら既にやってるでしょ
ぶっちゃけ、よっぽどシビアに速度を求める訳でないなら前置後置の差なんて気にする必要無いんじゃないかなぁ そもそも速度を気にして
記述を変えるって
間違ってる気がする・・ 機能に対して糞重いソフトが多いのも
ソフトに対する価値観が変わったからか >>318
速度を気にするというのもあるけど、意味的にも無意味な処理をするってのがダサいだろ? ■ このスレッドは過去ログ倉庫に格納されています