No Such Blog or Diary
cygwin 上の fread の挙動とか
- 2012-05-18 (Fri)
- プログラミング
"rb" ないし "r" で fopen した時には CR+LF をそのままにする.戻り値は,読み込んだバイト数 / サイズ.直感的で平和.
"rt" で fopen されてると CR+LF を LF に置き換える.戻り値は,(読み込んだバイト数 ー その中のCR+LFの数) / サイズ.先に CR+LF を LF に置き換えてからバイナリモードと同様に動く.つまり,カウント数×サイズ よりも多くのバイトを読みに行くかも.
つーかなんでテキストモードとかあるんだ? 要らない子だと思うのだけど.
- Comments: 0
- TrackBack (Close): -
C言語で return を省略した関数の戻り値を使うのは不定
- 2012-05-07 (Mon)
- プログラミング
ISO/IEC 9899 のC99の仕様とか C11のドラフト の 6.9.1 Function definitions には次のように書かれている.つまりは return なしで関数の最後まで行き,その関数の戻り値が使われたなら,何が起こるかわからないと.
12 If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.
が, どうせ return 文が無いだけならコンパイラが %eax にデータを上書きしないだけなので,それを期待すれば下の階乗のプログラムは想定通りに動く(gcc 4.5.3 @ cygwin で確認).つまり,関数の最後で関数を呼び,末端の呼び出しの return をいちばん外側まで到達させる(末尾再帰なわけだけど).実際にアセンブリで見てもそうなってる.
#include <stdio.h> int fact(int k) { static int f=1; if( k <= 0 ) return f; f*=k--; fact(k); } int main(int argc, char*argv[]) { printf("%d\n", fact(10)); }
で,お手伝いしているプログラミング演習で結構な数の学生らが上のようなものを書いてしまい,それが適当に動いてしまったがために「再帰呼び出しを繰り返してもどこかで発行した return の値が最初の呼び出しまで戻る」とか勘違いしてしまったのが問題.その次の課題の二分探索のプログラムで結構な数の学生が再帰呼び出しに return を書いてくれないという状況に陥った.ま,再帰関数の説明の資料が void 型の関数だったので理解のしようもないのだけど(注:私は資料にノータッチ).
つか,それって再帰の深部で値を exception に乗せて throw で投げて再帰の外で catch するという exception-driven programming の思想だよね(注:普通の意味と違う).
- Comments: 0
- TrackBack (Close): -
意地の悪い問題
- 2012-04-09 (Mon)
- プログラミング
プログラミング演習の初回のアンケートに,下記のプログラムが何を計算するか分かれば答えよ,とかいう設問を入れてみた.
int hoge(int x, int y) { int k = x % y; while(k!=0) { y^=k; k^=y; y^=k; k = k%y; } return y; }
答えは「x と y の最大公約数」なのだけど,y と k のスワップを XOR 3 回でやっている点が意地悪い.まぁ,XOR 3回でスワップができると理解できた人もいたのでそれ程ひどくもないのかもしれないけど,よくわからん.
ほか,わからないものはとりあえず動かしてみようというの数人いて,「打ち込んだけどコンパイルエラーが出るぞどうなってるんだ」という質問をもらったりした.まあ,main 関数書いてないからねぇ…… 「次の関数が何を計算するのか」という質問にすべきだったか?
とりあえず,なかなかにレベルのばらつきが酷いのでなんともはや.
- Comments: 0
- TrackBack (Close): -
今日のエラーメッセージ
Template Haskell でゴニョゴニョしてたら GHC がパニクった.
TTreeB.hs:69:3:ghc: panic! (the 'impossible' happened) (GHC version 7.2.2 for x86_64-unknown-linux): unknownNameSuggestErr UnhelpfulSpan Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
まあ,生成したプログラムがおかしいんだろうけどデバッグめんどくさい……
- Comments: 0
- TrackBack (Close): -
RecordWildCards が便利だなぁ
Type class で可換半郡を次のように書いていた.
class CommutativeMonoid a where
oplus :: a -> a -> a, -- commutative, associative
identity::a -- the identity of oplus
data Bag a = Bag [a] deriving (Show,Ord,Read)
instance CommutativeMonoid (Bag a) where
oplus (Bag a) (Bag b) = Bag (a ++ b)
identity = Bag []
んで,type class だと不都合が生じたのでレコードで演算をまとめて持ち運ぶようにしたのだけど,定義部分に限っては RecordWildCards を使うとほとんど同じように書ける.演算の集合を定義するという点では type class でもレコードでも手間は大して変わらないっぽいねと. 楽だし簡潔でいい.
data CommutativeMonoid a = CommutativeMonoid {
oplus :: a -> a -> a, -- commutative, associative
identity::a -- the identity of oplus
}
data Bag a = Bag [a] deriving (Show,Ord,Read)
bagMonoid = CommutativeMonoid { .. } where
oplus (Bag a) (Bag b) = Bag (a ++ b)
identity = Bag []
インスタンス宣言に同じクラスの別のインスタンスを使う,例えば
instance (CommutativeMonoid a, Ord c) => CommutativeMonoid (Map c a) where
oplus x y = unionWith oplus x y
identity = empty
とかも
mapMonoid m = CommutativeMonoid { .. } where
oplus x y = let CommutativeMonoid {..} = m in unionWith oplus x y
identity = empty
と書けばほとんど同じ雰囲気かね.let を内側で使ってあげるのが大事.下のようにやると定義の本体の oplus が新しく定義される oplus になっちゃうのでエラーを食らう.
mapMonoid (CommutativeMonoid {..}) = CommutativeMonoid { .. } where
oplus x y = unionWith oplus x y
identity = empty
- Comments: 0
- TrackBack (Close): -
「一番嫌いなプログラミング言語は何?」
結構悩んだ.そもそも嫌いな物を思いつくとか難しい気がするのだけど,悩んだ結果 perl が一番嫌いなんじゃないかと.「使いたくない=嫌い」という解釈で.任意の目的に対して積極的に使用を回避したくなるのは perl しか思いつかん.
以下,答えを探している最中の思考.
sed:ロマン.頭の体操.やればなんでもできる便利な子.ワンライナーに必須.
C++:速い.演算子オーバーロードは素晴らしい.template で頑張るととても楽しい.
Haskell:遅延評価バンザイ.型推論バンザイ.高階関数バンザイ.参照透明バンザイ.
Java:どこでも動く.GCは素晴らしい.遅くない.リフレクションで頑張るととても楽しい.
awk:数値を使うワンライナーに便利.
bash:言語かこれ? バッチ処理には十分.
Python:キレイなスクリプト言語.
アセンブリ言語:速度のために必須.インラインで使うけど.
Lisp:なんでもありの素晴らしき自由.mix.eval/apply.
FORTRAN:良くも悪くも数値計算に必要十分.
C言語:真のC言語は安全.union は素晴らしい.#define で頑張ると楽しい.
OCaml:高階関数とか型推論とか欲しいけと遅延評価とか要らないし汚いことしたい時用.
php:web に関連するものならこれで.HTML との親和性が一番良いんじゃないかなと.
JavaScript:ブラウザで動くLispだよね.
閑話休題.
これを次の自己紹介の項目に入れよう.
- Comments: 0
- TrackBack (Close): -