書籍
- C言語プログラミング ハーベイ M.ダイテル (著), ポール J.ダイテル (著), 小嶋 隆一 (翻訳)
- development environment
- Visual Stdio Code
- gcc 8.1.0
5.9: 駐車時間・料金の総和を表示するプログラム
source
#include <stdio.h>
#include <conio.h>
#define MAX_NUM 3
typedef struct park_info{
double time;
double count;
}PARK_INFO;
void input_parktime(PARK_INFO [],int);
void calculateCharge(PARK_INFO [],int);
void print_parkinfo(const PARK_INFO [],int);
int main()
{
PARK_INFO park_info[MAX_NUM];
input_parktime(park_info,MAX_NUM);
calculateCharge(park_info,MAX_NUM);
print_parkinfo(park_info,MAX_NUM);
getch();
return 0;
}
void input_parktime(PARK_INFO park_info[],int num)
{
int i;
for(i=0;i<num;i++)
{
do
{
printf("駐車時間を入力してください 0-24 (%d人目)\n",i+1);
scanf("%lf",&park_info[i].time);
}
while(park_info[i].time<0 || 24<park_info[i].time);
}
}
void calculateCharge(PARK_INFO park_info[],int num)
{
int i;
int hour;
for(i=0;i<num;i++)
{
if(park_info[i].time==24)
{
park_info[i].count=10;
}
else if(park_info[i].time<=3)
{
park_info[i].count=2;
}
else
{
hour=(park_info[i].time-3)*60/60;
park_info[i].count=2+hour*0.5;
}
}
}
void print_parkinfo(const PARK_INFO park_info[],int num)
{
int i;
double sum_time;
double sum_count;
sum_time=0.0;
sum_count=0.0;
printf("%-10s%10s%10s\n","クルマ","駐車時間","駐車料金");
for(i=0;i<num;i++)
{
printf("%-10d%10.1lf%10.2lf\n",i+1,park_info[i].time,park_info[i].count);
sum_time+=park_info[i].time;
sum_count+=park_info[i].count;
}
printf("%-10s%10.1lf%10.2lf\n","合計",sum_time,sum_count);
}
5.10: 入力された小数を四捨五入して(小数点以下第一位)表示するプログラム
source
#include <stdio.h>
#include <math.h>
#include <conio.h>
int main()
{
double x;
printf("数値を入力してください(小数第一位を四捨五入します)\n");
scanf("%lf",&x);
printf("%.1lf",floor(x+0.5));
getch();
return 0;
}
5.11: 戻り値がdouble型の引数double型をとる関数へのポインタを活用したプログラム
source
#include <stdio.h>
#include <conio.h>
#include <math.h>
#define FUNCTION_NUM 4
typedef double (*fp)(double);
double roundToInteger(double);
double roundToTenths(double);
double roundToHundreths(double);
double roundToThousandths(double);
int main()
{
int i;
double num;
fp kansu[FUNCTION_NUM]={
roundToInteger,
roundToTenths,
roundToHundreths,
roundToThousandths
};
printf("数値を入力してください\n");
scanf("%lf",&num);
for(i=0;i<FUNCTION_NUM;i++)
{
printf("%.3lf\n",kansu[i](num));
}
getch();
return 0;
}
double roundToInteger(double num)
{
return (floor(num+0.5));
}
double roundToTenths(double num)
{
return (floor(num*10+0.5)/10);
}
double roundToHundreths(double num)
{
return (floor(num*100+0.5)/100);
}
double roundToThousandths(double num)
{
return (floor(num*1000+0.5)/1000);
}
5.15: 3平方の定理で斜辺の長さを求める関数を実装したプログラム
source
#include <stdio.h>
#include <conio.h>
#include <math.h>
double hypotenuse(double,double);
int main()
{
double slide1,slide2;
printf("2辺の長さを入力してください\n");
scanf("%lf",&slide1);
scanf("%lf",&slide2);
printf("斜辺の長さは%lfです",hypotenuse(slide1,slide2));
getch();
return 0;
}
double hypotenuse(double slide1,double slide2)
{
return sqrt(pow(slide1,2)+pow(slide2,2));
}
5.16: 整数の整数乗を求め表示するプログラム
source
#include <stdio.h>
#include <conio.h>
int integerPower(int,int);
int main()
{
int num1,num2;
int result;
printf("2つの整数を入力してください\n");
scanf("%d %d",&num1,&num2);
result=integerPower(num1,num2);
if(result==-1)
{
printf("入力が正しくありません\n");
}
else
{
printf("%dの%d乗は%d",num1,num2,result);
}
getch();
return 0;
}
int integerPower(int base,int exponent)
{
int sum;
sum=1;
if(base<=0)
{
return -1;
}
if(exponent<0)
{
return -1;
}
while(exponent-->0)
{
sum*=base;
}
return sum;
}
5.17: 倍数判定し結果を表示するプログラム
source
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
int multiple(int,int);
int main()
{
int i,j;
srand(time(NULL));
for(i=-10;i<=10;i++)
{
for(j=-10;j<=10;j++)
{
if(multiple(i,j)==1)
{
printf("%dは%dの倍数です\n",j,i);
}
else
{
printf("%dは%dの倍数ではありません\n",j,i);
}
if(j%10==0)
{
getch();
}
}
}
return 0;
}
// モジュロ演算子で倍数判定する関数
int multiple(int num1,int num2)
{
if(num1==0 && num2!=0)
{
return 0;
}
else if(num1==0 && num2==0)
{
return 1;
}
if(num2==0)
{
return 1;
}
else if(num2<0)
{
if(num1<0)
{
if(num2%num1==0)
{
return 1;
}
return 0;
}
return 0;
}
else
{
if(num1>0)
{
if(num2%num1==0)
{
return 1;
}
return 0;
}
return 0;
}
}
5.18: 偶奇を判定するプログラム
source
#include <stdio.h>
#include <conio.h>
int even(int);
int main()
{
int end;
int num;
while(1)
{
printf("数値を入力してください\n");
scanf("%d",&num);
if(even(num)==1)
{
printf("%dは偶数です\n\n",num);
}
else
{
printf("%dは奇数です\n\n",num);
}
printf("終了(1),続行(それ以外)\n");
scanf("%d",&end);
if(end==1)
{
break;
}
}
getch();
return 0;
}
int even(int num)
{
if(num%2==0)
{
return 1;
}
else
{
return 0;
}
}
5.19: 稠密な正方形を表示するプログラム
source
#include <stdio.h>
#include <conio.h>
void print_square(int);
int main()
{
int slide;
do
{
printf("正整数を入力してください\n");
scanf("%d",&slide);
print_square(slide);
}
while(slide<0);
getch();
return 0;
}
void print_square(int slide)
{
int i,j;
for(i=0;i<slide;i++)
{
for(j=0;j<slide;j++)
{
printf("*");
}
printf("\n");
}
}
5.20: 整数型引数fillCharacterで指定された文字を使って正方形を表示するように、5.19の関数を変更したプログラム
source
#include <stdio.h>
#include <conio.h>
void print_square(int slide, int fillCharacter);
int main(void)
{
int slide;
int fillCharacter;
do
{
printf("正整数を入力してください\n");
scanf("%d", &slide);
printf("表示する文字のASCIIコードを入力してください\n");
scanf("%d", &fillCharacter);
if (slide > 0)
{
print_square(slide, fillCharacter);
}
} while (slide < 0);
getch();
return 0;
}
void print_square(int slide, int fillCharacter)
{
int i, j;
for (i = 0; i < slide; i++)
{
for (j = 0; j < slide; j++)
{
printf("%c", fillCharacter);
}
printf("\n");
}
}
5.21: 5.19と5.20で開発したテクニックを使って、いろいろな図形を描画するプログラム
source
#include <stdio.h>
#include <conio.h>
void print_square(int, char);
void print_rectangle(int, int, char);
void print_triangle(int, char);
void print_pyramid(int, char);
int main(void)
{
int size;
int width;
int menu;
char fillCharacter;
printf("表示する文字を入力してください: ");
scanf(" %c", &fillCharacter);
do
{
printf("\n===== メニュー =====\n");
printf("1. 正方形\n");
printf("2. 長方形\n");
printf("3. 直角三角形\n");
printf("4. ピラミッド\n");
printf("0. 終了\n");
printf("選択: ");
scanf("%d", &menu);
switch(menu)
{
case 1:
printf("一辺の長さ: ");
scanf("%d", &size);
print_square(size, fillCharacter);
break;
case 2:
printf("縦: ");
scanf("%d", &size);
printf("横: ");
scanf("%d", &width);
print_rectangle(size, width, fillCharacter);
break;
case 3:
printf("高さ: ");
scanf("%d", &size);
print_triangle(size, fillCharacter);
break;
case 4:
printf("高さ: ");
scanf("%d", &size);
print_pyramid(size, fillCharacter);
break;
case 0:
printf("終了します。\n");
break;
default:
printf("メニュー番号が正しくありません。\n");
}
} while(menu != 0);
getch();
return 0;
}
void print_square(int side, char ch)
{
int i, j;
for(i = 0; i < side; i++)
{
for(j = 0; j < side; j++)
printf("%c", ch);
printf("\n");
}
}
void print_rectangle(int height, int width, char ch)
{
int i, j;
for(i = 0; i < height; i++)
{
for(j = 0; j < width; j++)
printf("%c", ch);
printf("\n");
}
}
void print_triangle(int height, char ch)
{
int i, j;
for(i = 1; i <= height; i++)
{
for(j = 0; j < i; j++)
printf("%c", ch);
printf("\n");
}
}
void print_pyramid(int height, char ch)
{
int i, j;
for(i = 1; i <= height; i++)
{
for(j = 0; j < height - i; j++)
printf(" ");
for(j = 0; j < 2 * i - 1; j++)
printf("%c", ch);
printf("\n");
}
}
5.22: 整数aを整数bで割ったときの商、余りを計算するプログラムを使って、1から32767までの整数を入力し、その整数の各桁を2文字分ずつ空白をあけてプリントするプログラム
source
#include <stdio.h>
int main(void)
{
int n;
int d[5];
int i, count = 0;
printf("1~32767の整数を入力してください:");
scanf("%d", &n);
if (n < 1 || n > 32767) {
printf("範囲外です。\n");
return 0;
}
/* 商と余りを使って各桁を取り出す */
while (n > 0) {
d[count] = n % 10; // 余り(1桁)
n = n / 10; // 商
count++;
}
/* 逆順に表示 */
for (i = count - 1; i >= 0; i--) {
printf("%d", d[i]);
if (i > 0) {
printf(" "); // 半角スペース2文字
}
}
printf("\n");
return 0;
}
5.23: 時刻を3つの引数(時、分、秒)で受け取り、時計が最後に12時を打ってからその時刻までの経過秒数を返す関数を使って、前後2つの時刻の間の経過秒数を計算するプログラム
source
#include <stdio.h>
#include <conio.h>
int count_second(int,int,int);
int main()
{
int hour;
int minute;
int second_pre,second_post;
printf("(前の時間)時,分,秒を入力してください\n");
scanf("%d %d %d",&hour,&minute,&second_pre);
if((second_pre=count_second(hour,minute,second_pre))==-1)
{
printf("入力エラーです\n");
return -1;
}
printf("(後の時間)時,分,秒を入力してください\n");
scanf("%d %d %d",&hour,&minute,&second_post);
if((second_post=count_second(hour,minute,second_post))==-1)
{
printf("入力エラーです\n");
return -1;
}
if(second_post-second_pre<0)
{
printf("入力エラーです\n");
return -1;
}
else
{
printf("2つの時刻の経過秒数は%dです",second_post-second_pre);
}
getch();
return 0;
}
int count_second(int hour,int minute,int second)
{
if(hour>23 || hour<0)
{
return -1;
}
if(hour>=12)
{
return (hour-12)*3600+minute*60+second;
}
else
{
return (hour+12)*3600+minute*60+second;
}
}
5.24: カ氏温度を受け取って、セ氏温度を返す関数、セ氏温度を受け取って、カ氏温度を返す関数を使って、0から100度までのセ氏温度に対応するカ氏温度、および32から212度までのカ氏温度に対応するセ氏温度をそれぞれ表の形にプリントするプログラム
source
#include <stdio.h>
#include <conio.h>
double celsius(double);
double fahrenheit(double);
int main()
{
int cels;
int fahr;
for(cels=0;cels<=100;cels++)
{
printf("fahr %8.4lf cels %3d\n",fahrenheit(cels),cels);
}
printf("\n");
for(fahr=32;fahr<=212;fahr++)
{
printf("cels %8.4lf fahr %3d\n",celsius(fahr),fahr);
}
getch();
return 0;
}
double celsius(double fahr)
{
return 5.0/9*(fahr-32);
}
double fahrenheit(double cels)
{
return 9.0/5*cels+32;
}
5.25: 与えられた3つの浮動小数点のうち最小値を返す関数を実装したプログラム
source
#include <stdio.h>
#include <conio.h>
double min(double,double,double);
int main()
{
double a,b,c;
printf("3つの数を入力してください\n");
scanf("%lf %lf %lf",&a,&b,&c);
printf("最小値は%.3lfです\n",min(a,b,c));
getch();
return 0;
}
double min(double a,double b,double c)
{
double min;
min=a;
if(min>=b)
{
min=b;
}
if(min>=c)
{
min=c;
}
return min;
}
5.26: 完全数見つけてプリントするプログラム
source
#include <stdio.h>
#include <conio.h>
#include <limits.h>
int perfect(int);
void print_divisor(int);
int main()
{
int i;
for(i=1;i<=INT_MAX-1;i++)
{
if(perfect(i)==1)
{
printf("%dは完全数です\n",i);
print_divisor(i);
}
}
getch();
return 0;
}
int perfect(int number)
{
int i;
int sum;
sum=0;
for(i=1;i<number;i++)
{
if(number%i==0)
{
sum+=i;
}
}
if(sum==number)
{
return 1;
}
else
{
return 0;
}
}
void print_divisor(int num)
{
int i;
for(i=1;i<num;i++)
{
if(num%i==0)
{
printf("%d\n",i);
}
}
}
5.27: 素数を扱うプログラム
source
#include <stdio.h>
int prime_half(int);
int prime_sqrt(int);
int main()
{
int i;
printf("n/2版\n");
for(i = 1; i <= 10000; i++)
{
if(prime_half(i))
{
printf("%d ", i);
}
}
printf("\n\n√n版\n");
for(i = 1; i <= 10000; i++)
{
if(prime_sqrt(i))
{
printf("%d ", i);
}
}
return 0;
}
int prime_half(int number)
{
int i;
if(number < 2)
return 0;
for(i = 2; i <= number/2; i++)
{
if(number % i == 0)
return 0;
}
return 1;
}
int prime_sqrt(int number)
{
int i;
if(number < 2)
return 0;
for(i = 2; i*i <= number; i++)
{
if(number % i == 0)
return 0;
}
return 1;
}
5.28: 整数値を受け取り、各桁を逆転させた整数を返す関数を実装したプログラム
source
#include <stdio.h>
#include <conio.h>
int int_reverse(int);
int main()
{
int num;
printf("整数値を入力してください\n");
scanf("%d",&num);
printf("%dを反転させた値は%dです\n",num,int_reverse(num));
getch();
return 0;
}
int int_reverse(int num)
{
int reverse;
int sign;
reverse=0;
if(num<0)
{
sign=-1;
num*=-1;
}
else
{
sign=1;
}
while(num>0)
{
reverse=reverse*10+num%10;
num/=10;
}
return reverse*sign;
}
5.29: 最大公約数を返す関数gcdを実装したプログラム
source
#include <stdio.h>
#include <conio.h>
#include <math.h>
int gcd(int,int);
int main()
{
int a,b;
int result;
printf("最大公約数を求めます,2つの数値を入力してください\n");
scanf("%d %d",&a,&b);
if((result=gcd(a,b))==-1)
{
fprintf(stderr,"エラー");
return -1;
}
printf("%dと%dの最大公約数は%dです\n",a,b,result);
getch();
return 0;
}
int gcd(int a,int b)
{
int r;
if(b==0)
{
return -1;
}
if(fabs(a)<fabs(b))
{
return -1;
}
if(a<0 && b>0)
{
a*=-1;
}
else if(a>0 && b<0)
{
b*=-1;
}
do
{
r=a%b;
a=b;
b=r;
}
while(r>0);
return a;
}
5.30: 学生の平均点を入力して、5段階評価を返す関数qualityPointsを実装したプログラム
source
#include <stdio.h>
#include <conio.h>
int qualityPoints(int);
int main()
{
int data;
do
{
printf("学生の平均点を入力してください\n");
scanf("%d",&data);
}
while(data<0 || 100<data);
printf("この学生の評価は%dです\n",qualityPoints(data));
getch();
return 0;
}
int qualityPoints(int data)
{
if(90<=data && data<=100)
{
return 4;
}
else if(80<=data && data<=89)
{
return 3;
}
else if(70<=data && data<=79)
{
return 2;
}
else if(60<=data && data<=69)
{
return 1;
}
else
{
return 0;
}
}
5.31: コイン投げをシミュレートするプログラム
source
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
int flip(void);
int main()
{
int i;
int table,back;
srand(time(NULL));
table=back=0;
for(i=0;i<100;i++)
{
if(flip()==1)
{
table++;
}
else
{
back++;
}
}
printf("表 %2d 裏 %2d",table,back);
getch();
return 0;
}
int flip()
{
return rand()%2;
}
5.32: 小学生が掛け算を習うのを補助するプログラム
source
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void question(int *,int *);
int main()
{
int a,b;
int answer;
srand(time(NULL));
while(1)
{
printf("掛け算を行います答えを入力してください\n");
question(&a,&b);
printf("問題 %d×%dは?\n",a,b);
scanf("%d",&answer);
while(1)
{
if(answer==a*b)
{
printf("とてもよくできました\n");
break;
}
else
{
printf("もう一度やってみましょう\n");
scanf("%d",&answer);
}
}
printf("続けますか(1終了,それ以外続行)\n");
scanf("%d",&answer);
if(answer==1)
{
break;
}
}
getch();
return 0;
}
void question(int *a,int *b)
{
*a=rand()%10;
*b=rand()%10;
}
5.33: 5.32のプログラムを正解および不正解に対して特有の応答が返るように変更したプログラム
source
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define CORRECT 1
#define WRONG 0
void question(int *,int *);
void print_message(int);
int main()
{
int a,b;
int answer;
srand(time(NULL));
while(1)
{
question(&a,&b);
printf("掛け算を行います答えを入力してください\n");
printf("問題 %d×%dは?\n",a,b);
scanf("%d",&answer);
while(1)
{
if(answer==a*b)
{
print_message(CORRECT);
break;
}
else
{
print_message(WRONG);
scanf("%d",&answer);
continue;
}
}
printf("続けますか(1-終了 それ以外 続行\n");
scanf("%d",&answer);
if(answer==1)
{
break;
}
}
getch();
return 0;
}
void question(int *a,int *b)
{
*a=rand()%10;
*b=rand()%10;
}
void print_message(int answer)
{
switch(rand()%4)
{
case 0:
printf("%s\n",answer==CORRECT ? "とてもよくできました!":
"合っていません,もう一度やってみましょう");
break;
case 1:
printf("%s\n",answer==CORRECT ? "すばらしい!":
"間違いです,もう一回ためしてみましょう");
break;
case 2:
printf("%s\n",answer==CORRECT ? "じょうできです!":
"あきらめないで!");
break;
case 3:
printf("%s\n",answer==CORRECT ? "その調子でいきましょう!":
"合っていません,がんばってください!");
break;
default:
break;
}
}
5.34: 5.33のプログラムを正解と不正解の個数をカウントするように変更したプログラム
source
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define COUNT 10
void question(int *,int *);
void print_message(int);
double correct_percent(int);
int main()
{
int a,b;
int answer;
int correct;
int i;
correct=0;
for(i=0;i<COUNT;i++)
{
question(&a,&b);
printf("掛け算を行います答えを入力してください\n");
printf("問題 %d×%dは?\n",a,b);
scanf("%d",&answer);
if(answer==a*b)
{
correct++;
}
}
if(correct_percent(correct)<=75)
{
printf("先生によく教えてもらってください\n");
}
getch();
return 0;
}
void question(int *a,int *b)
{
*a=rand()%10;
*b=rand()%10;
}
double correct_percent(int correct)
{
return 100*(double)correct/COUNT;
}
5.35: 数当てゲームをするプログラム
source
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <ctype.h>
//void print_message(unsigned int);
int main()
{
int num;
int left,right;
int end;
int answer;
int first;
unsigned int guess;
char buf;
srand(time(NULL));
end=0;
first=1;
left=1;
guess=0;
right=1000;
while(end==0)
{
if(first==1)
{
answer=rand()%1000+1;
//printf("%d\n",answer);
printf("1-1000までの間の整数を1つ選びました。\n");
printf("その数を当てられますか?\n");
printf("推測した数をタイプしてください\n");
scanf("%d",&num);
first=0;
}
if(num==answer)
{
//print_message(guess);
do
{
printf("続けますか(yまたはn)?");
fflush(stdin);
scanf("%c",&buf);
buf=tolower(buf);
}
while(buf!='y' && buf!='n');
if(buf=='y')
{
first=1;
}
else
{
end=1;
}
}
else if(num<answer)
{
printf("小さすぎます,もう一度タイプしてみてください\n");
guess++;
left=num;
printf("(%d-%d)の範囲にあります\n",left,right);
scanf("%d",&num);
}
else
{
printf("大きすぎます,もう一度タイプしてみてください\n");
guess++;
right=num;
printf("(%d-%d)の範囲にあります\n",left,right);
scanf("%d",&num);
}
}
getch();
return 0;
}
void print_message(unsigned int guess)
{
if(guess<=10)
{
printf("秘訣をつかんだかそれとも運がよかったのいずれかですね\n");
}
else if(guess==10)
{
printf("さすが秘訣をつかみましたね\n");
}
else
{
printf("もっと上手にできるはず\n");
}
return;
}
5.36: 5.35で作ったプログラムをプレーヤーの推測数をカウントするよう変更したプログラム
source
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <ctype.h>
void print_message(unsigned int);
int main()
{
int num;
int left,right;
int end;
int answer;
int first;
unsigned int guess;
char buf;
srand(time(NULL));
end=0;
first=1;
left=1;
guess=0;
right=1000;
while(end==0)
{
if(first==1)
{
answer=rand()%1000+1;
//printf("%d\n",answer);
printf("1-1000までの間の整数を1つ選びました。\n");
printf("その数を当てられますか?\n");
printf("推測した数をタイプしてください\n");
scanf("%d",&num);
first=0;
}
if(num==answer)
{
print_message(guess);
do
{
printf("続けますか(yまたはn)?");
fflush(stdin);
scanf("%c",&buf);
buf=tolower(buf);
}
while(buf!='y' && buf!='n');
if(buf=='y')
{
first=1;
}
else
{
end=1;
}
}
else if(num<answer)
{
printf("小さすぎます,もう一度タイプしてみてください\n");
guess++;
left=num;
printf("(%d-%d)の範囲にあります\n",left,right);
scanf("%d",&num);
}
else
{
printf("大きすぎます,もう一度タイプしてみてください\n");
guess++;
right=num;
printf("(%d-%d)の範囲にあります\n",left,right);
scanf("%d",&num);
}
}
getch();
return 0;
}
void print_message(unsigned int guess)
{
if(guess<=10)
{
printf("秘訣をつかんだかそれとも運がよかったのいずれかですね\n");
}
else if(guess==10)
{
printf("さすが秘訣をつかみましたね\n");
}
else
{
printf("もっと上手にできるはず\n");
}
return;
}
5.37: 再帰関数power(base, exponent)を実装したプログラム
source
#include <stdio.h>
#include <conio.h>
int power(int,int);
int main()
{
int base;
int exponent;
int result;
printf("べき乗を求めます\n");
scanf("%d",&base);
scanf("%d",&exponent);
if((result=power(base,exponent))==-1)
{
fprintf(stderr,"エラーです\n");
return -1;
}
printf("%dの%d乗は%dです\n",base,exponent,result);
getch();
return 0;
}
int power(int base,int exponent)
{
if(exponent<1)
{
return -1;
}
else if(exponent==1)
{
return base;
}
else
{
return power(base,exponent-1)*base;
}
}
5.38: フィボナッチ数列を扱うプログラム
- a: フィボナッチ数列のn項目を計算する非再帰関数fibonacci(n)を実装
source
#include <stdio.h>
#include <conio.h>
#include <limits.h>
#define MAX 10
int fibonacci(int);
int main()
{
int n;
int i;
//printf("フィボナッチ数を第何項目を求めますか\n");
//scanf("%d",&n);
for(i=1;i<MAX;i++)
{
printf("%d項は%dです\n",i,fibonacci(i));
}
getch();
return 0;
}
int fibonacci(int n)
{
int i;
static int fibo[INT_MAX-1]; //fibonacci
fibo[1]=1;
if(n==1)
{
return fibo[0];
}
else if(n==2)
{
return fibo[1];
}
else
{
for(i=n-1;i>0 && fibo[i]==0;i--);
for(;i<=n;i++)
{
fibo[i+1]=fibo[i]+fibo[i-1];
}
return fibo[n-1];
}
}
5.39: ハノイの塔
source
#include <stdio.h>
// Recursive function to solve Tower of Hanoi
void hanoi(int n, char source, char target, char auxiliary) {
if (n == 1) {
printf("Move disk 1 from %c to %c\n", source, target);
return;
}
// Move n-1 disks from source to auxiliary
hanoi(n - 1, source, auxiliary, target);
// Move the nth disk from source to target
printf("Move disk %d from %c to %c\n", n, source, target);
// Move the n-1 disks from auxiliary to target
hanoi(n - 1, auxiliary, target, source);
}
int main() {
int num_disks = 3; // You can change this to any number of disks
hanoi(num_disks, '1', '3', '2'); // A = source, C = target, B = auxiliary
return 0;
}
5.40: ハノイの塔(反復バージョン)
source
#include <stdio.h>
#include <math.h>
void moveDisk(char, char, int);
void hanoiIterative(int, char, char, char);
void moveDiskBetweenRods(int *, int [], int *, int [], char, char);
void moveDisk(char from, char to, int disk) {
printf("Move disk %d from %c to %c\n", disk, from, to);
}
void hanoiIterative(int n, char from, char to, char aux) {
int totalMoves = pow(2, n) - 1;
// Rods represented as arrays of disk sizes
int A[n], B[n], C[n];
int topA = n - 1, topB = -1, topC = -1;
// Initialize source rod A
for (int i = 0; i < n; i++) {
A[i] = n - i;
}
// If number of disks is even, swap destination and auxiliary
if (n % 2 == 0) {
char temp = to;
to = aux;
aux = temp;
}
for (int i = 1; i <= totalMoves; i++) {
if (i % 3 == 1) {
moveDiskBetweenRods(&topA, A, &topC, C, from, to);
} else if (i % 3 == 2) {
moveDiskBetweenRods(&topA, A, &topB, B, from, aux);
} else if (i % 3 == 0) {
moveDiskBetweenRods(&topB, B, &topC, C, aux, to);
}
}
}
void moveDiskBetweenRods(int *topFrom, int from[], int *topTo, int to[], char fromRod, char toRod) {
int fromDisk = (*topFrom >= 0) ? from[*topFrom] : 0;
int toDisk = (*topTo >= 0) ? to[*topTo] : 0;
// Move logic
if (fromDisk == 0) {
from[++(*topFrom)] = toDisk;
(*topTo)--;
moveDisk(toRod, fromRod, toDisk);
} else if (toDisk == 0) {
to[++(*topTo)] = fromDisk;
(*topFrom)--;
moveDisk(fromRod, toRod, fromDisk);
} else if (fromDisk > toDisk) {
from[++(*topFrom)] = toDisk;
(*topTo)--;
moveDisk(toRod, fromRod, toDisk);
} else {
to[++(*topTo)] = fromDisk;
(*topFrom)--;
moveDisk(fromRod, toRod, fromDisk);
}
}
int main() {
int n = 3; // Number of disks
hanoiIterative(n, '1', '3', '2');
return 0;
}
5.41: 再帰処理の可視化
source
#include <stdio.h>
#include <conio.h>
long factorial(long);
int main()
{
int i;
for (i = 0; i <= 10; i++)
{
factorial(i);
printf("\n");
}
getch();
return 0;
}
long factorial(long number)
{
static int count;
static int startFlag = 1;
char buf1[100];
if (startFlag == 1)
{
count = number;
startFlag = 0;
}
sprintf(buf1, "%12s %%%dld\n", "(number)", count - number + 2);
printf(buf1, number);
if (number <= 1)
{
startFlag = 1;
return 1;
}
else
{
sprintf(buf1, "%12s %%%dld\n", "(number - 1)", count - number + 2);
printf(buf1, number - 1);
return (number * factorial(number - 1));
}
}
5.42: 与えられた整数xとyの最大公約数を返す再帰関数gcdを実装したプログラム
source
#include<stdio.h>
int gcd(int x, int y);
int main()
{
int x;
int y;
for(x = 1; x < 10; x++)
{
for(y = 0; y < 10; y++)
{
printf("The greatest common factor of x(%d) and y(%d) is %d\n", x, y, gcd(x, y));
}
}
return 0;
}
int gcd(int x, int y)
{
if (y == 0)
{
return x;
}
else
{
return gcd(y, x % y);
}
}
5.43: main関数を呼び出すプログラム
source
#include <stdio.h>
int main()
{
static count = 1;
// mainを呼び出す度にcountをポストインクリメントし表示
main();
count++;
printf("count %d\n", count);
return 0;
}
5.44: 小学生に掛け算を教えるコンピュータ支援教育プログラム
- a: 学習レベルを選択できるようにしたプログラム
source
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <math.h>
void question(int *,int *,int);
int main()
{
int a,b;
int answer;
int level;
srand(time(NULL));
while(1)
{
do
{
printf("レベルを入力してください\n");
scanf("%d",&level);
}while(level<=0);
printf("掛け算を行います答えを入力してください\n");
question(&a,&b,level);
printf("問題 %d×%dは?\n",a,b);
scanf("%d",&answer);
while(1)
{
if(answer==a*b)
{
printf("とてもよくできました\n");
break;
}
else
{
printf("もう一度やってみましょう\n");
scanf("%d",&answer);
}
}
printf("続けますか(1終了,それ以外続行)\n");
scanf("%d",&answer);
if(answer==1)
{
break;
}
}
getch();
return 0;
}
void question(int *a,int *b,int level)
{
*a=rand()%(int)pow(10,level);
*b=rand()%(int)pow(10,level);
}
- b: 学習したい算術問題の種類を選択できるようにしたプログラム
source
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <math.h>
void input_option(int *);
void input_level(int *);
void input_answer(int *);
int input_continue(void);
void print_question(int,int,int *,int *);
static void question(int *,int *,int);
int answer_check(int,int,int *,int *);
int main()
{
int a,b;
int answer;
int level;
int op;
srand(time(NULL));
input_option(&op);
while(1)
{
input_level(&level);
print_question(op,level,&a,&b);
input_answer(&answer);
while(1)
{
if(answer_check(answer,op,&a,&b)==1)
{
printf("とてもよくできました\n");
break;
}
else
{
printf("もう一度やってみましょう\n");
scanf("%d",&answer);
}
}
if(input_continue()==1)
{
break;
}
}
getch();
return 0;
}
void input_option(int *option)
{
do
{
printf("オプションを入力してください\n");
scanf("%d",option);
}while(*option<=0 || 6<=*option);
}
void input_level(int *level)
{
do
{
printf("レベルを入力してください\n");
scanf("%d",level);
}while(*level<=0);
}
void input_answer(int *answer)
{
printf("答えを入力してください\n");
scanf("%d",answer);
}
int input_continue()
{
int con;
printf("続けますか(1終了,それ以外続行)\n");
scanf("%d",&con);
if(con==1)
{
return 1;
}
else
{
return 0;
}
}
void print_question(int op,int level,int *a,int *b)
{
if(op==5)
{
op=rand()%4+1;
}
if(op==1)
{
printf("足し算を行います答えを入力してください\n");
question(a,b,level);
printf("問題 %d+%dは?\n",*a,*b);
}
else if(op==2)
{
printf("ひき算を行います答えを入力してください\n");
question(a,b,level);
printf("問題 %d-%dは?\n",*a,*b);
}
else if(op==3)
{
printf("掛け算を行います答えを入力してください\n");
question(a,b,level);
printf("問題 %d×%dは?\n",*a,*b);
}
else if(op==4)
{
printf("割り算を行います答えを入力してください\n");
question(a,b,level);
printf("問題 %d/%dは?\n",*a,*b);
}
return;
}
void question(int *a,int *b,int level)
{
*a=rand()%(int)pow(10,level);
*b=rand()%(int)pow(10,level);
}
int answer_check(int answer,int op,int *a,int *b)
{
if(op==1)
{
if(*a+*b==answer)
{
return 1;
}
else
{
return 0;
}
}
else if(op==2)
{
if(*a-*b==answer)
{
return 1;
}
else
{
return 0;
}
}
else if(op==3)
{
if(*a*(*b)==answer)
{
return 1;
}
else
{
return 0;
}
}
else if(op==4)
{
if((*a)/(*b)==answer)
{
return 1;
}
else
{
return 0;
}
}
return -1;
}
5.45: 2点の距離を計算する関数distanceを実装したプログラム
source
#include <stdio.h>
#include <conio.h>
#include <math.h>
float distance(float,float,float,float);
int main()
{
float x1,x2,y1,y2;
printf("2点間の距離を計算します\n");
printf("x1,y1");
scanf("%f %f",&x1,&y1);
printf("x2,y2");
scanf("%f %f",&x2,&y2);
printf("2点間の距離は%fです\n",distance(x1,x2,y1,y2));
getch();
return 0;
}
float distance(float x1,float x2,float y1,float y2)
{
return sqrt(pow(x1-x2,2)+pow(y1-y2,2));
}
5.48: 5.47のプログラムの働きがわかったら、2番目の引数が負であっても正しく機能するように変更したプログラム
source
#include <stdio.h>
#include <conio.h>
int mystery(int,int);
int main()
{
int x,y;
int result;
printf("2つの整数を入力してください\n");
scanf("%d%d",&x,&y);
if((result=mystery(x,y))==-1)
{
printf("bに負数が入力されました\n");
return -1;
}
printf("結果は : %d\n",result);
getch();
return 0;
}
int mystery(int a,int b)
{
if(b==1)
{
return a;
}
else if(b<=0)
{
return -1;
}
else
{
return a+mystery(a,b-1);
}
}
5.49: 表5.1(P.134)の数学ライブラリ関数をできるだけたくさんテストするプログラム
source
#include <stdio.h>
#include <conio.h>
#include <math.h>
int main()
{
double x = 1.0;
int count;
for (count = 1; count <= 3; count++)
{
printf("\n引数値 %lf\n", x);
printf("sqrt %lf\n", sqrt(x));
printf("exp %lf\n", exp(x));
printf("log %lf\n", log(x));
printf("log10 %lf\n", log10(x));
printf("fabs %lf\n", fabs(x));
printf("ceil %lf\n", ceil(x));
printf("floor %lf\n", floor(x));
printf("pow %lf\n", pow(x, 2));
printf("fmod %lf\n", fmod(x, 2));
printf("sin %lf\n", sin(x));
printf("cos %lf\n", cos(x));
printf("tan %lf\n", tan(x));
x += 2.0;
}
getch();
return 0;
}
5.51: リスト5.6(P.148)のクラップスゲームプログラムをお金を賭けられるように変更したプログラム
source
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <stdlib.h>
#define P_WIN 1
#define P_LOST 0
void input_data(int *);
int game(void);
int rollDice(void);
void print_message(int);
int main()
{
int warge;
int bankBalance=1000;
while(1)
{
input_data(&warge);
if(game()==P_WIN)
{
bankBalance+=warge;
}
else
{
bankBalance-=warge;
}
printf("現在の所持金は%dです\n",bankBalance);
if(bankBalance<=0)
{
printf("お気の毒さまあなたは破産しました\n");
break;
}
print_message(bankBalance);
}
getch();
return 0;
}
void input_data(int *wager)
{
do
{
printf("掛け金を入力してください\n");
scanf("%d",wager);
}
while(*wager<=0);
return ;
}
int game()
{
int gameStatus,sum,myPoint;
srand(time(NULL));
sum=rollDice();
switch(sum)
{
case 7:
case 11:
gameStatus=1;
break;
case 2:
case 3:
case 12:
gameStatus=2;
break;
default:
gameStatus=0;
myPoint=sum;
printf("もち点は %d\n",myPoint);
break;
}
while(gameStatus==0)
{
sum=rollDice();
if(sum==myPoint)
{
gameStatus=1;
}
else
{
if(sum==7)
{
gameStatus=2;
}
}
}
if(gameStatus==1)
{
printf("プレイヤーの勝ち\n");
return P_WIN;
}
printf("プレイヤーの負け\n");
return P_LOST;
}
int rollDice()
{
int die1,die2,workSum;
die1=1+(rand()%6);
die2=1+(rand()%6);
workSum=die1+die2;
printf("プレイヤーがさいころを振った 出目は %d+%d=%d\n",die1,die2,workSum);
return workSum;
}
void print_message(int b)
{
if(0<b && b<=1000)
{
printf("危ないもう時期無一文になるのでは?\n");
}
else if(1000<b && b<=2000)
{
printf("さあこいどんどんかけてみよう\n");
}
else if(2000<b)
{
printf("だいぶ稼げましたね そろそろお金に換えましょう\n");
}
return;
}
