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

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

ただいまの
回答率

91.23%

  • C

    2700questions

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

c言語 入門レベル問題

解決済

回答 3

投稿

  • 評価
  • クリップ 1
  • VIEW 267

GokaTokyo

score 31

下記エラーなぜでしょうか。

#include <stdio.h>
int main()
{
    //定义三位数num,个位数sd,十位数td,百位数hd
    int num, sd, td, hd;
    //循环所有三位数

    // for(   num=100  ;  num<1000  ;    num++ )

    for(sd=0,td=0,hd=0;sd<=9,td<=9,hd<=9; sd++,td++,hd++)
    {
        //获取三位数字num百位上的数字     // num = 123
        hd =    num/100         ;  // 1
        //获取三位数字num十位上的数字
        //    td =    num%100/10        ;
        //获取三位数字num个位上的数字
        //  sd =     num%10         ;

        //     hd = num/100;

        td = num/10-hd*10         ;  //  2

        sd = num-hd*100-td*10      ;  // 3


        //水仙花数的条件是什么?

        if( num == sd*sd*sd + td*td*td + hd*hd*hd)
        {
            printf("水仙花数字:%d\n", num);
        }
    }
    return 0;    
}


エラー
イメージ説明

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • A.Ichi

    2018/01/07 10:07

    お使いのツールでのエラーではないでしょうか、||を使われては(Linux gccではOK)

    キャンセル

回答 3

+3

for(sd=0,td=0,hd=0;sd<=9,td<=9,hd<=9; sd++,td++,hd++)

sd<=9,td<=9,hd<=9 は何を意図していますか?

sd<=9 && td<=9 && hd<=9 または
sd<=9 || td<=9 || hd<=9 のどちらか と思われますが。

さらに、このfor-loopは何を意図していますか?
sd,td,hd = 0,0,0 ~ 9,9,9 までの1000通りをすべて列挙したいのであれば、
3重のfor-loopになります。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

+1

こんにちは。

画面キャプチャの黄色くハイライトされている行の右端に、
以下のような2つのメッセージが読みとれます。

  • Expression result unused
  • Relational comparison result unused

前者のメッセージは sd <= 9 に対してのもの、
後者のメッセージは td <= 9 に対してのものです。

まず、これらのメッセージは、コンパイルエラーではなくて、警告(Warning)です。

どのような警告かを確認して、警告のないプログラムに
修正する手順(の一例)を以下に示します。

まず、両方のメッセージに共通しているのは result unused という部分です。
「結果が使われない」
という意味ですね。

この場合、何の結果かといえば、
sd <= 9と td <= 9 という比較演算の結果が使われない」
という意味の警告になります。

使われないものが書いてあるというだけで、文法的にはエラーではなく、警告(Warning)です。

「使われない」という意味と、エラーではなく警告であるという意味は
以下の手順で確かめられます。

まず、以下のように、test1.c を作ってコンパイルしてみます。

イメージ説明

上記の画像に出てくる、 test1.c は以下のようなものです。

#include <stdio.h>

int main() {

    int i, j;

    for(i=0, j=0; i > 0, j < 5; ++ j) {
        printf("i=%d, j=%d\n", i, j);
    }
}

上記のコードをよく見て欲しいのですが、 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さんの今の段階では)問題ありません。

上記を踏まえると、質問にあるコードの以下の部分、

for (sd = 0, td = 0, hd = 0; sd <= 9, td <= 9, hd <= 9; sd++, td++, hd++) {

は、以下のように、sd <= 9, td <= 9,  を削除しても、動作的には
(あるいは、実行ファイルを作るCコンパイラにとっては、)同じです。

for (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までの間にある
水仙花数を求めるプログラム)の途中段階で、質問のような、すぐには何がおかしいか分からない
警告あるいはエラーが出たときに、そのメッセージの内容から、

  • 「たぶん、こういうことを言っているエラー(または警告)メッセージだろう」と推測すること

と、

  • その推測が正しいかだけを見るために、本題から問題箇所だけを取り出して確認する、最小限のプログラムを書いて、その結果から推測の正しからしさを判断すること

はとても大事です。大事という意味は、上記の
「警告やエラーの意味を自分なりに確かめる小さなコードを書いてみる」
習慣があるのとないのとでは後々、プログラマーとしての腕に
大きな差がつくのではないかと思われるということです。(私見ですが)

ですので、次からは、上記のように、
本題のプログラムで起きている問題を特定するだけのための小さなコード
を作ってみることに挑戦するとよいかもしれません。
 
以上、参考になれば幸いです。


追記

理解を深めるために、以下のプログラム

#include <stdio.h>

int main() {
    int x = 10, y = -5, z = -1;

    int result = (x > 0, y > 0, z > 0);

    printf("%d\n", result);
}

で、result が 1(真) になるか 0(偽) になるかは、
z の値が正であるかどうかだけに依存して、
x と y の値がどうであるかには影響を受けないことを
確認して、, が、 && あるいは || である場合と
どう違うかを確認してみるのもよいでしょう。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

こんにちは。

下記エラーなぜでしょうか。

for文の2番目にはforを継続するための条件式を記述します。結果がfalseならforを終了し、trueなら再度ループを回りますね。

そこに、sd<=9,td<=9,hd<=9と書かれています。これは、 ,(カンマ)演算子にて3つの関係条件式を並べています。カンマ演算子はカンマで区切られた各式の最後の値を返却します。従って、このケースではhd<=9と同じ結果になります。
そして、前2つの関係式の結果が無視されるため、「それらをどこでも使ってないけど良いのか?」という警告がでています。その場所を示すため、sd<=9td<=9の下に^マークがついています。

正しい姿は恐らくepistemeさんが書かれている通りです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

ただいまの回答率

91.23%

関連した質問

同じタグがついた質問を見る

  • C

    2700questions

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