自分みたいなC++に中途半端な人にはとても有用だった。Cの細かいところとか落とし穴的なところを押さえるにもいいと思う。
C/C++迷信集 | 株式会社きじねこで読めるのかもしれない。
C++についてのみ。Cについては知識/経験なさすぎなのでスルー。
実行環境としてはVisual C++ 2013でWin32 コンソール アプリケーションで空のプロジェクトを作ってTest.cppなファイルにコードを書いてビルド&実行。
- 一重引用符の中には一文字しか書けない!?(p54)
- absは負の値を返さない!?(p123)
- ポインタを型変換してもアドレスは変わらない!?(p158)
- 配列や構造体をmemsetで一括ゼロクリア!?(p174)
一重引用符の中には一文字しか書けない!?(p54)
コード:// 一重引用符の中には一文字しか書けない!?(p54) #include <iostream> #include <ios> int main(int argc, char* argv[]) { const auto ns = 'a'; // 1文字の場合はchar型 const auto nm = 'abcd'; // 複数文字の場合はint型で値は処理系依存 std::cout << std::hex << typeid(ns).name() << ", " << ns << std::endl << typeid(nm).name() << ", " << nm << std::endl << std::endl; const auto ws = L'a'; #pragma warning(push) #pragma warning(disable: 4066) const auto wm = L'abcd'; // warning C4066: ワイド文字定数の文字列は無視されます。 #pragma warning(pop) std::wcout << std::hex << typeid(ws).name() << ", " << ws << std::endl << typeid(wm).name() << ", " << wm << std::endl << std::endl; return 0; }実行結果:
char, a int, 61626364 wchar_t, a wchar_t, a多文字リテラル(multicharacter literal)の存在とかそれがint型になるとか全く知らなかった。
これに関してはワイド文字は素直でいい。
absは負の値を返さない!?(p123)
コード:// absは負の値を返さない!?(p123) #include <cmath> #include <limits> #include <iostream> int main(int argc, char* argv[]) { const int x = std::numeric_limits<int>::min(); // -2147483648 トラップ表現 const int y = std::abs(x); std::cout << x << std::endl << y << std::endl << std::endl; return 0; }実行結果:
-2147483648 -2147483648説明されてみれば確かにそうなんだけど全く意識したことがなかった。これ踏んでるコードってけっこうありそうな気がするんだけどこれって初見なのでどうなんだろうと不安がある。
absなんか使った記憶ほとんどないけど使いまくりなfabsはどうだろうと確認してしまった。
ポインタを型変換してもアドレスは変わらない!?(p158)
コード:// ポインタを型変換してもアドレスは変わらない!?(p158) #include <iostream> class Foo { public: Foo() {} virtual ~Foo() {} }; class Bar { public: Bar() {} virtual ~Bar() {} }; class Baz: public Foo, public Bar { public: Baz(): Foo(), Bar() {} virtual ~Baz() {} }; int main(int argc, char* argv[]) { Baz baz; Foo *pfoo = &baz; Bar *pbar = &baz; Baz *pbaz = &baz; std::cout << "pfoo: " << pfoo << std::endl << "pbar: " << pbar << std::endl << "pbaz: " << pbaz << std::endl << std::endl; return 0; }実行結果:
pfoo: 001BF79C pbar: 001BF7A0 pbaz: 001BF79C結構初歩的なことな気がするけど知らなかった。正直恥ずかしい気とまずいコードを書いたことがあるかもしれない。
pfooとpbazの値が一致しないケースを作れない点で自分の低スキルぶりを再認識。
配列や構造体をmemsetで一括ゼロクリア!?(p174)
コード:// 配列や構造体をmemsetで一括ゼロクリア!?(p174) #include <iostream> struct Foo { char *c; int n; double d; wchar_t *wcs[10]; }; void write(const Foo& foo) { const char* x = reinterpret_cast<const char*>(&foo); for (size_t n = 0; n < sizeof Foo; ++n) { std::cout << int(*x++); } std::cout << std::endl; } int main(int argc, char* argv[]) { //Foo foo; //Foo foo = {0}; Foo foo = {}; write(foo); //Foo *pfoo = new Foo; Foo *pfoo = new Foo(); write(*pfoo); delete pfoo; //Foo *fs = new Foo[10]; Foo *fs = new Foo[10](); write(fs[0]); write(fs[1]); write(fs[9]); delete[] fs; return 0; }実行結果:
00000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000memsetとかstd::fillとかZeroMemoryを使ったりしてサーセン、理解or覚えてなかった。
0 件のコメント:
コメントを投稿