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

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

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

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

Q&A

解決済

5回答

13466閲覧

(C言語)4つの整数値が全て等しい事を求めるには?

komon4242

総合スコア21

C

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

0グッド

0クリップ

投稿2017/06/22 23:54

こんにちは
整数型の変数が4つあり、4つの数が全て同じときに success そうでないときに error を表示するプログラムについて教えてください。

C

1 int a, b, c, d; 2 3 a = 1; 4 b = 1; 5 c = 0; 6 d = 0; 7if(a == b && a == c && a == d ){ 8 printf("success\n"); 9}else{ 10 printf("error\n"); 11}

順当なやり方だとこの方法だと思いますが、
変数の数が増えたらどんどん増やしていかないと面倒なので簡単に比較できる方法があれば教えてください。

以下の方法で試しましたが上手くいきません。

この方法だとNG!

C

1int main() { 2 int a, b, c, d; 3 4 a = 1; 5 b = 1; 6 c = 0; 7 d = 0; 8 /* 違うのにsuccessに入る */ 9 if (a == b == c == d) { 10 printf("success\n"); 11 } 12 else { 13 14 printf("error\n"); 15 } 16 17 return 0; 18}

この方法も駄目!

C

1int main() { 2 int a, b, c, d; 3 4 a = 1; 5 b = 1; 6 c = 1; 7 d = 2; 8 /* 違うのにsuccessに入る */ 9 if (a && b && c && d) { 10 printf("success\n"); 11 } 12 else { 13 14 printf("error\n"); 15 } 16 17 return 0; 18}

よろしくお願いします。

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

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

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

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

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

guest

回答5

0

ベストアンサー

if は真偽値を取ります。a == b == c == d これは (((a == b) == c) == d) と解釈されていて、つまりは ((TRUE == c) ==d)(FALSE == d) となり、結果 if の正ブロックに入りません。
変数が違うのですから、個々にチェックするのが当然です。if(a == b && a == c && a == d ){ が正しい書き方になります。もし変数を配列に出来るならループを回す事が出来ます。

c

1#include <stdio.h> 2 3int 4main(int argc, char* argv[]) { 5 int i; 6 int v[200]; 7 8 // 適当な値を入れる 9 for (i = 0; i < 200; i++) { 10 v[i] = 1; // 例として、たまたま全て同じ値だった 11 } 12 13 // 全て同じかチェックする 14 for (i = 1; i < 200; i++) { 15 if (v[i] != v[0]) break; 16 } 17 // ループが回りきったという事は全て同じ値 18 if (i == 200) { 19 printf("success\n"); 20 } else { 21 printf("error\n"); 22 } 23 return 0; 24}

投稿2017/06/23 00:01

編集2017/06/23 00:02
mattn

総合スコア5030

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

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

0

なんとなく気持ちは分かりますが、
正しい構文が煩雑に感じてしまうのは、
書き方の工夫で回避できるかと思います。

C

1if( a == b 2 && a == c 3 && a == d 4 ){ 5 printf("success\n"); 6

投稿2017/06/24 12:56

chun

総合スコア324

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

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

0

追記:マクロSAME4のような例を出しましたがあまりよい方法とはいえないですね。マクロの展開で第一引数のaが複数回展開されます。そのためaが単純な変数参照でない場合にいやなことが起きます。特に副作用がある式だったりすると最悪ですね。単に4引数の関数を定義する方法を挙げた方がよかったと思います。すみませんでした。

###以下元の回答
上げておられるコードの中では一番最初以外は正しくありません。2番目の書き方は演算子の優先度に従って括弧をつけた上で、括弧の中の評価結果が何になるか考えれば間違いに気づけると思います。3番目の例は&&の仕様を調べてみてください。

さて、多数の変数が同じかどうかということを問題にするとき「それらの変数の集合を統一的に扱えるようにしたい」なら配列にするのが順当だと思います。対象としたい値がN個あったとして配列にしておけばNが4であろうが10であろうがコードを変える手間が最小限(個数を表すNについてのみ)でよくなります。

配列にはできない事情があるならもうひとひねりする工夫も考えられると思います。もっとも素朴なものは固定個数の引数のマクロを定義することかと思います。

#define SAME4(a,b,c,d) ((a)==(b) && (a)==(c) && (a)==(d))


以下は若干トリッキーに思える方法です

もう少し凝ったものとしてネット上で以下のようなものを見つけました。マクロの引数を可変個にする方法で上記のマクロよりは若干型安全になっていると思います。申し訳ないですが、どの規格なら通用する書き方なのか自分は知りません。少なくともUbuntu gcc 5.4.0では使えました。
(Web上によいC言語規格の一次情報源があると助かるのですが、残念ながら自分は知らないです...)

C

1#include <stdbool.h> 2 3#define SAMEI(a0, ...) \ 4 _samei( \ 5 (int[]){ a0, __VA_ARGS__ }, \ 6 1 + sizeof((int[]){ __VA_ARGS__ }) / sizeof(int) \ 7 ) 8 9static bool _samei(int vals[], size_t nvals) { 10 int val0 = vals[0]; 11 for (size_t i = 1; i < nvals; i++) { 12 if (vals[i] != val0) return false; 13 } 14 return true; 15} 16 17... 18if (SAMEI(a)) { ... } // 意味はないが引数の個数が1つから書ける 19if (SAMEI(a, b)) { ... } 20if (SAMEI(a, b, c)) { ... } 21if (SAMEI(a, b, c, d)) { ... } 22

投稿2017/06/23 01:07

編集2017/06/23 07:31
KSwordOfHaste

総合スコア18404

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

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

raccy

2017/06/23 10:26

> (Web上によいC言語規格の一次情報源があると助かるのですが、残念ながら自分は知らないです...) C11の規格はISOで売っています。ネットから購入してPDFを入手できます。これが正式の一次情報です。 https://www.iso.org/standard/57853.html C11最終ドラフト(n1570)であれば無料で手に入ります。 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf 正式版と最終ドラフトの違いは下記のstackoverflowを参考にしてください。 https://stackoverflow.com/questions/8631228/latest-changes-in-c11 JIS規格としてはC99までのないようになりますがJIS X 3010:2003があります。日本語ですが、C11未対応であることに注意してください。PDF版が購入できます。 https://webdesk.jsa.or.jp/books/W11M0090/index/?bunsyo_id=JIS%20X%203010:2003 あくまでCの規格としてと一次情報です。コンパイラなどの環境が全てに対応しているかどうかは別の話ですので、ご注意ください。
KSwordOfHaste

2017/06/23 10:47

to:raccyさん お手数をおかけして恐縮です。ドラフト以外は有償なのですね。それだけにC11ドラフトと差分の情報は大変ありがたいです。情報ありがとうございます。
yumetodo

2017/06/24 11:56

あれ、n1124ってC99ともまた違うんですかね・・・
guest

0

if文でまとめて判定するのは不可能です。
ひとつずつ比較するしかないですね。
mattnさんと同じようなコードになってしまいますが、既存の変数に対して処理するのであればポインタの配列に入れてからループで回せば良いと思います。
当然ながら全ての変数の型が一致している必要があります。

c

1 int a,b,c,d; 2 a = 1; 3 b = 1; 4 c = 1; 5 d = 1; 6 int *p[4]; 7 p[0] = &a; 8 p[1] = &b; 9 p[2] = &c; 10 p[3] = &d; 11 int i; 12 for(i = 1; i < sizeof(p)/sizeof(int*); i++){ 13 if(*p[0] != *p[i]) break; 14 } 15 if(i == sizeof(p)/sizeof(int*)){ 16 printf("success\n"); 17 } else { 18 printf("error\n"); 19 } 20

投稿2017/06/23 00:31

ttyp03

総合スコア17000

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

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

0

他の方の回答の通り、C言語の場合はちまちまと1つずつIF文で判断するしか無いと思います。
配列に入れれば、ループで回せるので数が増えたときでも対応しやすくなると思います。

===以下余談===
C++ならvectorコンテナに数値を突っ込んで、同じ値の要素を削除して、サイズが1つかどうかで判定する方法なんかが考えられそうです。

std::sortとstd::uniqueでstd::vectorの重複要素を削除する

投稿2017/06/23 08:16

PineMatsu

総合スコア3579

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問