質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

5回答

11164閲覧

【C言語/初心者】if文の中に関数を入れて戻り値で条件判定する場合の懸念

ak_

総合スコア12

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2020/06/27 10:54

編集2020/06/28 04:15

表題の件で質問させてください。

レガシーなプログラムに対して、手を加えようとしています。
きれいなコードじゃないなあ、と思ったため質問させてください。

IF文の中に関数を入れてその戻り値によって条件する場合、
戻り値のパターンが2つ以下なら以下のように書けると思います。

c

1if(hoge() == 0){ 2処理A 3}else{ 4処理B 5}

ただし、戻り値のパターンが3つ以上ある場合は、

c

1if(hoge() == 0){ 2処理A 3}else if(hoge() == 1){ 4処理B 5}else{ 6処理C 7}

みたいな書き方になるかと思うのですが、
こうすると、関数hogeは2回よばれちゃってますよね…。
かといって、switch文に関数は入れられないし。

こういう時に、
・関数を1回しか呼ばない
・戻り値で場合分けする

という条件を満たす方法はないのでしょうか?

結局自分は断念して、
戻り値のパターンを2つにして、関数hoge内にフラグを持たせて
それで条件分岐するようにしたのですが、
なんか賢い書き方じゃないなあと思っていました。

《追記》
switchで不可と書きましたが、勘違いでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cateye

2020/06/27 11:04

>IF文の中に関数を入れ・・・・・る、必要が有るんですか?
YT0014

2020/06/27 11:06 編集

switch(hoge())ってできませんか?caseには指定できませんけど
ak_

2020/06/28 04:16

>IF文の中に関数を入れ・・・・・る、必要が有るんですか? もとのコードがそうなので、 なるべくそこは変えないほうがいいかなと思ったためです。 >switch(hoge())ってできませんか?caseには指定できませんけど 出来ました。勘違いしていました。 追記にて、記しておきました。
guest

回答5

0

可能性の話として...

関数型言語でもなければ、hoge()が毎回同じ結果を返すものかどうか、というのは何の言及もなく前提としてはいけないかと思います。

アンチパターンと言っていいでしょうけれど、もしhoge()の2回の呼び出しが違う結果を返すことがあるとしたら、不用意に関数呼び出しをまとめられません。

ここでの質問だったか、read()はストリームから1文字取得する関数として

C

1if(read()=='a'){ 2 //処理A 3} else if(read()=='b'){ 4 //処理B 5}

などというプログラムを書いて期待通りに動かない、と悩んでいる例を見たことがあります。その時は得られた1文字が'a'なのかそれとも'b'なのか、という話ではありましたが、それからの連想。
処理Bが'a'以外-'b'というシーケンスを期待していることもあり得るわけで。

投稿2020/06/27 22:07

thkana

総合スコア7659

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ak_

2020/06/28 02:57

毎回同じ結果を返すか、について言及できていませんでした。 ・現在機能しているソースコードではhogeは1度しか呼ばれていない ・2回呼ぶと、違う結果を返す可能性が僅かながらありえる。 という状態です。不用意に2回呼ぶ仕様に変更してしまうと、 現在のソースコードの信頼性を損ねる可能性があると考えたため、 1度のままにしておきたい、という思想で書きました。
thkana

2020/06/28 04:24

> 現在のソースコードの信頼性を損ねる可能性がある なら、綺麗かどうか以前に 「2度呼ぶように変えてはいけない」 ではないでしょうか?
ak_

2020/06/28 12:54

はい。なので質問文には、1回しか関数を呼ばないことを 条件として書かせていただきました。
guest

0

C

1int result = hoge(); 2if ( result == 0 ) { 3 処理A 4} else if ( result == 1 ) { 5 処理B 6} else { 7 処理C 8}

投稿2020/06/27 10:58

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

解決済みになってるけど質問です。速度的に問題ありますか?問題なければソースを直さないほうがいいと思います。if文の前に変数を1つ増やすと少しだけコードが複雑になります。コードはできるだけ簡潔に抑えるのがベターです。また、「動いているコードは直さない」という原則にも反します。これは、実運用されているコードはそれなりに信頼性が高いということです。

もし、コードをリファクタリングしたければ、カーニハン・パイクの「プログラミング作法」という本を読んでください。本屋で立ち読みとかでもいいです。あと、リーダブルコードという本、こちらはもしかしたらすでにお読みになっているかもしれませんね。本の紹介になってしまって申し訳ないです。

投稿2020/06/27 12:15

anndonut

総合スコア667

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ak_

2020/06/28 02:44

速度に関してまで、考えが及んでいなかったです。 >「動いているコードは直さない」という原則にも反します。これは、実運用されているコードはそれなりに信頼性が高いということです。 そういう原則やコーディングルールに関して無知だったので、 紹介いただいた本を読んでみます。ありがとうございました。
Daregada

2020/06/28 04:08

動作確認のコード(ユニットテストなど)を書いて、「外部から見た動作が変わらないこと」を確認しながら、プログラムの内部構造を改善すること(リファクタリング)は有効だと考えられています。やみくもに書き替えることはお薦めしません。
guest

0

ベストアンサー

戻り値を変数に入れてそれを使えば良いのでは

c

1int a = hoge(); 2if(a==0){ 3 処理A 4}else if(a==1){ 5 処理B 6}else{ 7 処理C 8}

投稿2020/06/27 10:58

ohys

総合スコア147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ohys

2020/06/27 10:59

被った
guest

0

かといって、switch文に関数は入れられないし。

あなたがなぜそう思いこんだのかは知りませんが、返り値が整数値で等値比較だけ行なうなら、switch文の冒頭の式で関数を呼び出して、返り値をcaseで処理してください。

C

1switch (hoge()) { 2case 0: 3 処理A 4 break; 5case 1: 6 処理B 7 break; 8default: 9 処理C 10}

投稿2020/06/27 11:00

編集2020/06/27 11:29
Daregada

総合スコア11990

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2020/06/27 11:04

戻り値が float とか char*(文字列) とかだと switch で多重分岐できないので万能じゃありませんけどね。 整数値限定なら無問題。
Daregada

2020/06/27 11:06

提示されていた例が整数なので問題ないと判断しましたが、整数値限定ですね。
episteme

2020/06/27 11:18

たとえ整数値でも hoge() > 0 , == 0, < 0 の3分岐だとアウトやし。
Daregada

2020/06/27 11:23

いや、これは「提示例の処理ならswitchで対応できるよね」という趣旨の回答なので、提示例にないものを持ち出されても困ります。それは「switchの制御式に関数が入れられない」ことが原因ではなく、「もともとswitchでは対応できない条件だから」が原因ですよね。
otn

2020/06/27 11:26

質問文では、関数が使えればswitch使いたいように書いてあるので問題ないのでは?
episteme

2020/06/27 11:28

あ、ごめんなさい。回答の趣旨は理解してます。 「switch文に関数は入れられないし」に対し、 「いや入れられるけど、なんも考えんと突っ込むわけにはいかんよ」てゆー、 "余計なお世話"ではありました。失礼しました。
Daregada

2020/06/27 11:30

その点に質問者が留意すべく回答を修正しておきました。
ak_

2020/06/28 02:50

戻り値の型に関して、詳細な条件の記載がなく、議論をさせてしまいすいません。 今回は整数のみでした。 また、仰る通り、確かにswitch文で条件分岐できました。 以前、switch文でトライしたとき、エラーが出てたため、できないんだと 思い込んでいました。(おそらく当時出たエラーは別箇所に問題があったのだと思います)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問