やる夫と学ぶプログラミング言語 C 88
ストーリー by soara
できるところからはじめるお 部門より
できるところからはじめるお 部門より
あるAnonymous Coward 曰く、
AA(アスキーアート)を用いて歴史上の出来事・ゲームの内容・調理法など様々な内容をストーリー形式で紹介するやる夫シリーズに、プログラミング言語Cを紹介するスレッドが出ていたようだ(まとめサイト第1話、第2話、第3話、最終話:プログラムの内容については第2話から)。
内容はprintf/scanfを使った標準入出力、if/while、switch、関数はmain()のみなどポインタ以前のC言語について解説したもの。main()のみだが、初心者に変数がグローバル変数だけと思わせるような筋、stdio.hをインクルードする理由を解説しない点についてはタレこみ人はどうかと思うが、C言語のとっかかりとしてコミカル(若干)に解説してるものとしては面白い試みだと思う。
挫折 (スコア:5, おもしろおかしい)
とは言うけどね (スコア:4, 興味深い)
>> 初心者に変数がグローバル変数だけと思わせるような筋、stdio.hをインクルードする理由を解説しない点についてはタレこみ人はどうかと思うが
これね、教えたことがない人のセリフ。教えると、こうするしか無いのよ(main()の外にint宣言おいてあるのはいただけないが)。
関数の概念の前にmain()関数があって、メモリの概念の前に"やscanfの&があったり、プリプロセッサの前に#includeがあったり、とどめ、printf()なんて可変長引数をとる、どう考えても最初に教えちゃいけない関数だったり。
ある程度目をつぶって教えるしかない場所なんですよ。で、ポインタやってから戻って「実はscanfの&は・・・」というように教えるしかない。main()の引数char** argvなんて・・・じゃん。
-- gonta --
"May Macintosh be with you"
プログラミング初心者にCを教えるのが間違ってる(Re:とは言うけどね (スコア:5, 参考になる)
新入社員にCを教える講座を持ったことがあります。プログラミング初心者対象で。
「プログラミング初心者にC言語を教えるのは間違ってる」と再三にわたり進言したのですが「業務で使用する言語を最初に教えないと」と却下。
なんとか講義時間を8時間(1時間を週2で全8回)確保して、以下の流れで教えました。
1コマ目:コンピュータの構造。CPU毎に機械語が異なる。コンパイラ。宿題は「C言語以外のプログラミング言語を調べてくること」
2コマ目:なぜ複数の言語があるのか。同じソースから異なる機械語にするには。コンパイラの移植。宿題は「クロスコンパイラとはどんなものか調べてくること」
3コマ目:適当に書いたテキストファイルをコンパイラに食わせる。なぜエラーが出るのか。宿題は無し。(だいたいシェルに慣れてなかったり質疑応答で潰れる)
4コマ目:Cの解説スタート。変数について。数学と異なる記号の使い方。function(関数)について。C言語はfunctionを組み合わせて作る。
宿題は「なぜsum関数をコンパイラに渡しただけでは駄目か考えること」(だいたいは文の区切りだの宣言だので時間がなくなる)
5コマ目:コンパイラはmain関数を決めうちで読み込む。mainでsum(4, 5)とかしてみる。コンパイラが困るのでプロトタイプ宣言がある。結果をディスプレイに出す関数は既にある。ソースコードにコピペする代わりにincludeしよう。.hについて。プリプロセッサとリンカの話。宿題は「プリプロセッサは何をしてくれるか調べること」
6コマ目:printfで結果の出力。forでのループ。ifでの分類。偶数だけを出力してみる。
7コマ目:配列の話。3で割り切れる数だけ配列に入れてみる。配列の出力。文字列が無い話。配列の先頭と\0の話。やっとHello World!
8コマ目:fizzbuzzを作ってみよう。質疑応答。
教えることを絞り込んだので、きちんと理解してもらえたようで意外に好評でした。
あとオマジナイを極力排除した組み立てにしたので「自分で理解してから使う」癖が付いたようで部署に戻ってからもスムースだったようです。
目をつぶって教えなくて良いように考えたら、なんとかなるもんですぜ:-)
Cを教えるのに、コンパイラの説明から入らないのは無謀ですし、プリプロセッサの説明をせずに標準ライブラリは使えません。
やる夫のは、せっかく前フリ長いんだからもっともっと丁寧にやって良かったんじゃないかなあ。
# Hello World!までの距離が長い言語は初学者向きではないと思うのですが、いまだに中々理解が得られないのが寂しいところ:-P
# たまにCに慣れたやつが居るのでその時は数独ソルバーかCのコメントを取り除くプログラムを書いてもらってました。
Re:とは言うけどね (スコア:2, すばらしい洞察)
>> 初心者に変数がグローバル変数だけと思わせるような筋、stdio.hをインクルードする理由を解説しない点についてはタレこみ人はどうかと思うが
(main()の外にint宣言おいてあるのはいただけないが)。
それがまさに「初心者に変数がグローバル変数だけと思わせるような」ジャマイカ。
このソースならローカル変数で書けるし、後々main()以外の関数を導入した際に説明が容易だと思う。
Re:とは言うけどね (スコア:4, 興味深い)
ここは、グローバル変数でよいと思いますよ。
初心者なんですから、グローバルもローカルもわからないでしょ。
おそらく、初心者にはローカルの概念が難しいと思われ、
関数を教えるにせよ、最初はグローバルで教え、
そのあと、ローカル変数を教えつつ、
それぞれのスコープの違いなどの特徴を学ぶのがスムーズかと。
最初は、問題を単純化して覚えやすくするために、
正しくないことでも、あえて正しいと教えることも多々ありますからね。
Re:とは言うけどね (スコア:3, すばらしい洞察)
初心者はmain()以外の関数なんて分からない(少なくとも自分から作ろうとはしない)から, グローバルとローカルのいずれか一つで話を進めるならローカル変数だけにした方が後での実害は少ないです.
おそらくプログラマと称している人の半分程度は, 関数を作ることができないと考えておいた方が安全です.
Re:とは言うけどね (スコア:1)
おそらくプログラマと称している人の半分程度は, 関数を作ることができないと考えておいた方が安全です.
マジすか?!
じゃいったいそういう彼らは関数作らないで何を作るんで?
Re:とは言うけどね (スコア:5, おもしろおかしい)
main()も関数だから (スコア:1)
Cの場合、関数が作れないとバグも作れないゾwww
Re:main()も関数だから (スコア:1)
すみません。ネタがわかりにくくて。
「main()も関数だから関数が作れなければmain()も作れなかろうwww」という揚げ足取り系小ネタでした。
Re:とは言うけどね (スコア:1)
基本的にはmain()関数, あるいは仕様書に提示されているエントリ関数(これもstubは事前に提供されることが多い)だけで, 内部的にはのべたんで記述します. それが1万行を越えたとしても, 決して複数の関数に分割することはありません.
関数とは彼らにとっては既存の機能を呼び出すために存在するもので, 自分で作成するものではないのです.
Re:とは言うけどね (スコア:2, すばらしい洞察)
main()も関数…って茶々は他のコメントで入れたので置いておくとして。
それ書いてる本人は辛くないんですかね?
main()に全部書いてねって言われたら、それは普通に書ける人にとってはむしろ拷問ですよねぇ?
(関数がダメってことは多分関数型マクロはもっとダメですよね?)
かの史上初のプログラマブルな計算機である解析機関(機械式、残念ながら完成しなかった)にさえ
Ada女史がサブルーチン・コールの仕掛けを入れようとしたという歴史もありますし、
1万行にもなる場合、「必要は発明の母」的に関数書きたくなったりしませんかね?
#高校生の頃(1980年代前半)、FORTRAN入門でズラズラ変数並べる代わりに配列を習った記憶があるけどそんな感じに。>「必要は発明の母」
必要性・動機があれば学習は速そうなものですが…。
Re: (スコア:0)
.NET系だとイベントハンドラ内にゴリゴリ書かれてしまいますね。
そもそも教える側が関数/メソッドを切り出すための考え方を教えていないので
関数を書くと、追跡すべきコードが分散して読みにくくなるとしか思ってないと思います。
当然、教える側も分かってません。
Re:とは言うけどね (スコア:2, すばらしい洞察)
私にとっても拷問です. でもここで気をつけなくてはならないのは, それが「普通」であるという認識が間違っている(かもしれない)ということです. 自称プログラマの内のかなりの割合が, 問題を論理的に分割して対応するよりも, 既存の処理パターンを高機能エディタやIDEで集積して一つの物にすることの方が簡単と思っている(らしい)ことです. 前者を解析型, 後者を集積型と呼ぶとすると, 解析型ではプログラミングに際して常に考えることを要求されるのですが, 集積型では仕様書に従ってパターンを並べていくだけなので考えなくてもよいということみたいです. ですからそんなプログラムを書く当人は, 苦労はするけど決して拷問とは考えていないみたいです.
ちなみに, さらに酷い拷問は, こうして作られたプログラムをメンテナンスさせられることです.
Re:とは言うけどね (スコア:1)
名大、東工大、九大の学生さんたちや、某F社の研究所の同僚、先輩などプログラミングする人々を眺めてきましたが、本当に「main()に全部」をやった人を実地で見たことは(「笑い話」としては出てきても)なかったんですが、これは実はあんまり普通でない環境なんでしょうか?
Re:とは言うけどね (スコア:1)
## 職場環境の改善に自ら乗り出すって手もありだけれど…
以前、乗り出しました。
プロジェクトのメインツールの作り直しの機会に。
といってもさすがに「main()に全部」な人は居なかったので
そこの改善ではなく「Unitテスト書きましょう運動」。
「原理主義的だ!」とブツつかれつつも、結果として若干改善。
しかし今ひとつうまくモジュール化がなされた設計になってなかったので、結果としてテストしにくく、今ひとつテストが不十分なモジュールが発生・・・。現在担当者の異動によりそこを引き継いだのでリファクタリング中。
Re:とは言うけどね (スコア:1)
プロシジャ?
戻り値voidで結果をグローバル変数に格納とか、よく見かけちゃいます。
Re:とは言うけどね (スコア:1)
スパゲッティでは?
Re:とは言うけどね (スコア:1)
日本の4年生大学を卒業していて、関数という言葉は知っているはず(数学で出てきますから)なのに、
それがプログラミングで出てくる「関数」と結びつかない、ってことはありますよ。
やってることは数学の関数と同じなのに。
パラメータが複数あって、結果が一つだけ出てくるのだから、これは関数でしょ?
で、関数として作っておけば、他から使い回せるでしょ?
って言っても、なかなか関数を作れない、ってのは、実際に新人教育で教えてみて半分以上いたし……
ただ、こういうのは、「処理を分割すること」がそもそもできてない。
ある処理を、細かい処理の箇条書きにばらしてみることが上手くできないんですね。
ここができるかどうかが、そのままプログラミングができるかどうかにつながるかと思います。
-- To be sincere...
Re:とは言うけどね (スコア:1)
まぁでも、数学、特に解析学とかでやる関数は連続関数なんでイメージしにくいかもしれませんね。対応関係よりグラフとかのイメージのほうがどうしても鮮烈でしょうし、離散的な対応関係に拡張して考えるのは若干ギャップがあるのかもしれません。
もちろん連続関数も集合論的な意味での関数を基礎においていて、そこをわからないとちゃんと理解はできないとは思うんですが、離散数学とかやらないとイマイチ想像しにくいのかもしれません。工学部だと計算機関係に進まないと離散数学はやらないで解析方面だけで終わる可能性もありますからね。
また値の対応関係としての関数と計算手順として書かれた関数の関係も若干ギャップがある可能性もありますね。
Re:とは言うけどね (スコア:1)
関数型言語をかじった立場で見れば、C言語の関数って数学的な関数とは、副作用のあるなしの所が全然違うんだもの。結びつかないのはある意味、当然じゃないですか?
私はC言語の"function"を「関数」って訳したのは結果的にあまり良くなかったと思ってます。今考えれば「機能単位」くらいかな。でも最初に「関数」って訳語をあてた時、C言語は「分かっている人が使う言語」でしたからね。そこは責められないし、関数という言葉が「分かっている人達」に広まった状況から別の言葉を使うと、更に現場で混乱しそう。じゃあどうすれば良かった、これからどうすればいいのかと言われると分かりませんが。
「C言語の関数って機能単位の事なんですよ、数学の関数とはちょっと違う」って研修の時に言うのかなぁ。
vyama 「バグ取れワンワン」
Re:とは言うけどね (スコア:1)
機能単位としてしまうと、「式の中に繰り込むことができる」というのが上手く表現できないと思います。
結局、関数という訳語が一番なのではないかと。
関数が数値以外を返すことがある(もしくは何も返さない)ってとこにブレークスルーがあるのかなあ。
-- To be sincere...
Re:とは言うけどね (スコア:1, すばらしい洞察)
初めて何かをやる場合などは、最初に教わった方法・手順で後々まで覚えていく事って結構あると思うので、
意味もわからないところから教えるのであれば、ローカル変数使用した方法で教えていって
コードを組むときの定石として覚えてもらうって方法もアリかなぁとは思います。
(手段としては#include をおまじないと教えるのと同レベルかもしれませんが・・・)
Re:とは言うけどね (スコア:1, 興味深い)
> 後々main()以外の関数を導入した際に説明が容易だと思う。
関数の部分で ベタ書き → 関数化 と教えるのなら
変数についても グローバル → ローカル と教えた方が合理的じゃありませんか?
問題点の説明も、構造化の歴史をなぞった方が教えやすい
数年、Cを教えていた事があります。
初めからグローバルで教えた事も、ローカルにした事もありますが
ある程度のステップを踏んで学習する際は、後から覚えた方法を(より良い方法だと思って)使う傾向にあります。
グローバル→ローカルで教えたときは、ローカルで書く学生が多かったですが
ローカル→グローバルで押してた時は「こっちの方が便利だ」と思ったのか、グローバルで書く学生が多かったような記憶があります
ちゃんと説明はしたんですけどね
Re:とは言うけどね (スコア:1, すばらしい洞察)
それはどうでしょうか。単に最近聞いたほうを使っただけのように思いますが。 詳細な説明なくグローバルで進め、途中でローカルとの使い分けを学ぶと、 defaultがグローバルで,特定の使用状況のときローカルをつかうように捉えそうです。 perlは言語仕様的にそうなってしまいますが、Cではローカルが基本で他との共有が 必要なもののみグローバルにすべきでしょう。 教える順番の問題というより機能の違いを教えきれていないというか...
もう一つ理由があるげ (スコア:1)
文章だけなら、たれたれと書き流す事も出来るのですが、
AA連投というスタイルから「細かい事を書き連ねるのが困難」
という制約があったのではないでしょうか。
「テンプレのセリフ書き換えりゃ出来るんだろ?」
と感じる人も居るかと思いますが、
意外に工数がかかりますので。
また、文字数ばかりがかさんでいくのも、
作っていていまいち許しがたいので、
詳細な説明文を織り込むのは、
中々難しいのではないかと。
Re:とは言うけどね (スコア:1)
オーバーランを気にしなくてよい環境は結構多い (スコア:0)
Re:オーバーランを気にしなくてよい環境は結構多い (スコア:1)
scanf()を学習用として割りきれる人は, 今日では初心者では無い.
Re: (スコア:0)
ポインタ教えないならC言語である必要ないですよね
とっつき辛いし流行りのオブジェクト指向的なプログラムを学ぶのも難しいし
RubyとかPythonとか覚えてもらった方が百倍役にたつと思いますよ。
Re: (スコア:0)
何よりも問題なのはプログラミングとC言語をまとめて教えているところです。C言語はおよそプログラミングの学習に向かない。
つまりCも今や (スコア:3, おもしろおかしい)
AA(アスキーアート)を用いて歴史上の出来事…(以下略)
つまりCも今や歴史上の出来事に?!
Re:つまりCも今や (スコア:1, おもしろおかしい)
先生、私の歴史にはまだCが出てきてませんっ!
#C言語よりPerlの方が難しいと思ってるAC
Re:つまりCも今や (スコア:1)
1972年以前の時間にご滞在だというわけですね?
Re:つまりCも今や (スコア:1)
他のやる夫シリーズにそれなりに納得してたのが悲しくなってきた・・・ (スコア:2)
今まで他のやる夫シリーズにそれなりに納得してたのが悲しくなってきました。
歴史とか経済とかあって素人目にはいい感じにいいところをついているように見えたのですが、
やっぱりこのC言語編とおなじでほんとうに上辺をなぞっただけだったのかな。
わかっちゃいたけど、自分の専門分野で見せつけられるとちょっとショックが・・・。
Re:他のやる夫シリーズにそれなりに納得してたのが悲しくなってきた・・・ (スコア:1)
>上辺をなぞっただけだと何が問題なのだろうか。
何の役にも立たないどころか、時には害悪にさえなりうるから。
スパゲッティプログラム量産機と化した素人プログラマの群れ相手に
殺されかけたことがあれば、この意味も理解できるでしょう。
逃げ道を作っておくべき (スコア:1)
とか。
嫌な予感しかしない (スコア:0)
別に敷居が高くないのに自分では何もアウトプットを出さず、
「ココが悪い」「ゴミwww」とか上から目線のエリートエンジニアが
沢山湧いてきそうだ・・・。
Re:嫌な予感しかしない (スコア:2, すばらしい洞察)
これまでの実績でもスラドはそういう人多いし、
すでにタレコミの時点で上から目線だし。
実際に行動する人 >> (超えられない壁) >> 言うだけの人
だと思うんですけどね。
Re:嫌な予感しかしない (スコア:1, すばらしい洞察)
平和主義と不作為がセットになるのは日本ぐらいだと思う。
世の中を平和にするのにどれだけの労力が必要なことか。
Re: (スコア:0)
「エリート」という単語の定義にもよるが、
本当に優秀なエンジニアが下らないマンガを見れば、
それを見下すのは当然の反応だと思うぞ。
下らないものを見てへりくだる必要が理解できない。
Re:嫌な予感しかしない (スコア:4, すばらしい洞察)
別に気に食わないなら気に食わないで構わないんですが、「俺が気に食わない物は全部ゴミ」的な考え方はどうなんでしょう?ということでは。
自分にとってくだらないものでも、他の人にとっては非常に価値があるということもあり得ると思います。
CやC++を何年も使っている人なら、ポインタについてグダグダ語られた文章を読む気にならないでしょうが、同じ文章がポインタにつまずいている初心者にとってはとても分かりやすく理解の助けになるかもしれません。
そういった立場や知識の違いを無視して、大上段から「ゴミ認定」するのは、何というか謙虚さに欠ける行動のような気がします。エリートってのはそういう意味のイヤミでしょう。
Re:嫌な予感しかしない (スコア:1)
>やっぱりゴミはゴミですよ。
ですね。
入門書でちゃんと読める、まともな解説がしてある本なんて見たことがない。
あるにしても何十分の一、或いは何百分の一の確率でしょう。
それ以外のその他大勢の屑本は、全部ゴミ認定しておいた方が結局は初心者のためなのです。
Re:そうは言ってもK&Rは敷居が高い (スコア:1)
スラスラとは行きませんでしたが、K&RでCをおぼえました。可能です。
Re:そうは言ってもK&Rは敷居が高い (スコア:1)
K&Rの日本語版は版が古いもの程、壊滅的に翻訳がおかしいので、まるで暗号です。
わかっていなければ翻訳がおかしいということにすら気付かないでしょう。
版が進んで翻訳が良くなってきた頃にはもうその本は必要無い程度にはレベル上がってるという…w
ひとつだけ疑問がある (スコア:0)
Re:ひとつだけ疑問がある (スコア:3, すばらしい洞察)
Re: (スコア:0)
やる夫AAの界隈では手塚漫画におけるヒケオヤジ的存在。人気キャラはAAがたくさん作られてて状況にマッチしたAAを引っ張って来やすいというのもあると思われ
Re: (スコア:0)
多分このスレのPart.18446744073709551616 [wikipedia.org]くらいにはMIKO GNYO/Linux [gnyo.org]のソースになってるんですよ。