C言語でnanを使うことに問題はあるか

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
lon

C言語でnanを使うことに問題はあるか

#1

投稿記事 by lon » 9年前

こんにちは。
C言語に関する質問です。
環境はlinuxのCentos6です。

ある引数Aがあり、その引数に値が入力されたかどうかの判定にnan(isnan)を使うことを考えています。
この方法が問題があるかどうか、またはより良い方法があるか教えてください。

以下に簡単な例を書きます。
ファイルとして、
・main.c
・parameter.txt
 →パラメータの値が入っている(今回はa,bとする)
があるとします。
内容としてはa+bの足し算です。
parameter.txtにa,bの値が書いてあるのでそれを読み取ります。
しかし、aの引数を受けた場合は引数の値を優先して足し算に用いる、
という内容です。
色々省略して書いていますがご了承下さい。

コード:

#include 色々
int main(int argc, char **argv){
double a;
double arg_a;
int b;
int sum;
FP *fp;

//parameter.txtの読み取り
fopen=(fp,"parameta.txt", "r")
a = 1行目;
b = 2行目;
fclose(fp)

//引数の受け取り
arg_a = a;
他にも多くの引数があるとする。

if([もし引数があったら]){
a = arg_a;
}else{
何もしない
}

sum = a + b;
printf("sum=%lf\n", sum);

return 0;
}

以上のようなプログラムだとして、問題は[もし引数があったら]の部分です。
引数を受け取ったかどうかの判定として、
1.arg_a用のflagを用意して、flagに1を代入する。
ことが一般的なのかと思っています。
今回考えていることは、
2.arg_a = nan(NULL)を最初に代入しておき、if文でisnan(arg_a)を用いる。
という方法です。

1番の方法だと引数が増えてしまい、複数個になった場合煩雑になるかなと
思い、敬遠しています。
2番の方法が問題があるかどうか、またはより良い方法があれば教えてください。

よろしくお願いします。

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: C言語でnanを使うことに問題はあるか

#2

投稿記事 by h2so5 » 9年前

そもそも、flagに1を代入するかどうか、NaNを実数で上書きするかどうかはどうやって判定するのでしょうか。

lon

Re: C言語でnanを使うことに問題はあるか

#3

投稿記事 by lon » 9年前

h2so5 さんが書きました:そもそも、flagに1を代入するかどうか、NaNを実数で上書きするかどうかはどうやって判定するのでしょうか。
言葉足らずで失礼しました。

flagの場合は、
例文のうち、

コード:

//引数の受け取り
arg_a = a;
他にも多くの引数があるとする。
の部分で、代入と同時にflag=1にします。

isnanの場合は、arg_aの宣言後に
arg_a=nan(NULL)
で初期化します。

IFの判定では、
flagの場合は、flag==1で
isnanを使う場合は isnan(arg_a) != 0などで
書けば良いと考えています。

よろしくお願いします。

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: C言語でnanを使うことに問題はあるか

#4

投稿記事 by h2so5 » 9年前

flagが1かどうかで判定するということは、flagが常に1とは限らないわけですよね。
ということはその前にflagを1にするかどうかで条件分岐が存在するはずですが、その部分をどうするつもりなのかがよく分かりません。
「引数の受け取り」部分の処理が不明なのです。

lon

Re: C言語でnanを使うことに問題はあるか

#5

投稿記事 by lon » 9年前

h2so5 さんが書きました:flagが1かどうかで判定するということは、flagが常に1とは限らないわけですよね。
ということはその前にflagを1にするかどうかで条件分岐が存在するはずですが、その部分をどうするつもりなのかがよく分かりません。
「引数の受け取り」部分の処理が不明なのです。
返信ありがとうございます。
書洩らしが多く、ご迷惑おかけしています。
flagは宣言と同時に0に初期化しておきます。

コード:

//引数の受け取り
arg_a = a;
他にも多くの引数があるとする。
の部分が曖昧でした。実行時に”もし引数があれば”、
arg_a = a;
a_flag = 1;
を両方行う、ということです。

引数(a)がなければ、parameter.txtファイルから読み込んだ
aを足し算に用いたいのです。

コードの書き方が曖昧すぎました。
申し訳ないです。
また何かあれば教えてください。

よろしくお願いします。

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: C言語でnanを使うことに問題はあるか

#6

投稿記事 by h2so5 » 9年前

lon さんが書きました: の部分が曖昧でした。実行時に”もし引数があれば”、
arg_a = a;
a_flag = 1;
を両方行う、ということです。
この部分の「”もし引数があれば”」の部分が具体的にC言語でどのように記述されるのかを聞いているのですが。
「引数がある」という状態が一体何を意味しているのかが分かりません。

lon

Re: C言語でnanを使うことに問題はあるか

#7

投稿記事 by lon » 9年前

h2so5 さんが書きました:
lon さんが書きました: の部分が曖昧でした。実行時に”もし引数があれば”、
arg_a = a;
a_flag = 1;
を両方行う、ということです。
この部分の「”もし引数があれば”」の部分が具体的にC言語でどのように記述されるのかを聞いているのですが。
「引数がある」という状態が一体何を意味しているのかが分かりません。
失礼しました。
1.flagを用いる場合
if(a_flag==1)
です。
2.nanを用いる場合
if(isnan(arg_a)!=0)
です。
また、それぞれ
1の場合
・flagは0に初期化しておく。
2の場合
・arg_aはnanに初期化しておく。
とします。

flagを1にすること、arg_aにnan以外を代入することは、
//引数の受け取り
で行います。(記述しておらず申し訳ないです。)
なので、”もし引数があれば”ということは実際には
//引数の受け取り
の部分で終わっています。

よろしくお願いします。

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: C言語でnanを使うことに問題はあるか

#8

投稿記事 by h2so5 » 9年前

引数を受け取る時点でa, bに直接代入してparameter.txtから読んだデータを上書きしてしまえば済むと思うのですが。

lon

Re: C言語でnanを使うことに問題はあるか

#9

投稿記事 by lon » 9年前

h2so5 さんが書きました:引数を受け取る時点でa, bに直接代入してparameter.txtから読んだデータを上書きしてしまえば済むと思うのですが。
返信ありがとうございます。
この例文だと本当にそうですね。ご指摘通りで実現できると思います。

ただ実際は引数を受け取るプログラムは、別の関数(arg_checkとする)で定義しています。
そのためarg_checkに対しarg_aは渡しますが、aは渡さないのです。
そのため引数を受け取る段階でaに値を代入することができません。
(arg_checkは他のプログラム等にも用いるため、aのために引数を追加することはあまりしたくないのです…)

flagの処理や
arg_aにnanを代入しておくことも、実際にはmainではなくarg_checkで行います。

よろしくお願いします。

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: C言語でnanを使うことに問題はあるか

#10

投稿記事 by h2so5 » 9年前

arg_checkをこういう設計にするのはどうでしょうか。

コード:

#include <stdio.h>

enum arg_result {
	ARG_A = 1 << 0,
	ARG_B = 1 << 1,
	ARG_C = 1 << 2
};

int check_arg(int *a, int *b, int *c) {
	int r = 0;
	
	if (a && <引数Aあり>) {
		*a = <引数A>;
		r |= ARG_A;
	}
	
	if (b && <引数Bあり>) {
		*b = <引数B>;
		r |= ARG_B;
	}
	
	if (c && <引数Cあり>) {
		*c = <引数C>;
		r |= ARG_C;
	}
	
	return r;
}

int main(void) {
	int a, b, c;
	int r = check_arg(&a, &b, &c);
	
	if (r & ARG_A) {
		// 引数Aあり
	}
	
	if (r & ARG_B) {
		// 引数Bあり
	}
	
	if (r & ARG_C) {
		// 引数Cあり
	}
	
	return 0;
}

閉鎖

“C言語何でも質問掲示板” へ戻る