h.nkgwのメモ書き

自分のためのメモです

久しぶりにcursesプログラムを作ってみる

会社の飲み会の帰り、どこかで見た1時間でプログラムを作るといういう動画を思い出して、自分も何かやってみようと思い、酒が回った頭で考えた結果、マインスイーパーを1 時間で作ろうという事になりました。本当にあの日は酔って頭が

結果、1時間では作れなかったのですが、だいたいこんな感じのプログラムにはなりました。

MacだとCursesが入っていないので、homebrewでncursesをインストールしましたが、普通にxcodeに入っているclangでコンパイル出来ました。

まだmakeも作っていないので、コンパイルは 「gcc -lstdc++ -llcurses --std=c++11 mine.cpp」で行っています。 

 

f:id:nakagawa-chubei:20171018010116p:plain

自分がC言語も学んで最初に作ったプログラムがマインスイーパーだったのですが、あまり上達している感じがしないなあ。

なかなかクリアできなくて、クリア判定が正しいかわからないorz

 

さて、次は何をしようか

 

 

ポインタ表記も逃げられないような気がしますが

C++に関する戯言の続きです。

自分としては、2020年ぐらいまでには特殊な用途以外ではC言語C++を使わなくてもよい世の中になってほしいと思っていましたが、自分が生きている間は現役なのだろうと、少し諦めかけの状況になっていました。

やはり、変数からintなどの値を取るときに i だったり *i だったり(さらに **i の場合もある)する言語は、可読性という点では部外者にかなりの混乱を与えていると思うのですよ。

更に悪い事に、malloc/free もしくは new/deleteですか、今でも世界のどこかでFreeしていないポインタを追いかけているエンジニアがいる。それだけならまだしも、マルチスレッド間でたまに起こる不整合のために起こるセグメンテーションフォルトに悩んでいる事を考えると、エンジニアが足りていないからといって、多少の研修なんかはあるかもしれなくても、未経験者がいきなりC/C++でコードを書く現場に投入されて、そのコードが何処かのシステムで動いているという事は少し恐ろしく感じます。

話がそれましたが、ポインタ表記の書き方は実際のポインタ以外にも、スマートポインタやイテレータ、optionalなどでも使うため、単純にポインタ演算子として教えるよりも、実態を指しているものか、場所を指しているものかという2択から説明して、それが生の言語仕様なのか、それともクラスで定義されたものかで掘り下げたほうがわかりやすいような気もしますが、どうなのでしょうか

変数の宣言が面倒なのは避けようが無い気がする

前回の「Cではなくて他の言語を習得した人にC++を教えるには」という話の続きです。

C++の入門書をぱらぱらっと見てみたのですが、初心者向けの本といっても言語仕様自体が巨大なので、一通り文法の説明を終えるだけでかなりの量を読みこなさなければいけない感じがしました。

変数の宣言一つとっても、 constがついたり、参照、ポインタがついたり、配列だったり、それでいて初期化していない変数とか、コンストラクタがどうのこうのだとか、最近だと初期化子なんか出てきて、それだけで1章まるごと使えそうとか、使い分けとかどうするのとか考えると、変数宣言だけで手が止まる感じです。

とりあえず、初期化しましょうという事と、古いコンパイラコンパイルする必要がなければ autoを使った記法を優先したほうが、手が止まらない気がします。

最近は型を後ろに描くのが流行のようで、Cのように long a =33;よりは auto a = long(3); のほうが多数派のような気がしますが、最初に決めた型は変わらないので、変数にはなんでも代入出来る系の言語から来られた型はちょっと違和感があると思います。

最近anyやoptionalが標準ライブラリにやってきたので、それも最初に説明するほうが良いとは思いますが、どうでしょうか?

 

Cの文字列は避けて通れないけどあえて避ける

前回の「Cではなくて他の言語を習得した人にC++を教えるには」という話の続きです。

 

先日のHello Worldのプログラムを見て思ったのだけど、そもそもC文字列自体真面目に説明すると面倒だ。 だいたいモダンな言語は文字列の連結の説明にページを割くこと自体無いと思います。

C言語から入るとまず連結した文字列を入れるのに十分なバッファを用意しましょうから始まり、終端文字って何?、そもそも十分な量ってどれぐらい? などの色々な障害を超えてstrcatにたどり着くという長い道のりが待っています。さすがにそれだけの説明を受けて文字列が連結出来るだけだと刺激が少ないので、ベタなC言語の話はなるべく後にして新しい言語仕様の話からしたほうが、理解がはやく、間違いが少ないコードをかけるようになると思います。(効率を考えるのはその後でよいでしょう)

そういうことで、最初の取っ掛かりとして "Hello world"は数字と同じようなただの定数で、文字列として色々操作したいときは "Hello world"s のように最後にs を付ける という大雑把な説明から入ることを考えてみました。

 

”hello" + "world" はできないけど "hello"s + "world"s はきちんと "helloworld"sになってくれるし、"word"s.length() は 4を返してくれます。

モダンな言語から入った人には文字列の連結とかはコレぐらいの説明にして、次の項目に行ったほうが良いでしょう。先は長いのですから

 

C++をメインで使わない人にどう教えるのが良いか?

プログラムの勉強といったら、昔は大抵C言語から始めて、C++を勉強するという人はほとんどでしたが、最近はJavaC#を先に学んだり、PerlJavaScriptなどのスクリプト言語などから入ったり、様々な経験を積んでからC++を学ぶ人が増えてきていると思います。

そのように他の言語から入ると、結構変なところで躓いていたりするのですが、話を聞いてみると、やはりC++って難しいと感じるところが多々あるので、少し自分なりにどの順番に説明するのがよいか考えて見ようと思います。

やはり最初はHello worldから入るのが無難だと思います。コンパイルの方法とか実行方法とかの説明になると思います。


#include <iostream> using namespace std; int main() { cout << "Hello world" << endl; return 0; }

結構面倒なのがincludeの説明です。他のファイルの中身が展開される的な話になるのですが、他の言語ではどのライブラリを使いたいか描くという意味合いのものが多く、ベタに必要な宣言をすべて取り込んでいるものは珍しいのではないでしょうか。

実際、下記のように相互に関数を呼び合う場合、プロトタイプ宣言が必要だというのは、今考えると結構ハードルが高いと思います。


void func2(); void func1() { func2(); } void func2(){ func1(); }