以前、おつりの「金種」を求めるプログラムを作りました。
今回は大きくグレードアップしたプログラムを作りましょう。
スーパーのレジなどで、支払った金額が入力されると自動的にお釣りが出てくるのを見たことがありませんか?
ファストフード店で見たことがある人もいるでしょう。
あれはどのような仕組みになっているのでしょうか?
自動的にお釣りが出てこないレジでも「お釣りの計算」はしてくれますので、そこから始めましょう。
まずは簡単に、次の実行結果が表示されるプログラムを考えてください。
<実行結果>
価格を入力してください:2568 支払金額を入力してください:5000 お釣りは2432円です。 続行するには何かキーを押してください・・・
先に、変数名を決めておきましょう。
価格 price 支払金額 payment お釣り change
これで、作成してみてください。
解答例です。
<sample program 072-01>
#include <stdio.h> int main(void) { int price; /* 価格 */ int payment; /* 支払金額 */ int change; /* お釣り */ printf("価格を入力してください:"); scanf("%d", &price); printf("支払金額を入力してください:"); scanf("%d", &payment); change = payment - price; printf("お釣りは%d円です。\n", change); return 0; } |
<実行結果>
価格を入力してください:1231 支払金額を入力してください:2000 お釣りは769円です。 続行するには何かキーを押してください・・・
ここまでは大丈夫ですよね。
では、↓の実行結果に合うように変更をかけてみてください。
<実行結果>
価格を入力してください:1231 支払金額を入力してください:2000 お釣りは769円です。 続行するには何かキーを押してください・・・
<実行結果>
価格を入力してください:1231 支払金額を入力してください:1000 支払金額が不足しています。 続行するには何かキーを押してください・・・
解答例です。
<sample program 072-02>
#include <stdio.h> int main(void) { int price; /* 価格 */ int payment; /* 支払金額 */ int change; /* お釣り */ printf("価格を入力してください:"); scanf("%d", &price); printf("支払金額を入力してください:"); scanf("%d", &payment); if (price <= payment) { change = payment - price; printf("お釣りは%d円です。\n", change); } else { printf("支払金額が不足しています。\n"); } return 0; } |
<実行結果>
価格を入力してください:1231 支払金額を入力してください:2000 お釣りは769円です。 続行するには何かキーを押してください・・・
<実行結果>
価格を入力してください:1231 支払金額を入力してください:1000 支払金額が不足しています。 続行するには何かキーを押してください・・・
さて、ここからが問題です。
お釣りの計算が完了したら、金種を求めなければなりません。
お釣りの可能性のある金種は、以下の通りです。
5,000円 1,000円 500円 100円 50円 10円 5円 1円
今回は配列を作り、それぞれの枚数を保存しておくことを考えてみます。
先ほどのプログラムに配列を追加します。
金種は8種類ですから、defineで8という数値も定義しておきましょう。
<sample program 072-03-1>
#include <stdio.h> #define KIND 8 int main(void) { /* 数量(枚数) */ int amount[KIND]; int price; /* 価格 */ int payment; /* 支払金額 */ int change; /* お釣り */ printf("価格を入力してください:"); scanf("%d", &price); printf("支払金額を入力してください:"); scanf("%d", &payment); if (price <= payment) { change = payment - price; printf("お釣りは%d円です。\n", change); } else { printf("支払金額が不足しています。\n"); } return 0; } |
この配列amountは以下のように考えます。
amount[0] 5,000円の枚数 amount[1] 1,000円の枚数 amount[2] 500円の枚数 amount[3] 100円の枚数 amount[4] 50円の枚数 amount[5] 10円の枚数 amount[6] 5円の枚数 amount[7] 1円の枚数
それぞれの金種の枚数を計算する方法は以前のプログラムで同じようなことをやりました。
お釣り ÷ 5000 = 5,000円の枚数
お釣りが、7,000円であれば、
7000 ÷ 5000 = 1.4
整数で計算すれば、小数点以下切り捨てですから、「1」枚です。
お釣りが、4,000円であれば
4000 ÷ 5000 = 0.8
つまり「0」枚です。
↑の計算を商と余りという考え方に当てはめてみるとさらに分かることがあります。
7000 ÷ 5000 = 1 ... 2000 4000 ÷ 5000 = 0 ... 4000
割った商が「枚数」、余りが「残りの金額」になっています。
この「残りの金額」を次の計算に使う訳です。
次の計算とは1,000円の枚数を求める計算です。
1,000円の枚数計算も同じように「商」と「余り」を求めます。
商は1,000円の枚数となり、余りは次の計算に使います。
これを1円単位まで行うと完成します。
では、↑に書いたことをそのままプログラムにしてみます。
<sample program 072-03-2>
#include <stdio.h> #define KIND 8 int main(void) { /* 数量(枚数) */ int amount[KIND]; int i; int price; /* 価格 */ int payment; /* 支払金額 */ int change; /* お釣り */ printf("価格を入力してください:"); scanf("%d", &price); printf("支払金額を入力してください:"); scanf("%d", &payment); if (price <= payment) { change = payment - price; printf("お釣りは%d円です。\n", change); /* 5,000円 */ amount[0] = change / 5000; change = change % 5000; /* 1,000円 */ amount[1] = change / 1000; change = change % 1000; /* 500円 */ amount[2] = change / 500; change = change % 500; /* 100円 */ amount[3] = change / 100; change = change % 100; /* 50円 */ amount[4] = change / 50; change = change % 50; /* 10円 */ amount[5] = change / 10; change = change % 10; /* 5円 */ amount[6] = change / 5; change = change % 5; /* 1円 */ amount[7] = change / 1; change = change % 1; for (i = 0; i < KIND; i++) { printf("%d枚\n", amount[i]); } } else { printf("支払金額が不足しています。\n"); } return 0; } |
<実行結果>
価格を入力してください:1234 支払金額を入力してください:2000 お釣りは766円です。 0枚 0枚 1枚 2枚 1枚 1枚 1枚 1枚 続行するには何かキーを押してください・・・
完成していますね。
完成していますが、不恰好なプログラムになってしまいました。
似たようなプログラムが並んでいるのであれば、繰り返しを使ったプログラムの方がすっきりします。
しかし、まったく同じプログラムでは無いため、どのように考えれば繰り返し処理が出来るでしょうか。
似たような箇所を抜き出してみます。
amount[0] = change / 5000; change = change % 5000; |
ほぼ、同じプログラムが1円の箇所まで続くのですが、異なる箇所は↓の通りです。
amount[0] = change / 5000; change = change % 5000; |
添え字の部分は「0」から「7」まで変化しています。
これに関してはfor文を使えば何とかなりそうです。
for (i = 0; i < KIND; i++) { amount[i] = change / 金種; change = change % 金種; } |
金種の部分は、5000→1000→500→100→50→10→5→1と変化するため、法則的なものが見えてきません。
ここさえクリアできれば、繰り返し処理に切り替えることが出来そうです・・・
これを解決するため「テーブル」というものを使います。
「テーブル」とは、あらかじめ数値の入った配列と考えてもらえれば良いです。
今回は「金種テーブル」というものを作ってみます。
/* 金種テーブル */ int denomination[KIND] = { 5000, 1000, 500, 100, 50, 10, 5, 1 }; |
金種の金額は一定の法則に従って計算すると考えると難しそうな数値です。
そこで、配列にあらかじめ数値を入れておきます。
すると、
5000 は denomination[0] 1000 は denomination[1] 500 は denomination[2] 100 は denomination[3] 50 は denomination[4] 10 は denomination[5] 5 は denomination[6] 1 は denomination[7]
で指定することが出来ますから、「0」から「7」の数値でそれぞれの金種が使えるようになります。
「0」から「7」の数値はfor文のカウンタとしてすでに存在していますので、
for (i = 0; i < KIND; i++) { amount[i] = change / denomination[i]; change = change % denomination[i]; } |
とすれば、繰り返し処理に切り替えることが出来ますね。
それでは作ってみましょう。
<sample program 072-04>
#include <stdio.h> #define KIND 8 int main(void) { /* 金種テーブル */ int denomination[KIND] = { 5000, 1000, 500, 100, 50, 10, 5, 1 }; /* 数量(枚数) */ int amount[KIND]; int i; int price; /* 価格 */ int payment; /* 支払金額 */ int change; /* お釣り */ printf("価格を入力してください:"); scanf("%d", &price); printf("支払金額を入力してください:"); scanf("%d", &payment); if (price <= payment) { change = payment - price; printf("お釣りは%d円です。\n", change); for (i = 0; i < KIND; i++) { amount[i] = change / denomination[i]; change = change % denomination[i]; } for (i = 0; i < KIND; i++) { printf("%d枚\n", amount[i]); } } else { printf("支払金額が不足しています。\n"); } return 0; } |
<実行結果>
価格を入力してください:1234 支払金額を入力してください:2000 お釣りは766円です。 0枚 0枚 1枚 2枚 1枚 1枚 1枚 1枚 続行するには何かキーを押してください・・・
どの金種の枚数か分かりずらいので、金種テーブルを使って表示を書き換えます。
<sample program 072-05>
#include <stdio.h> #define KIND 8 int main(void) { /* 金種テーブル */ int denomination[KIND] = { 5000, 1000, 500, 100, 50, 10, 5, 1 }; /* 数量(枚数) */ int amount[KIND]; int i; int price; /* 価格 */ int payment; /* 支払金額 */ int change; /* お釣り */ printf("価格を入力してください:"); scanf("%d", &price); printf("支払金額を入力してください:"); scanf("%d", &payment); if (price <= payment) { change = payment - price; printf("お釣りは%d円です。\n", change); for (i = 0; i < KIND; i++) { amount[i] = change / denomination[i]; change = change % denomination[i]; } for (i = 0; i < KIND; i++) { printf("%4d円 %d枚\n", denomination[i], amount[i]); } } else { printf("支払金額が不足しています。\n"); } return 0; } |
<実行結果>
価格を入力してください:1234 支払金額を入力してください:2000 お釣りは766円です。 5000円 0枚 1000円 0枚 500円 1枚 100円 2枚 50円 1枚 10円 1枚 5円 1枚 1円 1枚 続行するには何かキーを押してください・・・
このように「テーブル」を使えば、不規則な並びの数を一定の法則に従って扱うことが出来ます。
色々と応用出来ますので、必ず覚えておいてください。