07 Dec 2013, 07:45

[Coursera]C++ For C Programmersを受講しました

Cプログラマなので、C++を勉強するために『C++ For C Programmers』を受講しました。

概要

C++の初級的な話題が紹介される。この講義でC++の基礎がマスターできる内容。Cプログラマを対象にしているため、Cとの比較やC++のここがスゴイのだという説明も出てきて、Cしかしらない自分にはこのCについての伏線が嬉しい。

また、なにかにつけてC++11の話題がガッツリ紹介されるので、C++11 For C++98 Programmersというタイトルのほうが実は適切な気がする。

オープニングにJAZZが流れて、ダンディさあふれるのIra Pohl教授が現れる。

[//www.youtube.com/embed/tph2O4qPNMg?rel=0]

話し方がカメみたいにものすごくゆっくりなので、English的な壁は大丈夫だった。スライドにカラーペンで書き込みながら説明されるので、臨場感がある。(しかし字がけっこうきたない)

参考書

参考書は、ネット上にある無料のものと、有料のものがある。

  • C++ by Dissection
  • C++ For C Programmers


が、自分は利用しなかった。どちらかというと、副読本としては、かつて挫折した独習C++を読んでた。

各回の概要

Week1 C++ as a Better C

A言語からC言語までに至る歴史の説明。そして、C++がC言語に比べてなぜ優れているかを解説する。課題は、C言語でかかれたコードをC++に書きなおす。ここでC++独特の表記をならう。

week2 C++: Basics of Generics and Classes Template

templateが出てくる。より汎用的で、再利用可能な書き方について学ぶ。課題はダイクストラ法の実装。どのへんがC Programmerのためなのだ? モンテカルロ法やPriorityQueueを使いこなす必要があり、難しい。

week3 C++: Class Constructors and Destructors

コンストラクタ、デコンストラクタの説明。または、List構造の説明。Assignmentの実装方法に関するフォローの講義も入る。

week4: C++: Minimum Spanning Tree & Standard Template Library

auto,継承、friend関数などなど。ここで、STLの解説とイテレータという概念が出てくる。だんだんC++ぽくなってくる。Assignmentは最小スパニングツリーをプリム法かクラスカル法で実装。

week5: C++ 11 Standard; Containers, Iterators and Algorithms

主にここではSTLの説明。コンテナ、イテレータ、アルゴリズムの三本柱が詳しく解説される。lambdaの使い方も紹介されるが、理解できなかった。

week6: Hex, the game and C++ Inheritance

後半の大きな話題である、Hex gameの説明が入る。また、重要な概念である、もここで解説。

Module 7: Min-Max and C++11 Classes; Alpha-beta and Polish

Copy Constactor や Move Costractorなど。またHex Gameを実装するための方法が解説される。ミニマックス法やアルファ・ベータ法など。ここで、このCourseのサムネイル画像がチェスの理由を理解した。この先生はチェスがとても好きらしい。チェスにおけるAIの実装方法なども出てくる。

後半の課題である、Hex Gameを 3weekにわたって実装する。この課題で、C++のfeatureを全部注ぎ込みなさいと言われて、けっこう頑張った。

Module 8: Monte Carlo Evaluation; the C++11 Standard

例外処理、スレッド処理などなど、今までで解説していないC++のfeatureももれなく紹介。また、C++中級への道として、簡単なデザインパターンが紹介される。

おわりに

For C Programmerな部分は実はweek1だけだった気がした。グラフ理論やゲーム理論が出てきて、『いったいどのへんがFor C Programmerナンダヨ!』と全生徒が唸ったに違いない。

Cしかできない自分にとっては、まさにうってつけの授業だった。

Hex Game

[//www.youtube.com/embed/kNOFq7aEYUE?rel=0]

05 Dec 2013, 13:51

rubyで別ファイルの変数を読み込んで利用するためのメモ

rubyスクリプトで、あるファイルに書いた変数を別ファイルで使いたい場合は、requireとグローバル変数を使うとよさそう。

たとえば、

$ ruby print.rb
Hello World

のようなメッセージを出力したい。メッセージはグローバル変数で宣言する。

$ cat message.rb
$hello="Hello World"

別ファイルの読み込みは、requireを利用する。ファイル名で、./をつけるのと、.rbを省略するのがミソ。

$ cat print.rb
require './message'
print($hello)

20 Nov 2013, 14:47

C++でのSTLアルゴリズムの使い方まとめ(sort)

C++ STLの algorithmで便利そうなものをメモしてきます.

並べ替え・ソート(sort)

  • 並べ替えを実施します。
  • vectorなどのランダムアクセス可能なコンテナで利用可能。
  • ロジックはクイックソートを利用している。

使い方

sortの引数として、並べ替えたい初めと終わりのイテレータを渡す。たいていは begin(),end().

sort(a.begin(), a.end());

デフォルトでは小さい順(less())に並べ替えられる。大きい順に並べ替える時は、以下のようにgreater<>()を引数として渡す。

sort(a.begin(), a.end(), greater<int>());

#include <algorithm>
#include<vector>
#include<iostream>

using namespace std;

int main()
{
  vector<int> a;
  a.push_back(3);
  a.push_back(1);
  a.push_back(2);

  sort(a.begin(), a.end());
  for( auto x : a ) cout << x;
  cout << endl;

  sort(a.begin(), a.end(), greater<int>());
  for( auto x : a ) cout << x;
  cout << endl;
}

実行結果

$ g++ -std=c++11 sort.cpp
$ ./a
123
321

13 Nov 2013, 14:40

エンジニアとプログラマの違いについて定義してみた

エンジニアの病気、うつ病にかかってる。

プログラマとエンジニア、並べて使われることが多いけれども、違いがよくワカラなかった。

アイデンティティ・クライシスを乗り切るために、ググってみた。

技能者としてのプログラマ

wikipedia

まずはじめは、wikipedia。客観的な説明がわかりやすい。

プログラマは、ことばのまんま。

コンピューターのプログラムを作成する人

日本ではプログラマーというが、海外ではプログラムコードライター(Program code writer)、略してコーダー(coder)といい…

エンジニアは、言い換えると技術者。対して、プログラマは技能者と語られる。

技術者(ぎじゅつしゃ、英語: engineer、エンジニア)とは、主に工学(エンジニアリング)分野の専門的な技術を持った実践者のこと

技術者に類似した概念に技能者がある。技能者とは、機械の組み立てや精密加工などの、ものづくりの実作業を担当する者を指す

情報技術の分野では、プログラマー(狭義ではコーダー)は技能者とされ、分析・設計を担当するシステムエンジニア、プロダクトマネージャーなどの職種が技術者であるとされる

Yahoo 知恵袋

つづいて、知恵袋。これはわかりやすい。

簡単に建築に例えて言えば

大工:プログラマー

設計士:システムエンジニア

プログラマーは、SE(監督)の指示(仕様書)に従って

コーデイングします。コーデイングとは、日本語をコンピューター語に置き換える通訳のような仕事だと思ってください。

アンサイクロペディア

一見ふざけているようで、真実を語っているアンサイクロペディアによると・・・

プログラマー(英:programmer)とは、コンピュータをバグらせる犯罪者。主に高級言語という名のスパゲッティを作るための奴隷。

電磁波を全身に浴びつづけ、仕事中にインターネットを巡回するのが日課になったりと、年々体と精神が崩壊していく。鬱病の発生率は100%である

どれだけ独創的で便利なソフトウェアを制作したとしても、顧客に気に入れられなければ無価値であり、また「仕様変更」「仕様差し戻し」という名の人災(陰謀)によって、一夜にしてそれまでの仕事が無駄になる危険をはらんでいる。

と、ここまで調べて、どうも自分が思っているプログラマという言葉とは異なっているように思えてきた。ハッカーという言葉が、自分の思うプログラマという言葉にあっている。というわけで、ハッカーについて調べる。

ハッカーとしてのプログラマ

wikipedia

やはり、こっちだ。

ハッカー (hacker) とは主にコンピュータや電気回路一般について常人より深い技術的知識を持ち、その知識を利用して技術的な課題をクリア(なかったことに)する人々のこと

こうかくと、芸術家っぽい。

この言葉は、大規模な開発プロジェクトを何年にも亘って指揮してきた優秀なソフトウェア技術者に対して使用されるものではない。ハッカーとは極めて個人的な属性に基づいた呼称であり、その人物の間に合わせのアイデアや閃きを重視した言葉である。

How to become a hacker

有名な、サイト How to become a hackerから引用。

ハッカーは問題を解決し、物事を築きます。そして自由と自発的な助け合いを信条としています。ハッカーとして受け入れられるには、こういう姿勢態度を持つようなふるまいが必要です。そしてこの姿勢を持つかのようにふるまうには、本当にその心構えを信じるしかありません。

ハッカーと画家

ハッカーと画家という本を読んだ時の読書メモから引用する。

ハッカーとは、優れたプログラマのこと。プログラマは職人。絵画を描くのとソースコードを書くのは同じこと。

すべてがコンピュータにどんどん置き換わっていく。21世紀のアーティストはプログラマなのだ。

ハッカーの目指すものは、すなわち美しいソフトウェアをデザインすること。全体像から次第に細部を描いていく。全体は細部からなり、細部は全体を形作る。

情熱プログラマ

つづいて、情熱プログラマからの読書メモ

ここでは、開発者という言葉が使われる。職業は人生を輝かせるための一つの手段。

誰もが光る部分をうちに秘めているが、それを発揮するにはやりがいのあることを見つけないといけないと思う。自分の環境や、自分の道具や、自分の専門分野を好きにならなければ、輝かしいことはできない。

ソフトウェア開発は、やりがいがあって、しかも報れる仕事だ。芸術活動のようにクリエイティブでありながら、具体的に数値化できる価値を生み出せる。

まとめ

ある言葉の意味を追求し始めるとそれは答えのないものなだから、自分で納得して自分で定義しなければいけない。定義することはすなわち、思考停止である。よし、ここらで定義して、考えるのをやめよう。

プログラマとは、

コーディングを通じて、新しいコトを創造する芸術家

エンジニアとは、

技術を通じて、顧客の夢を叶えるビジネスマン

プログラマは自分のためにプログラミングをして、エンジニアは顧客のためにプログラミングをする。プログラマは、エンジニアの仕様を満たす低級な存在ではなくて、自分のアイデアをコードで表現する存在。

自分は、エンジニアである。そして、プログラマになりたいと思う。そして、それは仕事を通じては実現できそうにない。せめて、昼間はエンジニアという社畜として働いても、プライベートではプログラマとしてありたい。

 

追記:2016/12/07 もっといい言葉が見つかった。私はソフトウェア開発者だ

10 Nov 2013, 00:34

UnionFindアルゴリズムを実装してみた

UnionFindをC++で実装した。

UnionFindとは、2つの異なる集合がつながっているかを調べるアルゴリズム。詳しくは以下。

Implement

以下のJavaでかかれた実装をC++版に書き直してみた。木構造にデータを保持する場合と、そう強いない場合の2つを実装。

05 Nov 2013, 15:39

「モダンC言語プログラミング」を読んだ!C言語の組込みエンジニアのためのモダンテクニックが満載

とてもエキサイティングな本に出会い、一気に読んでしまいました。感想を書こうと思います。



ターゲット読者層は組込み分野!

この本のターゲット読者はズバリ、組込みエンジニア。ソースコードのサンプルも、ズバリ組込みな内容を扱っています。C言語を使う人=組込みの人と決めつけているよう。書籍のあちこちで、このアプローチを組込み開発で適応するためにはどうすればいいかという考察が入るのがよい。

TIOBEというプログラミング言語の統計を見ると、C言語を利用している人がプログラマの2割程度いることがわかる。自分はこのデータを初めて知ったけれども、まずこの事実をしれたことは嬉しい事だ。C言語はいかに重要なのかという論題が冒頭で熱く語られる。

 内容について

各章のテーマは、広く浅く書かれているので、もう少し各章の突っ込んだ内容がほしいところだけれども、それはこの本の趣旨には合わないのだろう。

内容は、自分の日々考えていることに非常にマッチしていて、とてもエキサイティングな読後感でした。以下、自分の過去記事も整理しつつ、各章の覚書。

開発環境について

開発環境である、Ubuntuの導入方法と、Eclipseの使い方が紹介されていた。ここは、得るものはなしかな。

オブジェクト指向

C言語でオブジェクト指向のようにコーディングするためのテクニックが紹介されている。半分知っているようで、知らなかった。C言語でも、オブジェクト指向なプログラミングは可能だと気づかせてくれる。

あとは、Cでオブジェクト指向を勉強するならば、ズバリこの本でしょう。これもオススメ。



デザインパターン

自分の来年の重点学習目標の一つが、デザインパターンをマスターすること。この章は、C言語を利用したデザインパターンの実装方法が紹介されている。この章は知らないことが多く、とても興味深かった。

以下のパターンが紹介されている。

  • ステート
  • テンプレートメソッド
  • オブザーバ
  • チェインレスポンシビリティ
  • ビジター

C言語に特化したデザインパターンの本をまだ知らない。これが自分が出会った中で、もっともよくかかれた本かも。この本でも勉強するつもり。まだ読んでない。

いづれにしろ、この章は再読しよう。

TDD リファクタリング

テストフレームワークとして、GoogleTestが紹介される。レガシーコードに対するリファクタリングの実践がサンプルとして載っているのがうれしい。しかも、内容が組込みなので、実践的。パフォーマンスに関する考察もある。

namespaceを利用して、static関数を強引にテストケースに組み込む方法が紹介されていた。C++系のxUnitで利用できるテクニック。

namespace unit_test {
    #include "hogehoge.c"

    TEST(hoge,hogehoge) {
        EXPECT_EQ(3, hoge(1, 2));
    }
}

モックやスタブの定義についての言及は、自分の認識とは違うのだけれども、まあよい。モッキングフレームワークはC言語でいいものがないと書かれていた。そんなことはない、CMockやfffがあるではないか!

CでTDDをするならば、この本が必読本。



継続的インテグレーション

Jenkinsの紹介。これもあまり新しきことはなし。

C言語/C++でJenkins実践入門してみるよ | Futurismo

ビルドスクリプトとして、sConsが紹介されている。なかでも、感心したのが、スモークテストでのPytyonを利用した受け入れテストのアプローチ。pyhthonコードからシリアル接続を経由してテストする方法。この作者はPythonが好きなのかな?自分は、Rubyで同じことをやろうとした。

また、Valgrindを使ったメモリ破壊との戦いも、組込みならでは。こういうことにページを割くところも高評価。ValgrindはLinux用ツールなので、まだ使ったことがないけれども、今度調べてみようかな。

まとめ

組込みの現場ではなぜ、これらのテクニックが浸透しないのだろうか?

Eclipseが浸透しないのは、べつによい。エディタはEclipseだけではないし、EmacsやVimはEclipseに負けないくらいだ。

オブジェクト指向やデザインパターンが浸透しないのは、実行速度やメモリが関係しているのだろう。また、TDDもオブジェクト指向のほうが実施しやすい。(とくにMock)CIは、文化的なものだと思う。

  • 古い考えの人がCProgrammerには多いのだろうか?
  • レガシーコードをメンテナンスしていると、新しいテクニックは不要なのだろうか?
  • 過去の手続き型でかかれたレガシーコードを流用しているから、新しいテクニックを試す場がないのだろうか?

どれも、決定的な理由にはならない。一つ思うのは

「無知」

だからということ。自分もCに関わるいろんな情報を集めているものの、ほかの言語とくらべて、Cは圧倒的に情報量が少ない。Eclipsしかり、TDDしかり、Jenkinsしかり。

C Programmerに足りないものは、道標となるような情報や、書籍だ。C言語は使用率第一位の言語なのだ。これからも、こういう書籍がドンドン出てきてほしい。

04 Nov 2013, 14:46

C++ での優先順位付きキューの使い方まとめ (PriorityQueue)

はじめに

優先順位付きキューのを PriorityQueue という.

キューの中で最大 (最小) のものを抜き出す場合などに利用する.

使い方

宣言

<div class="outline-text-3" id="text-unnumbered-3">
  <p>
    デフォルトでは大きい順で pop されるので, 最小のものを pop で取り出すには, greater を宣言時に追記する.
  </p>

  <p>
    [sourcecode language=&#8221;cpp&#8221; title=&#8221;&#8221;]<br /> #include <queue><br /> using namespace std;
  </p>

  <p>
    priority_queue <int> maxpq; // default 大きい順<br /> priority_queue<int, vector<int>, greater<int> > minpq; // 小さい順<br /> [/sourcecode]
  </p>
</div>

関数

<div class="outline-text-3" id="text-unnumbered-4">
</div>

<div id="outline-container-unnumbered-5" class="outline-4">
  <h4 id="unnumbered-5">
    要素を追加する (push)
  </h4>

  <div class="outline-text-4" id="text-unnumbered-5">
    [sourcecode language=&#8221;cpp&#8221; title=&#8221;&#8221;]<br /> pq.push (1);<br /> [/sourcecode]
  </div>
</div>

<div id="outline-container-unnumbered-6" class="outline-4">
  <h4 id="unnumbered-6">
    先頭の要素を取り出す
  </h4>

  <div class="outline-text-4" id="text-unnumbered-6">
    <p>
      最大 (または最小) の先頭を取り出します.
    </p>

    <p>
      [sourcecode language=&#8221;cpp&#8221; title=&#8221;&#8221;]<br /> pq.pop ();<br /> [/sourcecode]
    </p>
  </div>
</div>

<div id="outline-container-unnumbered-7" class="outline-4">
  <h4 id="unnumbered-7">
    要素を調べる
  </h4>

  <div class="outline-text-4" id="text-unnumbered-7">
    [sourcecode language=&#8221;cpp&#8221; title=&#8221;&#8221;]<br /> // キューがからかどうかを調べる<br /> pq.empty ()</p> 

    <p>
      // 要素数をしらべる<br /> pq.size ();
    </p>

    <p>
      // 次に取り出される要素を調べる<br /> pq.top ();<br /> [/sourcecode]
    </p>
  </div>
</div>

Sample

昇順に取り出す

<div class="outline-text-3" id="text-unnumbered-9">
  [sourcecode language=&#8221;cpp&#8221; title=&#8221;&#8221;]<br /> #include <queue><br /> #include <iostream><br /> using namespace std;</p> 

  <p>
    int main ()<br /> {<br /> priority_queue<int> pq;
  </p>

  <p>
    pq.push ( 2 );<br /> pq.push ( 1 );<br /> pq.push ( 3 );
  </p>

  <p>
    cout << pq.top () << endl;<br /> pq.pop ();<br /> cout << pq.top () << endl;<br /> pq.pop ();<br /> cout << pq.top () << endl;<br /> pq.pop ();
  </p>

  <p>
    return 0;<br /> }<br /> [/sourcecode]
  </p>
</div>

<div id="outline-container-unnumbered-10" class="outline-4">
  <h4 id="unnumbered-10">
    実行結果
  </h4>

  <div class="outline-text-4" id="text-unnumbered-10">
    [sourcecode language=&#8221;language&#8221; title=&#8221;&#8221;]<br /> 3<br /> 2<br /> 1<br /> [/sourcecode]
  </div>
</div>

降順に取り出す

<div class="outline-text-3" id="text-unnumbered-11">
  [sourcecode language=&#8221;cpp&#8221; title=&#8221;&#8221;]<br /> #include <queue><br /> #include <iostream><br /> using namespace std;</p> 

  <p>
    int main ()<br /> {<br /> priority_queue<int, vector<int>, greater<int> > pq;
  </p>

  <p>
    pq.push ( 2 );<br /> pq.push ( 1 );<br /> pq.push ( 3 );
  </p>

  <p>
    cout << pq.top () << endl;<br /> pq.pop ();<br /> cout << pq.top () << endl;<br /> pq.pop ();<br /> cout << pq.top () << endl;<br /> pq.pop ();
  </p>

  <p>
    return 0;<br /> }<br /> [/sourcecode]
  </p>
</div>

<div id="outline-container-unnumbered-12" class="outline-4">
  <h4 id="unnumbered-12">
    実行結果
  </h4>

  <div class="outline-text-4" id="text-unnumbered-12">
    [sourcecode language=&#8221;language&#8221; title=&#8221;&#8221;]<br /> 1<br /> 2<br /> 3<br /> [/sourcecode]
  </div>
</div>

おまけ

ダイクストラ法の実装をする際に, C++ の STL があるとは知らずに, 自前で最小優先キューを実装しました. STL を利用すればよかった.

この Java Sourse を参考に C++ に書きなおした.

MinPQ:

04 Nov 2013, 06:10

秀丸のような罫線マクロないかなと思ってelisp作成した

秀丸エディタやサクラエディタには、Ctrl+Alt+Shift+矢印で罫線が引けるすぐれものマクロがある。

こういう便利な機能がほかのエディタでもないかなといろいろ調べてみたけれども、みつからなかった。

AuthHotKeyのキーバインドで罫線を割り当ててみたところ、左右はいい感じに動くけれども、上下が罫線マクロのように賢くできないので、挫折。

秀丸のような罫線マクロないかな・・・

追記(15/01/09)

Emacs用に elispを作成した.

参考

27 Oct 2013, 14:49

C++11のrandomライブラリで1から10の乱数を生成する方法のメモ

C++で乱数を利用する方法について調べてみた。

やりたいこと

1~10の間で、ランダムな数字を取得する

実装方法

C++には、長らく乱数生成はC言語に頼ってきた歴史があるようだが、C++11でようやくrandomライブラリが標準実装されたようだ。

利用するためには、以下をインクルード。

#include 

覚えないと行けないことが2つある。

  • 乱数生成エンジン ・・・ 乱数を生成する。
  • 分布生成器 ・・・ 生成された乱数を分布に従わせる。一様分布、正規分布、ベルヌーイ分布、ポアソン分布、など。

乱数生成エンジンは種類がたくさんあり、正直どれをつかえばいいのかわからないので、とりあえずコレ。

  // 予測不能な乱数生成器(class   
  std::random_device
  // メルセンヌツイスターの32ビット版(typedef)
  std::mt19937

分布は一様分布を利用。これは、intとdoubleでつかうエンジンが異なる。

`// 整数型 std::uniform_int_distribution // 浮動小数点型 std::uniform_real_distribution

追記`

randomライブラリは実行速度がrandに比べて早くないことが判明!なので、srand,randを使った方法も追記。srandはループの外で宣言する必要がある。

実装

-std=gnu++0xをコンパイルオプションにつけることを忘れないように。

こんな感じで、生成されました。

5.28957
8.79693
5.23333
1.76491
3.95931
5.52467
8.1513
6.85362
1.68268
9.75644

27 Oct 2013, 13:48

Eclipse CDTで変数や関数が赤バツになってしまう場合の対処方法(C++11対応も)

Eclipse CDTで変数や関数が赤バツになってしまう場合の対処方法

Eclipseに外部のソースをインポートすると、赤バツがたくさんでることがある。また、C++11対応のソースが赤バツになることがある。

これは、CDTのインデックス機能がインデックスをするときに、ファイルパスの場所やプリプロセッサの定義値を知らないから。

パスおよびシンボルを設定

こんなときは、プロジェクトを右クリックしてプロパティを選択。

  • C/C++一般 -> パスおよびシンボル

ここでMakefileに書くような情報(インクルードパスやdefine値)を設定することで、赤バツが消える。たとえば、

  • インクルードパスを追加する場合にはインクルードを選択。
  • define値を追加するときにはシンポルを選択。

Eclipse CDTで C++11のソースを赤バツにしない方法

すでにEclipseの設定でdefine値が設定してあると、自分の値が反映されないことがある。C++11などはまさにそうだった。この場合は、

  • C/C++一般 -> Prosessor Include, Macro..->エントリ -> CDT User Setting Entrys

であたいを追加する。

__cplusplus = 201103L