「質問と回答」の編集履歴(バックアップ)一覧はこちら

質問と回答」(2009/06/16 (火) 11:56:56) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

・コメントのネストとは何か テキストには例がない。普通にcプログラムを書いているとわりとよく遭遇する。 int main() { int a=0; /* ②if文いらねーや。 if(a==0) /* ①ここに説明を書いた。 */ 実際はここでコメントが終了。 { } ②ここまでのつもり */ } ・誤植 ・アクセス指定子 ・真偽値 if, while, forの第二項は式の真偽値を評価する。 真偽値というのは、その式があっている(true)か間違っている(false)かということ。 式が論理式じゃない場合は、値が「0」の場合はfalse、「非0」の場合はtrue ・namespace stdとは 同じ名前は同じものと判断されるので、ライブラリを使うなど、異なるプログラム間で名前が衝突するとコンパイルとかリンクができなくなる。 c++ではnamespaceを作ることでライブラリの互換性を高めている。 ほかの言語ではmoduleとか呼ばれる時もある。 stdは標準名前空間で、たいていのc++を謳う環境にはくっついている。 たいていの環境で使える関数とかクラス群が定義されている。 (それでも微妙な互換性の問題があったりするらしいけど。 ・const ・インライン関数はよく使うものなのか よく使うというか、 高速化したいなら気合い入れて使わないと大して早くならない。 性能はけっこう環境依存なので、 高速化をやろうとしたら、実行されるコードに対していろんな種類のcpuごとにクロック数をにらみながらインラインを切り替えたりループを書き換えたり...みたいな作業がいるっぽい。 しかしそれよりもむしろアルゴリズムを改善したほうが速かったりする。 ・共用体 構造体がデータを並べて保持するのに対して 共用体はデータを重複させて保持する。 メモリの少ない環境とか、大量のメモリを消費するプログラムに使われたりする。 いわゆる、ゆとりには扱えない代物だが、メンテナンス性は微妙。 ・enum 中身はintとかの形で保持されるが、値のとれる範囲を制限するのに結構有効。 #define EULAR 1 int a=EULAR; if(a==EULAR) とかよりも enum demethod{EULAR, HEUN, RUNGEKUTTA}; demethod a=EULAR; if(a==EULAR) とかのほうが間違ってたらコンパイルエラー出るし結構お得。 ・線の描画 Bresenhamのアルゴリズムとか? コンソールでもできるだろうけどなんかいろいろめんどくさいぜ。 ・2章末の問3の意図が不明 確かに不明。 ・オーバーロードは名前が重複しているようだが コンパイル時に引数の型がチェックされ、内部というかオブジェクトファイルではそれぞれ別の名前としてコードが生成されるので、 実際には重複していないはず。 ・forとかでまわすiをグローバルにおくとどうなるんだ for(int i=0;i<100;++i) とかのなどの記述がたくさん出てくるが、iをグローバルにおくと効率化できないか。 ローカルにおくときのメモリ使用量のことを心配しているなら、スタックが解放されるタイミングで解放されるのでそれほど問題にならない。 また、forの内部で関数を呼び出す場合に、グローバルアクセスがあるとコールスタックを自前で作る羽目になっていろいろたいへん。 int i; int func2() { i=1; } func1() { for(i=0;i<100;++i) { func2(); } } とかすると、あっというまに無限ループが完成。古いBASICとかでローカル変数がなかったときはグローバル変数の使い回しにそうとう頭をひねって設計していたに違いない。 また、キャッシュとかレジスタのからみで、ローカル変数にした方がコンパイラはレジスタに乗せやすい。 ・デストラクタでメモリ解放するクラスのコピー コピーコンストラクタ、代入演算とかを参照 immutableというのもある。 ・実引数と仮引数の名前はテキストでは異なることが多い 同じでもいい。 ・配列のコピー、forとかを使わずに std::vectorとかは内部に隠蔽されている ・配列に宣言できる最大要素数 スタックフレームのサイズに関連 ・ソート、木、リストとかの基本的なアルゴリズム 知識はあった方がいいけど、基本的なアルゴリズムはすでにいろいろ用意されていることが多い。 ・new演算子とかで確保したメモリを解放しない よいosなら終了時にとりあえず解放してくれるけど、基本的には解放した方がいい。 長時間動き続けるプログラムや、確保・解放をたくさん繰り返すプログラムでは致命的。 ・2次元配列でスタックに確保した領域は、連続が保証されているか 保証されている ・代入演算子の戻り値 a=1 などの式のデフォルトの戻り値は代入された値で、この場合は1 代入演算子のオーバーロードを行うとこの限りではないけど、これにはずれると使いにくくなることが多い。 デフォルトの形の代入演算子はチェインができるところが便利で a=b=c=0 とかやると cに0を代入 bに(c=0)すなわち0を代入 aに(b=0)すなわち0を代入 の順で評価されて、全部に値が入る。 ・参照とポインタは原理的にどこが違うのか C++の参照は変更ができないのとNULLがとれない。それ以外は同じようなもの。 NULLは場合によっては無理矢理とることもできるだろうけど、やらないほうがいいのは確か。 コンパイラの実装としてポインタを使うこともあるし、単に別名をつけるだけのときもある。 別名をつけるだけにできるなら、コンパイラとしてはさらなる最適化がより簡単に可能になるはず。 というわけで、C++ではできるだけ参照を使うことをおすすめしてみる。 ----
・コメントのネストとは何か テキストには例がない。普通にcプログラムを書いているとわりとよく遭遇する。 int main() { int a=0; /* ②if文いらねーや。 if(a==0) /* ①ここに説明を書いた。 */ 実際はここでコメントが終了。 { } ②ここまでのつもり */ } ・誤植 ・アクセス指定子 ・真偽値 if, while, forの第二項は式の真偽値を評価する。 真偽値というのは、その式があっている(true)か間違っている(false)かということ。 式が論理式じゃない場合は、値が「0」の場合はfalse、「非0」の場合はtrue ・namespace stdとは 同じ名前は同じものと判断されるので、ライブラリを使うなど、異なるプログラム間で名前が衝突するとコンパイルとかリンクができなくなる。 c++ではnamespaceを作ることでライブラリの互換性を高めている。 ほかの言語ではmoduleとか呼ばれる時もある。 stdは標準名前空間で、たいていのc++を謳う環境にはくっついている。 たいていの環境で使える関数とかクラス群が定義されている。 (それでも微妙な互換性の問題があったりするらしいけど。 ・const ・インライン関数はよく使うものなのか よく使うというか、 高速化したいなら気合い入れて使わないと大して早くならない。 性能はけっこう環境依存なので、 高速化をやろうとしたら、実行されるコードに対していろんな種類のcpuごとにクロック数をにらみながらインラインを切り替えたりループを書き換えたり...みたいな作業がいるっぽい。 しかしそれよりもむしろアルゴリズムを改善したほうが速かったりする。 ・共用体 構造体がデータを並べて保持するのに対して 共用体はデータを重複させて保持する。 メモリの少ない環境とか、大量のメモリを消費するプログラムに使われたりする。 いわゆる、ゆとりには扱えない代物だが、メンテナンス性は微妙。 ・enum 中身はintとかの形で保持されるが、値のとれる範囲を制限するのに結構有効。 #define EULAR 1 int a=EULAR; if(a==EULAR) とかよりも enum demethod{EULAR, HEUN, RUNGEKUTTA}; demethod a=EULAR; if(a==EULAR) とかのほうが間違ってたらコンパイルエラー出るし結構お得。 ・線の描画 Bresenhamのアルゴリズムとか? コンソールでもできるだろうけどなんかいろいろめんどくさいぜ。 ・2章末の問3の意図が不明 確かに不明。 ・オーバーロードは名前が重複しているようだが コンパイル時に引数の型がチェックされ、内部というかオブジェクトファイルではそれぞれ別の名前としてコードが生成されるので、 実際には重複していないはず。 ・forとかでまわすiをグローバルにおくとどうなるんだ for(int i=0;i<100;++i) とかのなどの記述がたくさん出てくるが、iをグローバルにおくと効率化できないか。 ローカルにおくときのメモリ使用量のことを心配しているなら、スタックが解放されるタイミングで解放されるのでそれほど問題にならない。 また、forの内部で関数を呼び出す場合に、グローバルアクセスがあるとコールスタックを自前で作る羽目になっていろいろたいへん。 int i; int func2() { i=1; } func1() { for(i=0;i<100;++i) { func2(); } } とかすると、あっというまに無限ループが完成。古いBASICとかでローカル変数がなかったときはグローバル変数の使い回しにそうとう頭をひねって設計していたに違いない。 また、キャッシュとかレジスタのからみで、ローカル変数にした方がコンパイラはレジスタに乗せやすい。 ・デストラクタでメモリ解放するクラスのコピー コピーコンストラクタ、代入演算とかを参照 immutableというのもある。 ・実引数と仮引数の名前はテキストでは異なることが多い 同じでもいい。 ・配列のコピー、forとかを使わずに std::vectorとかは内部に隠蔽されている ・配列に宣言できる最大要素数 スタックフレームのサイズに関連 ・ソート、木、リストとかの基本的なアルゴリズム 知識はあった方がいいけど、基本的なアルゴリズムはすでにいろいろ用意されていることが多い。 ・new演算子とかで確保したメモリを解放しない よいosなら終了時にとりあえず解放してくれるけど、基本的には解放した方がいい。 長時間動き続けるプログラムや、確保・解放をたくさん繰り返すプログラムでは致命的。 ・2次元配列でスタックに確保した領域は、連続が保証されているか 保証されている ・代入演算子の戻り値 a=1 などの式のデフォルトの戻り値は代入された値で、この場合は1 代入演算子のオーバーロードを行うとこの限りではないけど、これにはずれると使いにくくなることが多い。 デフォルトの形の代入演算子はチェインができるところが便利で a=b=c=0 とかやると cに0を代入 bに(c=0)すなわち0を代入 aに(b=0)すなわち0を代入 の順で評価されて、全部に値が入る。 ・参照とポインタは原理的にどこが違うのか C++の参照は変更ができないのとNULLがとれない。それ以外は同じようなもの。 NULLは場合によっては無理矢理とることもできるだろうけど、やらないほうがいいのは確か。 コンパイラの実装としてポインタを使うこともあるし、単に別名をつけるだけのときもある。 別名をつけるだけにできるなら、コンパイラとしてはさらなる最適化がより簡単に可能になるはず。 というわけで、C++ではできるだけ参照を使うことをおすすめしてみる。 ・演算子のオーバーロード ・オーバーロードのあいまいさ ・関数のアドレス ・constについて ・staticについて ・仮想基本クラスについて ----

表示オプション

横に並べて表示:
変化行の前後のみ表示: