21 Oct 2013, 13:20

『C言語とC++』メリットとデメリットについて調べてみたメモ

Courseraで 『C++ for C Programer』という講義を受講しています。そこで、今日は、C++がC言語よりも優れている点、またはその逆を調べてみました。

講義では、マーガリンはバターから作られるから、バターよりベターというオヤジギャグでC++のCに対する優位性が説明されるが、ほかにも以下の様な理由があげられる。

  • More Type Safe
  • More Libraries
  • Less reliance on preprocessor
  • OO vs imperative

そこで、ネット上の意見も調べてまとめてみた。

※自分の意見ではなくて、あくまでネット上の情報をまとめたもの。

C++がCよりも優れている点

  • C++はC言語を内包している、互換性がある。
  • オブジェクト指向を言語がサポートしている。
  • 豊富なライブラリ群

CがC++よりも優れている点

  • 実行速度、パフォーマンスが高い。
  • メモリ使用量の小ささ。
  • C++よりも文法がシンプル。

まとめ

ハードのレジスタをいじるような組込み系はCが優位、アプリケーションならばC++が優位と読めた。

C言語でもオブジェクト指向ライクな実装はできるけれども、それをしないのは、(すくなくとも自分の職場では)、過去の資産が手続きで書かれているためと、OOに対する知識のなさからだと思う。

あとは、OOライクでないと、テストコードがとても書きにくい。TDDが好きなので、C言語よりもC++に魅力を感じる。いまはC言語を仕事でつかっているけれども、早くC++を身につけてC++の仕事に移動したい。

20 Oct 2013, 01:00

必殺技を実践で繰り出すために、TDDの『Code Kata』について調べてみた

TDDの型を身につけるための方法論『Code Kata』について調べてみたことをまとめます。

medium_7380838634

photo credit: 1936matt via photopin cc

きっかけ

本『The Coding Dojo Handbook』を見つけたので、調べてみた。この本の読書メモは読み終わってからまた書く。

 The Pragmatic Bookshelf | The Coding Dojo Handbook

これらの本にも、紹介されてた。初め、Dojosをどぜうだと思っていた。




自分も過去記事にしてた。 TopCoderに挑戦するきっかけになったのだった。再度、引用。

Code Kata てなに?

Kataは、日本の柔道の型を指す。

実践で技を繰り出すためには、普段からなんどもなんども技を練習しておく必要がある。実践では、考えてる時間がないので、頭が空っぽでも身体がかってに動くレベルまで、普段から基本的な技を磨いておく。

これを、TDDに応用したのが、『Code Kata』だ( ー`дー´)

TDDやリファクタリングの技術は小さなTipsや心構えの積み重ねなので、それを実践のコーディングですばやく繰り出すためには、普段からTDDをして身体を慣らしておく必要がある。『CleanCoder』のボブおじさんの言葉も引用。

必要になった時に完全な動きが自動的にできるようになることが、最終的な目標である。

プログラミングの型というのは、プログラミングの問題を解くためのキーボードやマウスの動きの練習である。

解き方はすでにわかっている問題を解きながら身体の意思決定の練習をするのだ。

(第6章 練習)

やり方

お題がネット上にあるので、それを解く。自分は、『The Coding Dojo Handbook』のお題を進めていく予定。

週1回から3回、30分くらいかけて実施する。深い呼吸をしながら、心の声に耳を傾ける。

まとめ

型を磨くというのは、プログラミングにかぎらず、道を極めるための王道だ。『Code Kata』というのは、Katalogという形で、技を磨くためのステップが体系化されているところがよい。

しばらく、この習慣を始めてみようと思う。

19 Oct 2013, 07:28

iPadでデュアルディスプレイを可能にする『AirDisplay 2』にアップデート。速度が50%向上!

いつも常用しているiPadソフト、『AirDisplay』が2にアップデートしていたので、試してみました。

20131019160113.jpg

このソフト、いままでは速度が遅かったり、解像度が途中でおかしくなったり、そもそもたまに接続できなかったりで、常用しているわりにはとてもストレスのたまる子でした。



でも、今回のアップデートで、

  • スピードサクサク(50%の速度向上!)
  • 解像度問題なし
  • 一発で接続可能

最高ですね。詳しいアップデート内容は以下。

クライアントソフト、iPadアプリ共に、デザインも,フラットデザイン時代を狙った、モダンなものになってます。

20131019162121.jpg

ただし、接続先のIPが192.168.1.101になっていることが気に食わない。これは別のIPをすでに割り当てているので、どうしようか。。。

参考までに、モバイルwifiだと、以下のような対処方法が必要。

いつも常用しているiPadソフト、『AirDisplay』が2にアップデートしていたので、試してみました。

20131019160113.jpg

 

このソフト、いままでは速度が遅かったり、解像度が途中でおかしくなったり、そもそもたまに接続できなかったりで、常用しているわりにはとてもストレスのたまる子でした。



でも、今回のアップデートで、

  • スピードサクサク(50%の速度向上!)
  • 解像度問題なし
  • 一発で接続可能

最高ですね。詳しいアップデート内容は以下。

クライアントソフト、iPadアプリ共に、デザインも,フラットデザイン時代を狙った、モダンなものになってます。

20131019162121.jpg

 

ただし、接続先のIPが192.168.1.101になっていることが気に食わない。これは別のIPをすでに割り当てているので、どうしようか。。。

参考までに、モバイルwifiだと、以下のような対処方法が必要。

19 Oct 2013, 03:56

gcc 4.8.1を利用するためにCygwin64に移行したメモ + Eclipse CDTの設定について

Cygwin 64bit版が 2013年の7月にリリースされたようです。Cygwin64bit版のgccは、c++0xに準拠したgcc 4.8.1をサポートしているようです。

コレを試してみたかったので、64bit版に移行してみました。ついでにEclipse CDTでCygwinを利用したC++開発環境をセットアップするまでの作業メモです。

64bit版のインストール

Cygwin公式サイトにいくと、以下の2つのインストーラがあります。

  • Cygwin
    • setup-x86.exe (32-bit installation)
    • setup-x86_64.exe(64-bit installation)

以前は、setup.exeの一つでした。ここでは、64bit版のsetup-x86_64.exeをダウンロードします。

インストーラを起動して、次へ次へと選択。ここでインストール先のフォルダパスが、defaultではcygwin64となっていることに気づきます。

いままで利用していたディレクトリ名がC:\cygwinだったので、ここは旧フォルダとの互換性を保つために、インストール先をC:\cygwinに変更します。合わせて、もともとのC:\cygwinは C:\cygwin86と名前変更しました。

リポジトリは、.jpが付いているところを選択。

  • ftp.yz.yamagata-u.ac.jp
  • ftp.jaist.ac.jp

あとは必要なパッケージを見繕ってインストール。ここでは、C++開発に必要な最低限をまずはインストールする。

  • Devel/gcc-core
  • Devel/gcc-g++
  • Devel/make

gccのバージョンは、gcc 4.8.1です。バッチリ v(-∀-)v

$ g++ --version
g++ (GCC) 4.8.1
Copyright (C) 2013 Free Software Foundation, Inc.

/home/配下のファイルを旧環境から新環境に移行。これで、.sshやら.emacs.dやらが一切合切移動できる。

その他、Cygwinを導入したらこのまとめ記事が参考になりすぎる。

Eclipse CDT の設定

Eclipse CDTの導入は省略。Pleiadesから落とせばよい。

プロジェクト・エクスプローラから 新規C++プロジェクトを作成。ここで、ツールチェーンには、Cygwin GCCを選択。

Eclipse を -cleanオプションを再起動すると、4.8.1のパスをインクルードしてくれる。(cleanしないと、古い設定が残ったままになる)

apt-cygの対応

おまけで、Cygwin入れたら欠かせないツール、’apt-cyg’も導入する。

15 Oct 2013, 14:44

C++での文字列の使い方まとめ(string)

C++での文字列(string)の使い方についてまとめます

文字列(string)

宣言と初期化

#include<string>
using namespace std;

// 宣言
string c;

// 初期化をともなう宣言
string str( "abcdefghijk" );

文字列操作

サイズ

size()を使う。

str.size();

空の場合は、emptyで調べる。

if (str.empty());
連結

‘+’ を使う

// str1にstr2を連結
str1 += str2
比較

‘==’ を使う

// str1 と str2 を比較
str1 == str2
分割

substr( 取り出す初めの文字の番号 ) を使う

string str3( "abcdefghijk" );
str3.substr( 5 );    // "fghijk"
str3.substr( 5, 3 ); // "fgh"
文字の取り出し

str[取り出したい文字の番号] を使う

//strの1文字目取り出し
char c = str[1] ;
挿入

insertを使う。開始位置を指定する。

  //先頭に挿入
  string str( "abcdefghijk" );
  str.insert(0,"123"); // 123abcdefghijk

  //3文字目に挿入
  string str( "abcdefghijk" );
  str.insert(3,"123"); // abc123defghijk
削除

eraseを使う。

インデックスだけを指定した場合にはそこから最後の文字までが削除される。

str.erase( 3 );    // "abc"

指定した場所から指定した文字数を削除するには、erase(インデックス,文字数)で呼ぶ。

str.erase( 3, 3 );    // "abcghijk"

1文字を削除するためには、イテレータの先頭からの文字列を指定する。

str.erase(str.begin()+3);    // "abcefghijk"
検索

単純に for 文を回す方法

  bool rslt = 0;
  string str( "abcdefghijk" );
  char key = 'h';

  for (int i=0; i < str.size(); i++) {
    char target = str[i];
    if ( key == target ) {rslt = 1; break;}
  }

findを利用する。もし検索で求める文字があると、その文字位置を返す。

  string str( "abcdefghijk" );
  char key = 'h';
  cout << str.find(key) << endl; // 7

検索に失敗すると、string::npos という値が返される。(-1)

string str( "abcdefghijk" );
char key = 'z';

if( str.find(key) == string::npos ) {
  cout << "Not Found" << endl;
}

文字配列

文字列配列が与えられた時の、(i,j)要素へのアクセスは以下

str[i][j];

文字列配列が与えられた場合の表のサイズの求め方

vector<string> table 
= { "ABC",
    "DEF",
    "GHI",
    "JKL"}
int width  = table.size();
int height = table[0].length();

コピーは直接代入。与えられた配列をメソッド間で共有するときなどに利用する。

str1 = str2;

15 Oct 2013, 14:42

C++での配列の使い方まとめ(array,vector)

C++での配列(array, vector)の使い方についてまとめます。

配列(array)

宣言と初期化

//宣言
int a[50];

// 0初期化
int a[50] ={0};

// memsetを利用
memset(a, 0, size(a));

// メモリ獲得で宣言
int* a = new int[50];

// newで0初期化までするには、()をつける
int* a = new int[50]();

代入

要素番号を指定して、代入。

a[1] = 1;

サイズを調べる

a.length();

動的配列(vector)

宣言と初期化

vector は std という名前空間に含まれる。

using namespace std;

vector<int> a;      // int型で宣言
vector<Class>   a;    // クラスで宣言

// 領域獲得
a.reserve( 100 ); 

代入

// 末尾に追加
a.push_back( 1 );

参照

a[4];

サイズ獲得

size()を使う

a.size()

空の場合は、emptyで調べる。

if (a.empty())

削除

eraseを利用する。

  //先頭を削除
  a.erase(a.begin());
  // i番目を削除
  a.erase(a.begin()+i);

すべてを消すときは、clearで

  a.clear()

イテレータ

// 宣言
vector<data>::iterator it;

// 参照
*it;        

// サーチ
for(it = data.begin(); it != data.end(); it++ ) {}
</data>

その他

移動ベクトルを定義する

二次元配列が与えられてサーチが必要な場合、移動ベクトルを定義すると、処理か綺麗にかける。

  • 4方向 int dx[] = {1, 1, 1, 0}; int dy[] = {-1, 0, 1, -1};

  • 8方向 int dx[] = {1, 1, 1, 0, 0, -1, -1, -1}; int dy[] = {-1, 0, 1, -1, 1, -1, 0, 1};

配列の領域外でないかチェック

#define IS_IN2(x, n) ((x)>=0) && ((x)<n) )

二次元配列の領域外でないかチェック

#define IS_IN2(x, n, y, m) ( (x)>=0) && ((x)<n) && ((y)>=0) && ((y)<m) )

14 Oct 2013, 13:28

『Modern C++ with TDD』学習メモ(Chapter2-5)

Modern C++ Programming with Test-Driven Development: Code Better, Sleep

Better

体育の日の祝日なので、図書館とカフェにこもってベンキョしてました。そんな体育の日もオツだよね。というわけで、今日勉強した記録を淡々とメモします。

今日は、『Modern C++ Programming with Test-Driven Development』の前半を読みました。これからあんまし時間がとれなくなる気がするので、後半はお正月休みあたりか。

各章の概略

  • Chapter1・・・ツールの準備について。
  • Chapter2・・・TDDの実践方法をsampleとともに、解説される。ここでは、GoogleMockをつかうものの、中身としてはGoogleTestの使い方解説。TDDを知らない初心者向けに丁寧に書いてある。リファクタリングの方法なども、sampleとともに、体験できる。けっこう優しめで丁寧。
  • Chapter3・・・『レッド・グリーン・リファクタリング』にはじまるTDDの思想や原則、規律について書いてある。Webや書籍ですでにいろいろと言われていることをまとめているだけなので、とりわけ目新しいことはない。
  • Chapter4・・・GoogleMockの細かい使い方など。テスト。フィクスチャ、テストのフィルターやパラメタライズドテストの方法が解説される。HamcrestやASSERT_THATがmodernなのだ!と強調される。また、例外のテストや浮動小数点数のテストなど、細かいTipsとか。
  • Chapter5・・・テスト・ダブルの紹介。ここでついに、GoogleMockが登場。まずは、マニュアルでモックをつくらせて、そのあとにGoogleMockでモックをつくり『ほ~ら、コンナに簡単にできちゃうんだぞ~』とさとされる。cURL、JSONCPPなどのサードパーティをつかって、それらとの依存関係を取り除く方法が紹介される。

Study Memo

以下、新しく知ったことを忘れないためのStudy Memo。なので、自分が知っていることは省略。

ASSERT_EQと ASSERT_THAT

いままで、テスト結果の検証には『ASSERT_EQ』しか利用してこなかったけれども、この本では 『ASSERT_THAT』を利用している。理由は、テストコードの可読性が高まるから。

比較してみる。 『1+1=2』( (1+1) equals to 2 )。

ASSERT_EQ( 2, (1+1) );

これを、ASSERT_THATで書きなおすと以下のようになる。

ASSERT_THAT( (1+1), Eq(2) );

なるほど、英語の文の並びと同じになる。 Assert that 1+1 equals to 2.

ASSERT_EQからASSERT_THATを利用しているところが、まずモダン。

Test Fixtureでのクラス生成はポインタで

クラスをフィクスチャ間で共有するには、どうすればいいか、いままでワカラなかった。こうすればよい。

#include "gmock/gmock.h"
#include "RetweetCollection.h"
#include "Tweet.h"

#include 

using namespace ::testing;
using namespace std

class ARetweetCollectionWithOneTweet: public Test {
public:
   RetweetCollection collection;
   shared_ptr tweet;

   void SetUp() override {
      tweet = shared_ptr(new Tweet("msg", "@user"));
      collection.add(*tweet);
   }
};

TEST_F(ARetweetCollectionWithOneTweet, IgnoresDuplicateTweetAdded) {
   Tweet duplicate(*tweet);
   collection.add(duplicate);

   ASSERT_THAT(collection.size(), Eq(1u));
}

Classの宣言に、shared_ptrを利用して、SetUp()でメモリを動的に獲得する。

Hamcrest Assertion

従来のAssertion(expect_eqとか)では、一つの宣言で一つのことしか検証できなかった。

しかし、モダンなHamcrest Assertionだと、Matcherを利用し、一つの宣言で複数のことを検証できる。

ASSERT_THAT(actual,
    AllOf(StartsWith("al"), EndsWith("ha"), Ne("aloha")));

GoogleMockはC++でHamcrestが利用できるxUnitなので、こういう方法も紹介されている。

Parameterized Test

複数のテストケースをまとめて実行できるというもの。TDDというよりは、スプレッドシートにかかれた仕様を検証するようなときに必要そうなテストの書き方。

#include "gmock/gmock.h"
using namespace ::testing;

struct Sumcase {
  int a, b, expected;
  Sumcase(int anA, int aB, int anExpected)
    : a(anA), b(aB), expected(anExpected) {}
};

class AnAdder: public TestWithParam {
};

class Adder {
public:
  static int sum(int a, int b) {
    return a + b;
  }
};

TEST(AnAdder, GenerateASumFromTwoNumbers) {
  ASSERT_THAT(Adder::sum(1, 1), Eq(2));
}

TEST_P(AnAdder, GenerateLotsOfSumsFromTwoNumbers) {
  Sumcase input = GetParam();
  ASSERT_THAT(Adder::sum(input.a, input.b), Eq(input.expected));
}

Sumcase sums[] = {
  Sumcase(1,1,2),
  Sumcase(1,2,3),
  Sumcase(2,2,4)
};

INSTANTIATE_TEST_CASE_P(BulkTest, AnAdder, ValuesIn(sums));

Test Double、Mock、Stub、Spy、Fake

これは、この本の本題ではないけれども、メモしとく。

  • Test Double・・・テストのために本番用コードと置き換わり、本番用コードをエミュレートするもの
  • Stub・・・ハードコーディングされた値を返すTest Double
  • Spy・・・テストの後の検証のために、オブジェクトに送られた情報をキャッチするTest Double
  • Mock・・・自分で検証機能をもつTest Double
  • Fake・・・本番用クラスを簡易版実装したTestDouble

14 Oct 2013, 01:48

CentOS 6.4でC++11対応のg++ 4.7.2を使うためのメモ

c++11対応のg++をCentOSに入れてみた作業メモ。

yum installで取れるCentOSのデフォルトg++のバージョンは4.4.7(2013/10現在)。

% g++ --version
g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-3)

なので、別のリポジトリからg++4.7.2を持ってきて、CentOSにインストールしてみた。

以下のコマンドで取得。

cd /etc/yum.repos.d
wget http://people.centos.org/tru/devtools-1.1/devtools-1.1.repo 
yum --enablerepo=testing-1.1-devtools-6 install devtoolset-1.1-gcc devtoolset-1.1-gcc-c++

以下のパス配下にインストールされます。

 /opt/centos/devtoolset-1.1/root/usr/bin/

インストール完了です。

# /opt/centos/devtoolset-1.1/root/usr/bin/g++ --version
g++ (GCC) 4.7.2 20121015 (Red Hat 4.7.2-5)

パスを通します。

export CC=/opt/centos/devtoolset-1.1/root/usr/bin/gcc
export CXX=/opt/centos/devtoolset-1.1/root/usr/bin/g++

Trouble Shooting

[Errno 14] PYCURL ERROR 6 – “Couldn’t resolve host ‘people.centos.org’“

PYCURL ERROR 6 – “Couldn’t resolve host ‘people.centos.org’“というエラー発生。

# yum --enablerepo=testing-1.1-devtools-6 install devtoolset-1.1-gcc devtoolset-1.1-gcc-c++
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: ftp.tsukuba.wide.ad.jp
 * extras: ftp.tsukuba.wide.ad.jp
 * updates: ftp.tsukuba.wide.ad.jp
http://people.centos.org/tru/devtools/6/i386/RPMS/repodata/repomd.xml: [Errno 14] PYCURL ERROR 6 - "Couldn't resolve host 'people.centos.org'"
Trying other mirror.
Error: Cannot retrieve repository metadata (repomd.xml) for repository: testing-devtools-6. Please verify its path and try again

これは、ipv6が有効になっていることによる問題のようだ。

以下を参考にした。

ipv6を無効にする。

% emacs /etc/sysconfig/network
=> NETWORKING_IPV6=noを追加
% emacs /etc/modprobe.conf
=> 以下を追加
   alias ipv6 off
   alias net-pf-10 off
% /sbin/chkconfig ip6tables off
% shutdown -r 0

[Errno 14] PYCURL ERROR 22 – “The requested URL returned error: 404 Not Found”

“The requested URL returned error: 404 Not Found”というエラー。

% sudo yum --enablerepo=testing-1.1-devtools-6 install devtoolset-1.1-gcc devtoolset-1.1-gcc-c++
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: ftp.tsukuba.wide.ad.jp
 * extras: ftp.tsukuba.wide.ad.jp
 * updates: ftp.tsukuba.wide.ad.jp
http://people.centos.org/tru/devtools/6/i386/RPMS/repodata/repomd.xml: [Errno 14] PYCURL ERROR 22 - "The requested URL returned error: 404 Not Found"
Trying other mirror.
Error: Cannot retrieve repository metadata (repomd.xml) for repository: testing-devtools-6. Please verify its path and try again

これは、ftp.tsukuba.wide.ad.jpのミラーサイトには、testing-1.1-devtools-6のリポジトリが存在しないということ。

というわけで、ミラーサイトを変更してみます。理化学研究所に変更しました。以下にまとめました。

Reference

14 Oct 2013, 01:45

yum updateのミラーサイトを理化学研究所(理研)に変更したメモ

yum updateのミラーサイトを、いままでは筑波大学(ftp.tsukuba.wide.ad.jp)としていたのだが、ある不具合のため理化学研究所(ftp.riken.jp)をデフォルトのミラーサイトに変更してみた。理研のほうが、早いらしいといううわさも。

変更はCentOS-Base.repoを修正

変更は、/etc/yum.repos.d/CentOS-Base.repoを修正する。

  • mirrorlistをコメントアウト
  • baseurlを mirror.centos.orgからftp.riken.jpに変更。これをすべてのカテゴリで実施。

/etc/yum.repos.d/CentOS-Base.repo

/etc/yum.repos.d/CentOS-Base.repoの設定。そのままコピペでOk.

[tsu-nera]% cat /etc/yum.repos.d/CentOS-Base.repo

13 Oct 2013, 12:23

git pushで『You can’t push to …』でエラーする場合の対処方法メモ

久しぶりに、git pushをしてみたところ、以下のエラーがでて利用できなかった。

% git push
fatal: remote error:
  You can't push to git://github.com/tsu-nera/dotfiles.git
  Use https://github.com/tsu-nera/dotfiles.git

う~ん、なんでだろう。日頃pushしてないからかな・・・。

調べてみたところ、.git/configの設定が間違っているようだった。

%cat .git/config

[remote "origin"]
    url = git@github.com:tsu-nera/dotfiles.git

このurlの部分を以下のように変更する。

(変更前)url = git://github/com:tsu-nera/dotfiles.git
(変更後)url = git@github.com:tsu-nera/dotfiles.git

これで、git pushが成功するようになった。