C++の学習:Macに行き着けない

C++のままではMacのObjective-Cに行き着けないので、集中力がなくなるのはわかっていても、Objective-Cの方も見てみることにしました。

コンソール入出力のサンプルプログラムではMacに行き着けそうにないので、その焦りも手伝い、Objective-Cをまとめたサイトを読みはじめました。目次は次の通りです。

Advertisements

C++の学習:string名.compare だいぶ前進

ようやく、少し見えて来ました。

string名.compareまでサンプルコードを作ってみて、C++の書き方がわかってきました。

do while(正確にはwhile)、if else、関数の記述と戻り値(returns)の取り扱いができるようになりました。先が見えてきたと言っても、基本中の基本のことなので、助走を終えた程度の話です。もしかすると、足下の数十歩先?

しかし、これ以上、どういうふうに関数を記述し、使うのか自分の頭で考えてコーディングするのはやめようと思います。それでは時間もかかります。また、どうせ全部を覚えきれるはずもありません。これからは、サンプルコードをコピーして、動きを確認するだけにします。

そうすることで時間を節約し、関数の全体像を早く把握した方がいいと思うのです。多分、重要なことは、そこにはなく、既存のライブラリに何があり、それがどういう機能で、どう利用できるのかの方が重要なのではという気がします。何を作るかにもよりますが、これこそ時間がかかると思われますので、早くそこに行けるようにしたいと思います。

関数もどこかで端折ることになればさらに前進できます。

もちろん、その前に、まだ勉強しないといけない多くの関数とモジュール化と呼び出しパラメタの設定の仕方等が山積みされています。

これまでのところ、C++で良かったことはインデクスがゼロオリジンであることです。アドレス+サイズ=次のアドレスになるので考えやすいです。Xcodeも使いやすいので何とかなりそうです。

サンプルコードは、英語ですがcplusplusというサイトに整理されていました。C++の文法やreturnsも載っていますので、今後はこのサイトを利用していく予定です。

compare

C++の学習:string名.empty()とdo while

string名.empty()には結構ハマりました。

string名.empty()はtrueなら空、faulseなら文字列が入っているということになっています。しかし、サンプルコードが動かなかったことから長時間ハマりました。

原因は、作成したtest.cppに何らかのバグ。test2.cppで新たに書き直したらちゃんと動きました。つまらないことで時間が取られました。

1. string名.empty()

empty2. do while, append, コンストラクタ

  • 条件がdoのあとに聞かれることになるので、do文の中を少なくとも1回は通り、ループする可能性に留意するべき。
  • if文を使わないで最初に継続条件を調べる方法はあるのでしょうか?
    ➡ 単純にwhile文ではじめればいいのかなあ?。➡ その通り。サンプルコードでは、if文がない代わりに、getline(cin,inputArea);をwhile文の前に書くことで上から下に流せ、同じ結果が得られました。ループは鬼門で、forやdo untilには、安易に飛び込めません。
  • string名.append(文字数,文字):問題なし
  • コンストラクタ: string名に初期値の文字を設定:問題なし

while

C++の学習:string名.find

stringのfindをひと通りコーディングして確認しました。

1. find関係で注意した方が良さそうな点は次のことでした。

  • インデクスには、(文字サイズ-1)よりも小さい値を設定した方が無難。
    rfindは文字数よりも大きい値を設定しても適切な値を戻して来ましたが、find_last_not_ofは不適切な値を返して来ました。このことから設定するインデクスは前処理でチェックするべきなのでしょうね。
  • 検索文字がヒットしないとき、string::nposを戻して来るので、チェックするロジックを入れることを考慮すること。
  • findとfind_first_ofとは似て非なるものでした。
    find_first_of(“abcde”,2)は、”bc”でヒットした”c”の位置2を戻して来ます。1でない理由は、2から探しはじめるようにインデクスで指定しているからでしょうか。
    この点、findは指定したインデクスからヒットするかどうか探します。

パラメタのチェックをするときに使えそうな気がしましたが、具体的なことはno ideaです。実際に使う段になってから、もう一度アルゴリズムを考えることになると思います。いろいろ使うと、その場では便利でも、後々、頭が混乱しそうです。

ところで、コード体系が何なのかも調べないといけません。シフトJISはいいにしても、うーっ!これは最悪。全くわかっていないなあ。

string find2. size, length, max_size, at 関係で注意しないといけないことは、やはりインデクスをチェックしないとまずいということでした。このこと以外には、特に大きな問題はありませんでした。

  • まず、max_sizeの最大値は18446744073709551614、findのヒットしないときの戻り値はstring::nposのとき18446744073709551615でした。これは64bit表現で1bitを符号としたときの最大値と-1になるのでしょうか?
    余計なことかもしれませんが、アドレッシングは64bitになっている(?)。
  • string名.at(インデクス)は、範囲チェックをしないとout of rangeのエラーになります。これまでのことと合わせて考えても、インデクスエラーはメモリのアクセスエラーにつながるということなのでしょう。

c++ size訂正:やはり、このif分はまちがっているようなので、修正しました。{ }は単一行のときは不要なようですが、拡張性を考えると常に{ }で囲んでみました。それでいいかどうかは確信がありません。今、.empty()がdo whileで歯止めにならなかったり、単純なstringの代入+=後にsize()=0になる問題などを試しています。少し整理しながらやらないと、ゴチャゴチャになりそうです。

if文修正

C++の学習:勘違い

charについて勘違いがあるようなのですが、stringの方を先に進めています。

インターネットで調べると、だいたいのことはわかります。多分?少しは。

charについて勘違いをしているようなのですが、何がわかっていないのかわからないので、それはそれとして、stringの方を先に勉強しています。

1. string

  • エリアの定義の仕方
  • ヘッダでstringを組み込むこととusing namespace stdで名前空間を定義しておき、std::のような冗長性のある記述を割愛する。
  • stringの初期値設定の仕方:文字列、代入、繰り返しデータ、インデックス指定
  • 文字列の結合: string名+string名
  • stringの長さ: string名.size()

2. string検索

  • インデックス表現は0オリジン
  • string名.find(“検索する文字列”)
    ※ ヒットしないときは?
    ➡ string::nposが返って来るのでチェックする。
    ➡ if string名.find(“検索する文字列”)=string::npos
  • 日本語文字列のとき、東京都台東区の京が3になる理由は?
    ➡ ?

ここまで勉強したところで、string全体では32種類の処理があることがわかりました。現時点でスタディ済みのものは演算子、find、sizeの3個で、一応スキャンしたfind関係を入れても7個。未了が25個もあります。面倒ですが、25行から50行くらい書けばすむことなので、全部試すことにします。

全体像がわからないまま手当り次第にやっていますので、ひとつひとつ片付けて、ある程度概要がつかめたところで、振り出しに戻って全体像をとらえた方がいいのではないかと考えています。時間がかかるのはやむを得ません。

string

C++文字列(std::string)

コンストラクタ 文字列を初期化するメソッド
演算子 比較、および文字列の割り当てを行う
append() 文字列の後ろに他の文字列を追加する
assign() 文字列にテキストを割り当てる
at() 指定されたインデックスの文字を返す
begin() 最初の文字を示すイテレータを返す
c_str() C言語形式の文字配列を返す
capacity() 文字列が格納できる文字数を返す
compare() 2つの文字列を比較する
copy() 文字列の中に文字列をコピーする
data() 最初の文字へのポインタを返す
empty() 文字列が空の時にtrueを返す
end() 文字列の最後を指すイテレータを返す
erase() 文字列の一部分を削除する
find() 与えられた文字列を検索する
find_first_of() 与えられた文字列を検索し、一番最初の要素のインデックスを返す
find_first_not_of() 与えられた文字列の中の文字ではない最初の要素のインデックスを返す
find_last_of() 文字列の中から文字を検索し、一番最後の要素のインデックスを返す
find_last_not_of() 与えられた文字列の中の文字ではない最後の要素のインデックスを返す
get_allocator() 文字列のアロケータを返す
insert() 文字列の中に他の文字列を挿入する
length() 文字列の長さを返す
max_size() 文字列が保持することができる最大の長さを返す
rbegin() 文字列の最後を示すリバースイテレータを返す
rend() 文字列の最初を示すリバースイテレータを返す
replace() 文字列の中の文字を置換する
reserve() 文字を格納する容量を確保する
resize() 文字列の大きさを変更する
rfind() 与えられた文字列を検索し、最後の要素のインデックスを返す
size() 文字列の文字数を返す
substr() 文字列の一部を新しい文字列オブジェクトとしてコピーする
swap() 2つの文字列を交換する

C++の学習:一歩前進二歩後退

遅々として進まない感じです。基本中の基本の勉強からスタートしていますから、ABCの次になにがあるのか、考えが及ばないのは当然のことです。

1. コンソール入力と出力

  • #include <iostream> 組み込み
  • cout << 出力
  • using namespace std std::の省略
  • cin >> 入力
    ※ スペースで自動的に区切られる➡対応方法は?
  • 表示方法
    ※ スペースに伴う入力の処理の仕方はエリア定義を学習したあとでもう一度戻って来て再学習すること。

2. エリア定義

  • char : 1byte
  • int : 2byte
  • long : 4byte
  • 配列定義例 char table50[128][50]; 128 byte x 50
  • メモリの静的割当
    ※ メモリの動的割当➡対応方法は?
  • #include <string> ➡ ※ charとの違いを調べること
  • 文字列の長さは、strlen()で知ることができる。nullを除く長さ。
  • 動的にエリアを確保する場合、malloc(strlen(dynambuffer)+1)のように+1 byte足さないといけないことに注意。
  • string
    ※ さらに詳細について学習すること。

3. メモリのダイナミックアロケーション

  • メモリのアロケーションができないときが問題
    ➡回避方法?
  • free()で確保したメモリを解放する必要がある。ただし、プログラム終了と強制終了で自動的に解放される。多分、ある許容量の動的エリアがあるとき、これを超えてメモリ確保はできないし、これ以内であれば、解放しながら使わないと動的確保はできないよということではないか。要フォロー。

エリア定義

C++の学習:XcodeとC++の攻略方法を考える

全部が全部、不完全な状態からのスタートなので、最初にXcodeとC++の攻略方法を考えないといけません。

サンプルプログラムが動くことはすぐに確認できました。何行か新たにプログラムを書き加えても動きましたので、手始めとしてはいいのではないかと思います。

しかし、相変わらず、どこから手をつけていいかわからない状態なので、概要が把握できるまではサンプルプログラム中心に学習して行くことにしました。知識の整理のしかたはプログラムにコメントを記述することで対処することにします。そうすれば、手間がかかりません。

本日、1日目に学習したことは次の通りです。

  • コメントの書き方
  • ソースプログラムの拡張子は.cppであること
  • ヘッダには、①マクロ、②クラス、③変数の3種類と④#includeが定義できること
  • 変数をプログラム間で定義する方法
    ① externで変数がexternal definitionとなることを宣言する。
    ② #includeでそのプログラムを取り込み、実際の変数定義をintで行う。
    ③ 参照するときは、#includeでexternで定義したプログラムを組み込んで利用する。
  • 関数をプログラム間で共有するときも、変数と同じ考え方。externの代わりにプロトタイプ宣言をする。

勉強しはじめたら、昔、アセンブラとOSを書くためのPLIライクの専用言語では数万行書いたことを思い出しました。12,000行くらいまでは暗記でき、エラーがでたら、リストを見なくても、いつでもどこでもデバッグできました。そういう意味では、頭からロジックが離れないことが、後々、プログラム開発を嫌なしごとにしてしまった面があります。

最初のプログラム開発は、新聞社の記事配信のリアルタイム処理のQueue管理ではじまり、バッファのダイナミックアロケーションとタスク管理とか、それらを使ったオブジェクトベースのシーケンス処理とかは得意中の得意になりました。その応用として、日本語の組版処理をするのにプログラムをリカーシブルに作ったら意外と簡単にいったこともありました。禁則処理や表処理では、プログラムが自分で自分を呼び出すようにすれば、繰り返し処理について深く考えなくてすみます。しかし、ロジックがまちがっていたときのデバッグは並大抵ではありませんでした。

その点、Cobolは最初は敷居が高く、覚えるのがたいへんでした。Cobolは高島屋の顧客データベースのメンテナンスとDM発送処理の開発でマスターしました。何でも、5,000行くらい書くと、覚えてしまいますよね、OSが何であれ。

そうは言っても、C++ははじめてで今後どういう展開になるか、見当がつきません。また、意味のあることをやっているかどうかも、現時点では判断さえつきません。

1月は、ほかに優先順位の高いやらなければならないこともあり、こればかりに集中できません。そのことも配慮しておく必要があります。

スクリーンショット 2013-12-27 22.18.26