Twitterに投稿 はてなブックマークに追加 Google Bookmarksに追加

目次 >> C、C++

C、C++ Tips

ここでは、C、C++のTipsについて述べる

Tips一覧

  1. プログラムを実行しているホスト名を取得するには?
  2. Unixのターミナルの画面幅を取得するには?
  3. Unix系OSでディレクトリ内のファイル一覧を取得するには?
  4. Unix系OSでファイル、ディレクトリを削除するには?
  5. Unix系OSで実行優先度を取得するには?
  6. Unix系OSでタイムゾーンを取得するには?
  7. Unix系OSでCPU時間を取得するには?
  8. プロセスIDを取得するには?
  9. Visual C++でM_PIを使うには?
  10. XORSHIFTによる乱数
  11. マイクロ秒まで計測するには?
  12. インテルコンパイラでインクルードパスを追加するには?
  13. プログラムから簡単にメールを送信するには?
  14. #ifdefでelse ifは?
  15. coutで出力桁数を指定するには?
  16. ディスクに完全に書き込むには?
  17. ofstreamで書き込みバッファの容量を指定するには?
  18. vectorで多次元配列を実現するには?
  19. ローカルタイムを取得するには?
  20. インテルコンパイラでsleep関数を使うには?
  21. 1秒以下のsleepを行うには?
  22. intを32ビットに指定するには?
  23. 正規分布の乱数を得るには?
  24. ポアソン分布の乱数を得るには?
  25. 四捨五入を行うには?
  26. makeがデフォルトで知らない拡張子を使うには?
  27. コンパイラの種類とバージョンを知るためのpre-defineされたマクロは?
  28. 64ビットOSとlongの関係は?
  29. カレントディレクトリを取得するには?
  30. fstreamのバッファを増やすには?
  31. int型のabs関数の場所は?
  32. Windowsでisnanを使うには?
  33. ハードウェア乱数生成器による乱数を生成するには?

Tips

マイクロ秒まで計測するには?

Unix系OSでマイクロ秒まで計測するには、gettimeofdayを使用します。必要なヘッダは

#include <sys/time.h>

です。使い方は、下記のようにします。

struct timeval t;
gettimeofday(&t, NULL);
cout<< t.tv_sec + (double)t.tv_usec*1e-6<<" sec"<<endl;

インテルコンパイラでインクルードパスを追加するには?

インテルコンパイラの場合、INCLUDE環境変数ではなく、CPATH、C_INCLUDE_PATH、CPLUS_INCLUDE_PATHに追加する。

手動で追加する場合は-I pathで指定する。

coutで出力桁数を指定するには?

#include <iomanip>
cout<<std::setprecision(20)<<t<<"\t"<<x<<endl;

この方法は、当然ofstreamなどにも使えます。

ディスクに完全に書き込むには?

endlやflushメソッドは、バッファを空にしても、それがOSのキャッシュに残ってしまうかもしれない。完全に書き込むには、fsyncを使う。ただしこれはfopenでファイルを開く。Cでのみ使える。C++のofstreamには、ファイル記述子がないので、一旦closeを呼び出すのが簡単。もしくは、fopenを使った独自のクラスを書く以外にない。

ofstreamで書き込みバッファの容量を指定するには?

pubsetbufを使う。pubsetbufがC言語のstdioのsetvbuf関数に相当する。

vectorで多次元配列を実現するには?

スペースが重要。

ベクトル化してSSE等を使って計算しやすいコードを書くには?

Array of StructureではなくStructure of Array(AoS)を使います。これは、たとえSSEを使わない場合でも、メモリアクセスが高速化される。

パイプの使い方

インテルコンパイラでsleep関数を使うには?

#include <unistd.h>をインクルードする。
sleep(1)で一秒間眠る。

1秒以下のsleepを行うには?

通常のsleep関数は、引数の数値は秒を表す。例えば

sleep(1);

は1秒間プログラムを停止する。これ以下の間隔でプログラムを停止したい場合、nanosleep()を使う。

makeでコンパイルする

空白ではなく、タブ文字を使うこと。

コンパイル時にmultiple definition of xxxというエラーが出る

.hファイル内にconstパラメータは記述しないこと。 constはcppファイル内に記述する。

テンプレートで分割コンパイルするには?

通常、クラステンプレートはヘッダファイルに本体も書かないとコンパイル時にエラーになってしまう。
すなわち、ヘッダhファイルとcppファイルという形で書くことが通常できない。
分割して書きたい場合は、cppファイルの最後に下記のようなものを入れておく。

template class foo<double>;
template class foo<float>;

ここではdoubleとfloatだけしか書いていないが、例えばintなど他の型を取る可能性がある場合はすべて列挙しておく。
なお、列挙した分だけコンパイルに時間もかかる。
逆に言えば、不特定の型を仮定する場合はこの方法は使えない。

makeがデフォルトで知らない拡張子を使うには?

makeを使ってコンパイルする際に、例えば.cや.cpp、.oといった拡張子は、あらかじめ登録されている。具体的には

$make -p -f /dev/null | less

というコマンドで、その一覧を知ることができる。
この中に登録されていない、拡張子、例えばWindowsのコンパイラでよく使われる.objなどの拡張子を使いたい場合は、Makefileの中で登録しておく必要がある(そうしないとうまくコンパイルされない)。具体的には、Makefileの中で

.SUFFIXES:.obj

と言う一行を追加する。



最終更新日


本文中のFC4はFedora ProjectのFedora Core 4を、FC5はFedora Core 5を、FC6はFedora Core 6をopenSUSEはNovellのSUSE Linux OSSを表します。Fedora7以降は、単にFedora7、Fedora8、Fedora9、Fedora10、Fedora11、Fedora12、Fedora13、Fedora14、Fedora15と表示しています。Ubuntuは、必要に応じて20.04、21.04のようにバージョン番号をつけて区別しています。

ここに登場するドメイン名やIPアドレスなどはフィクションです。実在の人物・団体等とは一切関係がありません。
実際に使用する際は、各自の環境に合わせて書き換えてください。
もし何か間違いなどありましたらこちらからご連絡ください
リンクに許可は不要です。
Copyright (C) 2021 Chikuma Engineering Co., Ltd. All Rights Reserved.