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

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

ただいまの
回答率

88.93%

C言語で「引数が10進数の場合は真を返すマクロis_digitを記述してください。」という問題が分かりません。

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,551

tada_tadaa

score 93

お世話になっております。
「C実践プログラミング」という本を読んでいるのですが、この本には問題の
回答例がないようで、自分で作らないとダメみたいです。なんとか問題を解い
てきたつもりですが、マクロの説明のところの問題で分からなくなっています。
以下に問題文を示します。

実習10-2 引数が10進数の場合は真を返すマクロis_digitを記述してください。

で、僕なりに作ってみたソースが以下です。

#include <stdio.h>
#define is_digit(i)     (0 <= i && i <= 9) ? 1 : 0

int main(){

        int  num;
        int  n;
        char line[20];

        printf("数値を入力してください\n");
        fgets(line, sizeof(line), stdin);
        sscanf(line, "%d", &num);

        n = is_digit(num);
        if( n == 0 ) printf("10進数ではありません\n");
        else if( n == 1 ) printf("10進数です\n");

        return 0;
}


しかしこれでは0から9までの数字しか判定しません。
(-999999 <= i && i <= 9999999) ? 1 : 0
のようにしたら判定できる数字の範囲が広がりますがなにか違う気がします。

これは参考になるかどうか分かりませんが、別の問題の実習10-1を他の本を
参考にしたりして作った僕の回答例を下に載せます。

実習10-1 パラメーターが10で割り切れる場合は真を、そうでない場合は偽を
返すマクロを記述してください。

#include <stdio.h>

#define  JUDG(i)        (i%10==0) ? 1 : 0

int main(){
        int  num;
        int  n;
        char line[20];

        printf("数値を入力してください\n");
        fgets(line, sizeof(line), stdin);
        sscanf(line, "%d", &num);

        n = JUDG(num);
        if( n == 0 ) printf("10で割り切れません\n");
        else if( n == 1 ) printf("10で割り切れます\n");

        return 0;
}

みなさんだったら実習10-2の問題をどのように解釈し、どのように回答するで
しょうか。参考までに教えて頂ければと思います。
よろしくお願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+2

こんにちは。

引数がどのような条件をみたしたら、「10進数」判定するのか記載はないですか?

少なくともC言語の数値型の変数には10進数の概念は存在しません。(内部表現は2進数ですし。)
ですので、10進数かどうかは文字列で表記された数値でないと定義できません。
次にC言語の数値定数は0で始まると8進数です。0xで始まると16進数です。スペースやタブで始まってたらどうする? NULLで終わる前にアルファベットや記号があったらどうする?等の問題もあります。
これらをマクロで対応するには荷が重すぎると思います。

せめて「10進数」の条件について指示がないと解けないと思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/09/22 01:48

    回答ありがとうございます。

    >引数がどのような条件をみたしたら、「10進数」判定するのか記載はないですか?

    残念ながら、質問に掲載した問題文が、本に載ってた問題文の全てです。僕もマクロとかいう単純そうなことしかできなさそうなものに、10進数の判定なんていう複雑そうなことができるのだろうかと思っておりました。やはり問題文が説明不足ですよね。

    >少なくともC言語の数値型の変数には10進数の概念は存在しません。(内部表現は2進数ですし。)
    ですので、10進数かどうかは文字列で表記された数値でないと定義できません。

    うーん、なるほど。とても参考になります。やはり文字じゃないと10進数とか16進数とか判定できないんですね。
    勉強になる回答をどうもありがとうございました。

    キャンセル

  • 2016/09/22 02:12

    完璧ではないと思いますが、本の問題はおよそこういうことを想定していたのではないかと仮定してプログラムを作りました。もし同じ問題でつまづいておられる方がいれば参考になればと思います。

    #include <stdio.h>
    #include <string.h>

    #define is_digit(i) ('0' <= i && i <= '9') ? 1 : 0

    int main(){

    int i;
    int flag = 0 ;
    int n;
    char line[20];

    printf("数値を入力してください\n");
    fgets(line, sizeof(line), stdin);

    for(i=0; i<strlen(line)-1; i++){
    n = is_digit(line[i]);
    //マクロに渡した文字が'0'から'9'の範囲内でなかったらflagを1にセットする
    if( n == 0 ) flag = 1;
    }

    /*8進数や16進数の場合は0から始まるので、それをチェックして0から始まる場合はflagに1をセットする*/
    if(line[0]=='0') flag == 1;
    if(flag == 1) printf("10進数ではありません\n");
    else if(flag == 0) printf("10進数です\n");

    return 0;
    }

    キャンセル

+2

実習10-1 についてコメントがあります。

↓のプログラムとその出力は理解できますか?
j.c

#include <stdio.h>

#define  JUDG(i)        (i%10==0) ? 1 : 0
#define  JUDGX(i)       ((i)%10 == 0)

int main() {

  printf("%d, %d\n", JUDG(0),  JUDGX(0));
  printf("%d, %d\n", JUDG(1),  JUDGX(1));
  printf("%d, %d\n", JUDG(10), JUDGX(10));


  int x = 9;
  printf("%d, %d\n", JUDG(x+1),   JUDGX(x+1));
  printf("%d, %d\n", JUDG((x+1)), JUDGX((x+1)));

  return 0;
}
$ gcc j.c
$ a.out
1, 1
0, 0
1, 1
0, 1
1, 1

最後から2つ目の行の数字2つが一致しないのは何故? マクロの定義としてはどちらが適切な動作?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/09/22 10:57

    回答ありがとうございます。

    >最後から2つ目の行の数字2つが一致しないのは何故? マクロの定義としてはどちらが適切な動作?

    意外な落とし穴を教えていただきありがとうございます。以下のようなコマンドを実行しました。

    gcc -E j.c

    すると最後の部分に次のような出力がありました。

    int main() {

    printf("%d, %d\n", (0%10==0) ? 1 : 0, ((0)%10 == 0));
    printf("%d, %d\n", (1%10==0) ? 1 : 0, ((1)%10 == 0));
    printf("%d, %d\n", (10%10==0) ? 1 : 0, ((10)%10 == 0));


    int x = 9;
    printf("%d, %d\n", (x+1%10==0) ? 1 : 0, ((x+1)%10 == 0));
    printf("%d, %d\n", ((x+1)%10==0) ? 1 : 0, (((x+1))%10 == 0));

    return 0;
    }

    最後から二つ目の文が
    (x+1%10==0)
    というふうに展開されていて、これでは正しい結果は出力されないはずだと分かりました。ですので、マクロとしては「JUDGX」の方が適切な記述がなされていると言えると思います。勉強になる指摘をありがとうございます。

    キャンセル

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

  • ただいまの回答率 88.93%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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

  • トップ
  • Cに関する質問
  • C言語で「引数が10進数の場合は真を返すマクロis_digitを記述してください。」という問題が分かりません。