こんにちは。
画面キャプチャの黄色くハイライトされている行の右端に、
以下のような2つのメッセージが読みとれます。
- Expression result unused
- Relational comparison result unused
前者のメッセージは sd <= 9
に対してのもの、
後者のメッセージは td <= 9
に対してのものです。
まず、これらのメッセージは、コンパイルエラーではなくて、警告(Warning)です。
どのような警告かを確認して、警告のないプログラムに
修正する手順(の一例)を以下に示します。
まず、両方のメッセージに共通しているのは result unused
という部分です。
「結果が使われない」
という意味ですね。
この場合、何の結果かといえば、
「sd <= 9
と td <= 9
という比較演算の結果が使われない」
という意味の警告になります。
使われないものが書いてあるというだけで、文法的にはエラーではなく、警告(Warning)です。
「使われない」という意味と、エラーではなく警告であるという意味は
以下の手順で確かめられます。
まず、以下のように、test1.c
を作ってコンパイルしてみます。

上記の画像に出てくる、 test1.c
は以下のようなものです。
c
1#include <stdio.h>
2
3int main() {
4
5 int i, j;
6
7 for(i=0, j=0; i > 0, j < 5; ++ j) {
8 printf("i=%d, j=%d\n", i, j);
9 }
10}
上記のコードをよく見て欲しいのですが、 for文で、 i
は、 i=0
と初期化され、
その後も増えないので、 i > 0
はforループの実行中、常に成り立ちません。
それでも、コンパイルされて、実行ファイル a.out
が生成され、
a.out
を実行すると、エラーにならず
i
と j
の値が出力されています。
また、画像の中i > 0
のところに以下の警告が出力されています。
test1.c:7:21: warning: relational comparison result unused [-Wunused-comparison]
コンパイルエラーではなく、警告(warning)であるとは、今の段階では
「文法的には問題ないが、もしかしたら、バグの原因になるかもしれない怪しいコード」
ぐらいに思っていてください。
実際に、コンパイルエラーではないので、a.out
が生成されています。
また、常に偽になる比較演算 i > 0
の結果(整数の0)は無視されて、
for ループが続く条件としては、j < 5
だけが使われているのが
分かります。ですので、test1.c
の i > 0,
を削除して、
#include <stdio.h>
int main() {
int i, j;
for(i=0, j=0; j < 5; ++ j) {
printf("i=%d, j=%d\n", i, j);
}
}
としても、結果が無視されるコードを削除しただけなので、動作としては同じものになりますが、
以下のようにコンパイル時に警告は出なくなりました。(ファイル名は、test1r.c
としました)

次に変数をもう1つ増やしてやってみます。
以下のような、test2.c
を作成して、コンパイル、実行します。

上記でも、警告なのでコンパイルはできて、a.out
が生成され、
for の条件のはじめの2つ、i > 0
と j > 0
は常に偽(値としては整数の0)に
なりますが、無視されて、k < 15
だけがforループを続けるかどうかの判定に使われて、
実行されました。
ですので、上記の test2.c は i > 0
と j > 0
を削除しても
動作としては同じで、以下のように警告は出なくなります。(ファイル名は、test2r.c
としました)

ここで、test2.c
の i > 0
に対する警告は
test2.c:7:27: warning: relational comparison result unused [-Wunused-comparison]
で、j > 0
に対する警告は
test2.c:7:34: warning: expression result unused [-Wunused-value]
と、少し違っています。
なぜ違うのかということについては、私は「このCコンパイラがそういう仕様になっているから」という
回答しかできないのですが、コンパイラを使ってCのプログラムを作る側としては、
result unused
に注目して、これらの警告の言っていることは、ほぼ同じ と思って
おいて、(GokaTokyoさんの今の段階では)問題ありません。
上記を踏まえると、質問にあるコードの以下の部分、
c
1for (sd = 0, td = 0, hd = 0; sd <= 9, td <= 9, hd <= 9; sd++, td++, hd++) {
は、以下のように、sd <= 9, td <= 9,
を削除しても、動作的には
(あるいは、実行ファイルを作るCコンパイラにとっては、)同じです。
c
1for (sd = 0, td = 0, hd = 0; hd <= 9; sd++, td++, hd++) {
上記のようにすると警告は消えると思います。
以上が、この問題の本題である、黄色くハイライトされている行の警告についての
説明になります。
ただし、 sd <= 9, td <= 9,
を削除して警告が消えても、
意図通りに動くプログラムになるかというと、それはまた別の問題ですので、
意図通りに動かない原因が分からないときは、また新たに質問をされるとよいでしょう。
最後にこの回答で重要なことをつけ加えておきます。
回答者の私自身、
for (sd = 0, td = 0, hd = 0; sd <= 9, td <= 9, hd <= 9; sd++, td++, hd++) {
と書くと、
- Expression result unused
- Relational comparison result unused
という警告が出ることを知りませんでした。
つまり、この回答を書くことで初めて知りました。
回答を書くために、警告のresult unused
という文言から、
「たぶん、こういうことを言っている警告だろう」ということを推測して、
その推測を確かめるコード test1.c
、test2.c
とそれらを修正した
test1r.c
と test2r.c
を書きました。
このように、自分がいま書いている本題のプログラム(ここでは、100から999までの間にある
水仙花数を求めるプログラム)の途中段階で、質問のような、すぐには何がおかしいか分からない
警告あるいはエラーが出たときに、そのメッセージの内容から、
- 「たぶん、こういうことを言っているエラー(または警告)メッセージだろう」と推測すること
と、
- その推測が正しいかだけを見るために、本題から問題箇所だけを取り出して確認する、最小限のプログラムを書いて、その結果から推測の正しからしさを判断すること
はとても大事です。大事という意味は、上記の
「警告やエラーの意味を自分なりに確かめる小さなコードを書いてみる」
習慣があるのとないのとでは後々、プログラマーとしての腕に
大きな差がつくのではないかと思われるということです。(私見ですが)
ですので、次からは、上記のように、
本題のプログラムで起きている問題を特定するだけのための小さなコード
を作ってみることに挑戦するとよいかもしれません。
以上、参考になれば幸いです。
追記
理解を深めるために、以下のプログラム
c
1#include <stdio.h>
2
3int main() {
4 int x = 10, y = -5, z = -1;
5
6 int result = (x > 0, y > 0, z > 0);
7
8 printf("%d\n", result);
9}
で、result
が 1(真)
になるか 0(偽)
になるかは、
z
の値が正であるかどうかだけに依存して、
x
と y
の値がどうであるかには影響を受けないことを
確認して、,
が、 &&
あるいは ||
である場合と
どう違うかを確認してみるのもよいでしょう。