金曜日, 1月 11, 2008

C++解説1(最初に)

何か分からないけど自分の知識が抜けないようにというのが
一番の目的でC++の解説を書きます。
書いていると予想以上に忘れている事があるような気がするので
その時は調べて記述。
そうすれば復習にもなりますし

1.C++って
C++ってオブジェクト指向言語? というのは正確ではない言葉です。
C++はオブジェクト指向でも表現可能な言語であって
オブジェクト指向で絶対表現しなければならない言語ではありません。

オブジェクト指向と言えば、classという考えた方があります。
ではclassを使用しなければならないか?
もちろん、答えはNoです。
C言語しかしらないのであれば、それでいいと思います。
少しづつC++に移行すれば良いのですから。

C++って正直難しいと思います。
だから始めるにはかなり苦労すると思います。
でもそれは全体を見るからであって、登れる山を少しだけ登れば
それだけでも良い言語だと思います。

今C言語でプログラムを書く人の中でC言語の事を100%知っている人って
どのくらいいるでしょうか?
プログラムミング言語なんてそんなものです。
所詮言葉ですから。日本語、英語、中国語などと何も変わらないって事です。
日本語全てを理解しなくても、日本語が話せるように
C++全てを理解しなくてもC++で話せる(書ける)わけですね。

さらにC言語を知っている人がいるのであれば
それはさらにC++を始めない理由はありません。
C言語がC++の一部なのですから、C言語を知っているという事が
C++の一部を知っているという事イコールなので。

それではさっさと移行を始めましょう。


2.少しだけC++の世界へ

2.1.型チェック
最初に戸惑って下さい。
C++ってC言語と比べるとめんどくさいじゃないか!
って思わせるポイントに型チェック厳密化があります。
何かと言えば「char*」と「void*」は違うという事です。
あたり前と言えば、あたり前なのですが
以外と気付かないところで許されていたはずです。

char *p;
p = malloc(10);

って書いてませんか?
mallocはvoid*を返却する関数ですので
p = (char*)malloc(10);
と書かなければなりません。


これ以降はC言語が書ける人に対して
さっさとC++に移行してしまえポイントを書きます。
こんな事は今日からでも行ってしまえば良いって事です。
もしかしたら既に行っている人もいるかもしれません。

2.2.コメントは//を使え!
C言語においてコメントとは「/*」~「*/」で囲まれている範囲となります。
これはこれで良いのですが、C++では「//」を使います。
C99では「//」もコメントとして認められるようになったと認識してます。
何で「//」がコメントとして作られたのか?
もちろん、簡単な話です。「/*」~「*/」では問題があるからです。

-----------------------------------------------------------------------------------------
1: int main(void) {
2: int i = 0;
3: int j = 0;
4:
5: for(i = 0; i != 10; i++) {
6: printf("i=%d\n", i);
7: }
8:
9: printf("j=%d\n", j);
10:
11: return 0;
12: }
-----------------------------------------------------------------------------------------
上記プログラムの5行目から7行目までコメントにする場合
どのようにするでしょうか?
人それぞれなのでしょうが私的には2通りあると思います。
①4行目に「/*」8行目に「*/」を付ける方法
②5~7行目の行頭に「/*」行末に「*/」を付ける方法

このどちらが間違っている事ではないですしどちらでも良いと思います。
言ってしまえば、個人的な癖や学んできた環境によるものでしょう。
ただ6行目が以下の内容だったとします。
-------------------------------------------------------------------------------
6: printf("i=%d\n", i); /* 変数iの内容を出力 */
-------------------------------------------------------------------------------
いろいろと都合が悪くなります。
1の方法ではコメントが正しく行われなくなります。
言うまでもなく6行目でコメントが終わってしまうからです。
よって2の方法しかなくなってしまいます。
ただ2の方法も単純ではありません。
ようは行末では間違ったコメントになってしまうからです。
-------------------------------------------------------------------------------
6: /* printf("i=%d\n", i);*/ /* 変数iの内容を出力 */
-------------------------------------------------------------------------------
こんな感じとなりますね。
この例は大した問題ではありませんね。たかだか3行程度のコメントなので。
でも桁が1つ2つと違いがでたら重労働です。
基本的に、こんな作業は多くの方が一括置換で作業していると思いますが
この一括置換が行えないという場面に遭遇してしまうからです。
またコメントをする時は良いですが、その修正等に間違いがあり
コメントを解除する場合、かなりものを考える必要があります。
たかだかコメントでここまで苦労したくはないですね。

その点「//」コメントなら行末がコメント最終となりますので
何所までなんて考える必要がありません。
行頭にコメントする行全てに「//」を付ければ良いわけです。
もともとコメントされている行が存在し「////」となっても何の問題もないのです。
う~ん素晴らしいですね。というかもう常識ですね。
この程度のコメントはUNIX、LINUXの各shell、Windowsのbatch、OfficeのVBAなどで
すら採用されている事です。
C言語で「/*」「*/」でコメントを書く事が時代に逆行している。
と言い切ってしまって問題ないと思います。
C言語が悪いのではなく、C言語で「//」を使わないプログラムマーが悪いのです。
こんな簡単な事が今日から実践です。


2.3.変数の宣言は関数の先頭で行うな!
C言語は変数の宣言が関数の先頭である必要があります。
これも頂けない仕様です。
なぜ頂けないというと、バグを埋め込む可能性があるからです。

そもそも、loopで使用するindexを
なぜ関数の先頭で宣言しなくてはならないのか?
これもプログラミング言語が発展している今では考えられない事です。
script言語と言われるものは宣言すら必要ありません。
これが究極の姿でしょう。
しかし、パフォーマンスなどを考えると宣言しないまで行くのは
非常に困難なようですね。
そこで宣言するまでは良いとしても「最初に宣言しちゃって下さい」という
コンパイラーの都合は頂けません。

私が知っている限り、Fortran、Cobol、C言語など
古いプログラミング言語はこの傾向があります。
昔はしょうがなかったのでしょうね。

ただ、C++はその必要がありません。
って事は古い方法に縛られる必要はないって事です。
-------------------------------------------------------------------------------
1: int main(void) {
2: int i = 0;
3:
4: for(; i != 10; i++) {
5: printf("i=%d\n", i);
6: }
7:
8: return 0;
9: }
-------------------------------------------------------------------------------
上記プログラムは危険を持っています。
3行目に後でプログラムを追加された場合、
iが0ではなくなってしまうかもしれません。
i = 0;を初期化として入れる事でこの事態は防ぐ事ができますが
7行目に3行目で処理したiを使用する場合、iの値が保障されなくなってしまいます。
このような事態を防ぐには、新しい変数を追加するしかありません。
そもそも初めからそのようにすれば良いのが
そうされないのは2行目に変数宣言がある事で
無駄なworkを作成する事にならないかという考え方が発生するからです。
この考え方は非常に重要で、これを考えないと意味もなくworkを増やしていき
最後には理解不能なプログラムとなってしまいます。

ではどこがいけなかったのでしょう?

「無駄なworkを作成する事にならないか」と考えさせた事がいけないのです。
なぜそのように考えたたのかは状況によりますが
最低限、同一型が既に存在しているという理由は含まれます。
であれば、存在していなければ良いのです。
ようは使う範囲が分かっている変数は
その範囲でしか有効でない場所に変数宣言するべきなのです。
これは非常に重要なポイントです

C言語にもこの考え方は存在します。
誤解している人もいるようなので確認しておくと
C言語で変数宣言できる箇所はブロックの先頭です。
関数の先頭ではありません。
ブロックとは「{」でブロックを開始し「}」でブロックを終了します。
つまり、関数の先頭とはブロックの先頭でもある訳です。

C++で出来るようになった事はブロックの何処でも変数宣言可能となった事です。

-------------------------------------------------------------------------------
1: int main(void) {
2: {
3: int i;
4: for(i = 0; i != 10; i++) {
5: printf("i=%d\n", i);
6: }
7: }
8: }
-------------------------------------------------------------------------------
上は立派なC言語のプログラムです。
あんまりこのように書くことはしないと思いますが、
2行目にブロック開始を埋め込んでいるため
3行目の変数宣言は有効となります。
そして、ここで宣言した変数は7行目までが有効な範囲です。
実は、これだけでもかなりの変数使いまわしを防ぐ事ができます。
ただ、ネストが進みプログラムの可読性が著しく低下する事になってしまいます。

この「変数使い回し防止」「可読性」といった2つの観点で
クリアしたのが変数は何処でも宣言可能といったところでしょう。
これも直ぐに実践あるのみです。

ただのIndexが沢山宣言されていて、Indexの変数名が「i,j,k,l,..」などど
進んでいませんか?
まったくもって無駄な事です。

まだまだあるのかな?
私が思うにこれだけでも...

0 件のコメント: