gooブログを検索して眺めていたら、次の記事が目に入った。
んん〜〜〜。
いや、そこで書かれているプログラムはC++のモノじゃない。単なるCの(しかもANSIの)モノだ。
CとC++の見分けが付いてないのか。あるいはC++の初心者向け入門書かなんかで紹介されているプログラミング法が実はCのモノだったのか。
いずれにせよ、現時点ではC++はCの上位互換ではない(※1)。この2つはハッキリと分けていった方がいい、ってのが原則、となる。
ただ、実行環境がAndroidって事もあって、その辺どうなってんのか、はちと分からん。
そもそも、いわゆる「組み込み環境」では現行のCの仕様に従ってない処理系が多い事もあり、それもあって、「スマホでプログラミングなんざ学んではいけない」って言ってるわけだが。
一方、マトモな、PC上の開発環境だと、以前も指摘したが、Microsoftの(C++ではなく)C環境でも、現時点での最新仕様であるC17が使えるようになっている。
よって、まずはWindowsでは、MicrosoftのVisual Studio系でのCを使うのなら、C11/C17が使えるようにインストールしておくべきだ。
そしてANSI Cスタイルでコードを書くべきではない。件のページで最後に「予想した通りに」動く、と書かれたプログラムは、JIS C仕様(ISO C99に当たる)以降ではまずは次のように書くべきだろう。
![](https://blogimg.goo.ne.jp/user_image/7b/e1/e384775beb0f62867ed559578bd358b5.png)
前にも書いたが、C99以降の「望ましいプログラミング書法」をキチンと使ったC言語入門書は基本的に存在しない。おっさん共は「俺は昔っからこう書いてきたんだよ」と仕様の確認もせず、ダラダラと「長年培ってきた」もはや(フォーマルでは)通用しない書き方を垂れ流ししてるから、だ。(C言語に於いては)おっさんは勉強しない。おっさんは邪魔だ。おっさんは常に老害予備軍だ。
だからマジで、C/C++を今学ぶならRustにすべきだ、ってのはそういう意味なんだ。おっさんが近づかない場所へ若人は逃げるべき、だ。おっさんは貴方の害になる事しか基本言わない、って事を覚えておこう。
じゃなければ、上のような「仕様的に望ましい」記述を心がけよう・・・いや、何だかメンド臭そうに見えるのは事実だけどな(笑)。
いずれにせよ、まず心がけるのは、forループ内でカウンタ変数の初期化をする事。forの外部でカウンタ変数の初期化をするのは既に「悪い書き方」だ。サイテーでもこれだけ、は心がけるように。
もう一つ、オリジナルのコードには問題がある。それはmain関数がコマンドライン引数を求めてる事だ。
いや、コマンドライン引数を求める事自体は悪い事じゃない。悪いのはそれを利用してない辺り、なんだ。
そこのブログの筆者はわざわざループの初期値と終了条件の値を書き換えてコンパイルしている。ハッキリ言うと、あまり賢くないやり方だ。書いたソフトウェアの再利用性を阻害したようなプログラムを書いている。
せっかくコマンドライン引数を受け付けるような設計にしたんだから、ループの初期値と終了条件はコマンドライン引数として受け付けるようにすべきだろう。int argcはコマンドライン引数の個数の指定、char** argvはコマンドラインを文字列として受け取った配列を意味する。
つまり、まずは、
![](https://blogimg.goo.ne.jp/user_image/70/3c/7b4425085c6d28fd9b1e35bc34339ef6.png)
と言う風に、コマンドラインとして受け取った文字列2つをループの初期値、終了条件値として組み込む。
これだけで
![](https://blogimg.goo.ne.jp/user_image/2e/75/d7737241d3a7fd4ec53be9583692aac2.png)
とコマンドライン引数でループ範囲を指定出来、同じプログラムのままで使いまわしが可能、となる。
Cプログラミング初心者こそがコマンドライン引数を活用すべきだ。scanfによる入力は危険が多い。そして初心者が扱うCプログラミング課題は、実の事を言えば、入力ではなくコマンドライン引数を使う程度で回せるモノの方が多いんだ。
さて、残りは「暴走」に付いて、だ。「暴走」は初期値が終了条件値より小さかった場合に起こる。よってこれを防げばいいだけ、だ。
![](https://blogimg.goo.ne.jp/user_image/50/90/f5a8316a63ba974c6f32757c59ccb264.png)
以上、だ。
あと、宿題的な事を言えば、コマンドライン引数で受け付ける数値(文字列)が二個以下の場合、エラーを出して終了するのではなく、デフォルト引数が発動する、ようにしてもいいだろう。
その辺は各自考えてみてほしい。
さて、ではホンマモンのC++で同じプログラムを書くにはどうするのか。
正直、全然C++は詳しくないし、テンプレートくらいしか使った事がないんだけど、恐らく典型的なパターンでは次のようになるんじゃなかろうか。
![](https://blogimg.goo.ne.jp/user_image/2e/8b/f8030506f6663f24903af7e4bafd7955.png)
#includeするヘッダが違う。そして出力が見慣れないstd::coutと言うモノになっている。使用方法も独特だろう。
こう、C++って言語は「枠組み」はCなんだけど、標準的に使う命令類がこのようにCとは随分と食い違っている。やはりもはや「完全に別言語」なんだ。
くれぐれもCとC++を混同しないようにしよう。また、混同しそうな人は素直に「素直な」Rustを学んだ方が、2024年現在では遥かにマシな筈だ。
※1: 確かにC++が生まれた当初は、C++はCの上位互換を目指して開発された。が、これは過去の話であって、現在もそう、と言う事はない。
いつぞやも見たが、「自分が愛用している言語の仕様も把握してない」なんて人の言う事はマトモに受け取らない事。