多言語音声翻訳システム(アプリ「VoiceTra」)と …多言語音声翻訳システム(アプリ「VoiceTra」)とは ・31言語間の翻訳 ・うち23言語は音声入力、
C言語の課題を(エクストリームに)解こう #1
-
Upload
university-of-tsukuba-linux-user-group -
Category
Education
-
view
1.057 -
download
2
description
Transcript of C言語の課題を(エクストリームに)解こう #1
C言語の課題を
(エクストリームに)解こう
techno@Hirotaka Kawata筑波大学 情報学群 情報科学類 1年
プログラミング入門1の課題
ここからみれます。今回は、課題2 をやります。
http://www.ialab.is.tsukuba.ac.jp/~maeda/class/prog1/ 多分、みなさんなら、きっと簡単な課題でしょう!僕には、むずかしすぎて...(笑
ちょっと、情報科学類1年生の内輪向けですが...
ここでやること。
プログラミング入門 1 の課題を、究極の形で、皆さんと一緒に解いてきましょう。
条件:
課題の本来の趣旨を守る無理しすぎないなるべく効率の良いコードを(?)
やってみよう。
そうしよう。
課題1
整数を入力し,入力された値が偶数か奇数かを判定して出力するプログラムを作成しなさい.
よくありそうな、課題ですねー。きっと頭にうかんだ演算子は...
%
ですよね....
念のため、聞いておきます。
多分いちばん代表的なやり方は
if(i % 2) { 奇数 }
else { 偶数 }
% (あまりを求める演算子) 以外を使おうとした人。いてほしい...
もし % が使えなかったら...
どうするおつもりですか?
偶数であるか奇数であるかを見分ける方法...思いつきますか?
決して、ずっと / (割り算) していくなんてことはしませんよ。
例えばこんな例も...
0000 0001 -> 11111 1111 -> -1 (2の補数表現)
0000 0010 -> 21111 1110 -> -2 (2の補数表現)
0000 0011 -> 31111 1101 -> -3
なんだか気付きませんか?
デジタル人間なら、
2進数で考えよう。
偶数だと、必ず最下位ビットが 0 になる。奇数だと、必ず最下位ビットが 1 になる。
という法則がある。これを利用しよう。
マスクしましょう。
たとえば、5 が偶数か奇数か調べたいとき。
0000 0101 == 5
00000101 & 00000001= 00000001
if(i & 0x01) {} じゃだめですか?
実際どっちがいいのよ...
んー。
% を、CPU がどんな計算してるんだかわからん。(知識不足)たぶん、そんな命令もなかったはずだし。
マスクしたほうが、オールマイティーに早い。とおもう。(どんなCPUでもってこと)だけど、コード読みづらくなるかも...コメント重要。
課題 2
100点満点の点数を入力し、 50点以上であれば、A、50点未満であれば、B、0から100の数字でなければ、errorと出力するプログラムを作成しなさい.
おー。これもなかなかおもしろそう。
一般的なやり方
if(a < 0 && a > 100) { if(a >= 50) { puts("A"); } else { puts("B"); }}else { puts("error"); }
こんな感じだと思うのですがいかがでしょう?やり方は、いっぱいありますが。
だけど...
先程の例は、問題の文章通りに設計書を書いただけ。
ここから、人力最適化のお時間です。コンパイラの最適化なんかあてにしちゃーいけません。そもそも、コンパイラの最適化は、設計書に書いてあることに忠実に、ちまちまやってるだけだし。
人力最適化。
if(a >= 0 && a <= 100) { if(a >= 50) { puts("A"); } else { puts("B"); }}else { puts("error"); } error は最大 2 回の比較。
A, B は 3 回の比較。
という感じになります。
人力最適化。
たとえば、違う実装。
if(i >= 50 && i <= 100) { puts("A"); }else if(i < 50 && i >= 0) { puts("B"); }else { puts("error"); }
error は 3 回の比較。
A, B は最大 3 回の比較。 コードを短くすればいいというものではない。
人力最適化
if(i >= 50) { if(i <= 100) { puts("A"); } else { puts("error"); }}else { if(i >= 0) { puts("B"); } else { puts("error"); }}
error は 2 回の比較
A, B も 2 回の比較
完璧じゃない?ご想像にお任せします。
ただ、よくみると....
なんだか、行数が多い?
そう、コード量が若干多くなりました。
error を 2 回出力させているんです。
ということは、バイナリのサイズもでかくなる。(goto でジャンプさせるってのもありだけど、たぶん else で JMP したあとに、
goto でもう一度 JMP するような気もするので、実行時間的には JMP 命令だからといえど、最適なコードとは言えない...)(そうだ、アセンブラだ!!!)
人力最適化はほどほどに。
もうちょっと、語ると...
なんだか、あとのコードになるほど、理解しづらくなったとは思いませんか?
変に最適化しすぎると、コードが読みづらくなって、コードも長くなって... という状況になることが。まあ、ほどほどに。
課題 3
二つの整数値A、Bを読み込んで,BがAの約数かどうかを判定する プログラムを作りなさい.表示は以下のようにしなさい.
つまんねーな。これが一番単純じゃん?
いきなりだけど、解答例。
if(a % b) { puts("n");}else { puts("y");} これ以上、どうしろっていうの...ちょっと思いつきませんでした。
課題3について議論?
なんかありますかね?
最後に...
普通に解いて終わりでは、つまらない!とおもった、techno のお遊びでした。
これからも、また不定期にやるかもしれません。(LT とかで)プログラミングの面白さが少しでも分かってくれたら...
1年生いっぱいよんできてください。以上。
ご清聴ありがとうございました。