C言語関係掲示板

過去ログ

No.619.条件式の評価順序

[戻る] [ホームページ]
No.6183

条件式について
投稿者---初心者(2003/05/09 15:02:29)


はじめまして。
教えてください。
2000年7月号の古いCマガジンの雑誌に記載の画像処理の
Kitterの2値化閾値決定法のアルゴリズムの中の閾値決定アルゴリズム
の中のサンプルコードについてですが、
最終行付近の
if(kai>0.0 && (th==0 || min>kai)) {
				min=kai;
				th=i;


の部分ですが、minの初期値がないのにこのif文の条件式の
(th==0 || min>kai)の||演算子(Or演算子)の入る式って評価できるのでしょうか?

左側のth=0は、初期値が設定されているから評価できますが、min>kaiの判断は
最初はできないのではないのでしょうか?




char sbuf[256];

int getThreshold(int *hist,int n)
{
	int th;
	int i,j;
	double min;
	int sa,sb,da,db;
	double ma,mb,mt;
	double oa,ob;
	double wa,wb,wt;
	double kai;
	double oo;

	th=0;
	for(i=1;i<n-1;i++) {
		da=0;
		sa=0;
		for(j=0;j<i;j++) {
			da+=(hist[j]*j);
			sa+=hist[j];
		}
		db=0;
		sb=0;
		for(j=i;j<n;j++) {
			db+=(hist[j]*j);
			sb+=hist[j];
		}
		if(sa!=0.0)
			ma=(double)da/(double)sa;
		else
			ma=0.0;
		if(sb!=0.0)
			mb=(double)db/(double)sb;
		else
			mb=0.0;
		mt=(double)(da+db)/(double)(sa+sb);
		wa=(double)sa/(double)(sa+sb);
		wb=(double)sb/(double)(sa+sb);
		if(wa!=0.0 && wb!=0.0) {
			oa=ob=0.0;
			for(j=0;j<i;j++) {
				oo=(double)(j-ma);
				oo=oo*oo*hist[j];
				oa+=oo;
			}
			oa/=((double)sa);
			for(j=i+1;j<n;j++) {
				oo=(double)(j-mb);
				oo=oo*oo*hist[j];
				ob+=oo;
			}
			ob/=((double)sb);
			kai=wa*log(oa/wa)+wb*log(ob/wb);
			if(kai>0.0 && (th==0 || min>kai)) {
				min=kai;
				th=i;
			}
		}
	}
	return th;
}


No.6185

Re:条件式について
投稿者---kikk(2003/05/09 17:32:45)


ども。


>(th==0 || min>kai)の||演算子(Or演算子)の入る式って評価できるのでしょうか?

いくつかの演算子は、演算の対象となる式の評価順序が規定されていて、
&&や||は、それに含まれます。&&と||の場合は最初に左側の式を評価し、
その時点で真偽が確定しない場合にのみ、右側の式を評価します。
つまり、&&は、先に左式が評価され、それが偽なら(偽が確定するので)
右式は評価されません。同様に、||は、先に左式が評価され、それが真なら
(真が確定するので)右式は評価されません。
# 最適化によってそうなるのではなく、言語仕様で規定されています

なので、(th==0 || min>kai)だと、th=0で初期化されているため、
最初の1回は右式は評価されないので、問題ないことになります。
(min>kai || th==0)だとだめです。

C FAQ
http://www.catnet.ne.jp/kouno/c_faq/c3.html
の3.4, 3.5あたりも参考にしてください。


では。

No.6186

Re:条件式について
投稿者---初心者(2003/05/09 18:00:07)


なるほど。
たいへんありがとうございました。