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

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

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

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

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

Q&A

解決済

2回答

3625閲覧

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

tada_tadaa

総合スコア111

C

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

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

0グッド

0クリップ

投稿2016/09/21 15:32

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

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

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

c

1#include <stdio.h> 2#define is_digit(i) (0 <= i && i <= 9) ? 1 : 0 3 4int main(){ 5 6 int num; 7 int n; 8 char line[20]; 9 10 printf("数値を入力してください\n"); 11 fgets(line, sizeof(line), stdin); 12 sscanf(line, "%d", &num); 13 14 n = is_digit(num); 15 if( n == 0 ) printf("10進数ではありません\n"); 16 else if( n == 1 ) printf("10進数です\n"); 17 18 return 0; 19}

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

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

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

c

1#include <stdio.h> 2 3#define JUDG(i) (i%10==0) ? 1 : 0 4 5int main(){ 6 int num; 7 int n; 8 char line[20]; 9 10 printf("数値を入力してください\n"); 11 fgets(line, sizeof(line), stdin); 12 sscanf(line, "%d", &num); 13 14 n = JUDG(num); 15 if( n == 0 ) printf("10で割り切れません\n"); 16 else if( n == 1 ) printf("10で割り切れます\n"); 17 18 return 0; 19}

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

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

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

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

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

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

guest

回答2

0

実習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/21 17:34

katoy

総合スコア22324

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

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

tada_tadaa

2016/09/22 01: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」の方が適切な記述がなされていると言えると思います。勉強になる指摘をありがとうございます。
guest

0

ベストアンサー

こんにちは。

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

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

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

投稿2016/09/21 16:29

Chironian

総合スコア23272

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

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

tada_tadaa

2016/09/21 16:48

回答ありがとうございます。 >引数がどのような条件をみたしたら、「10進数」判定するのか記載はないですか? 残念ながら、質問に掲載した問題文が、本に載ってた問題文の全てです。僕もマクロとかいう単純そうなことしかできなさそうなものに、10進数の判定なんていう複雑そうなことができるのだろうかと思っておりました。やはり問題文が説明不足ですよね。 >少なくともC言語の数値型の変数には10進数の概念は存在しません。(内部表現は2進数ですし。) ですので、10進数かどうかは文字列で表記された数値でないと定義できません。 うーん、なるほど。とても参考になります。やはり文字じゃないと10進数とか16進数とか判定できないんですね。 勉強になる回答をどうもありがとうございました。
tada_tadaa

2016/09/21 17: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; }
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問