関数を使って2

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
すず

関数を使って2

#1

投稿記事 by すず » 17年前

次のも教えて下さい。

西暦年、月、日を読み込み、その日が何曜日であるかを表示するプログラムを以下の手順で作成せよ。
3-1
西暦年を読み込み、その値を返す関数
int get_year(void)
を作成せよ。なお1900未満の値が入力された場合のには再入力を促し、1900以上の値が入力されるまで処理を繰り返させること。
また、関数の動作を確認するための適切なmain関数も作成し、完成したプログラムとして動作テストを行うこと。

3-2
月を読み込み、その値を返す関数
int get_month(void)
を作成せよ。なお0以下または13以上の値が入力された場合には再入力を促し、1以上12以下の値が入力されるまで処理を繰り返させること。
また、関数の動作を確認するための適切なmain関数も作成し、完成したプログラムとして動作テストを行うこと。

3-3
西暦年year を受け取り、その年が閏年ならば1をそうでなければ0を返す関数
int judge_uru(int year)
を作成せよ。また、関数の動作を確認するための適切なmain関数も作成し、完成したプログラムとして動作テストを行うこと。
なお、グレゴリオ暦では以下の規則に基づいて、閏年が設けられる。
(1)4で割り切れる年は閏年である。
(2)ただし、100で割り切れるが、400で割り切れない年は、閏年ではない。
たとえば、2004年は閏年であり、また1900年や2100年は閏年ではなく、2004年は閏年である。

3-4
西暦年yearと月monthを受け取り、year年 month月の最終日を返す関数
int get_lastday(int year,int month)
を作成せよ。たとえば、yearに2004をmonthに2を受け取ると、2004年の2月は29日までなので29を返す事になる。
なお、関数get_lastdayの中で3-3で作成したjudge_uruを呼び出して使うようにする事。また、関数の動作を確認するための適切なmain関数も作成し、完成したプログラムとして動作テストを行うこと。

3-5
日を読み込み、その値を返す関数
int get_day(int year, int month)
を作成せよ。なお、この関数は、西暦年yearと月monthを受け取り、これらの値に基づき、その月の最終日を求める。そして0以下または最終日より大きな値が入力された場合には、再入力を促し、正しい値が入力されるまで処理を繰り返す。
なお、関数get_dayの中では、3-4で作成した関数get_lastdayを呼び出して使うことにすること。(言うまでもなく、関数last_dayの中では、3-3で作成されたjudge_uruが呼び出されることになる)また、関数の動作を確認するための適切なmain関数も作成し、完成したプログラムとして動作テストを行うこと。

3-6
西暦年yearを受け取り、1900年からyear年までのトータル日数を返す関数
int get_year_offset(int year)
を作成せよ。たとえば、この関数は1902年を受け取ると、1900から1901年までのトータル日数を返す。すなわち、1900年も1901年も閏年ではないため、365+365=730を返すことになる。
なお、関数get_yesr_offsetの中で、3-3で作成した関数をjudg_uruを呼び出して使うようにすること。また、関数の動作を確認するための適切なmain関数も作成し、完成したプログラムとして動作テストを行うこと。

3-7
西暦年yearと月monthを受け取り、year年の1月からmonth月の前の月までのトータル日数を返す関数
int get_month_offset(int year,int month)
を作成せよ。たとえば、この関数は、yearに2,004を、monthに3を受け取ると、2004年の1月から2月までのトータル日数を返す。すなわち、2004年は閏年であるため、31+29=60を返すことになる。
なお、関数get_month_offsetの中で3-4で作成した関数get_lastdayを呼び出して使うようにする事。また、関数の動作を確認するための適切なmain関数も作成し、完成したプログラムとして動作テストを行うこと。

3-8
世暦年year、月month、日dayを受け取り、year年、month月、day日が何曜日であるかを表示する関数
void put_what_day(int year,int month)
を作成せよ。
なお、この関数のyearには1900年以降の年が与えられるものとする。また、1900年1月1日は月曜日であることを利用して、該当の曜日を求めることにする。
なお、関数put_what_dayの中で、3-6で作成した関数get_year_offsetと3-7で作成した関数 get_month_offsetを呼び出して使うようにする事。また、関数の動作を確認するための適切なmain関数も作成し、完成したプログラムとして動作テストを行うこと。

3-9
3-1から3-8で作成した関数を用いて、以下に示すように、西暦年、月、日、を読み込み、その日が何曜日であるかを表示するプログラムを作成せよ。

例1
西暦年・月・日を入力して下さい
西暦年:2005  return
月  :10 return
日  :15 return
<結果>
2005年10月15日は、土曜日です
 
例2
西暦年・月・日を入力して下さい
西暦年:1899 return
1900年以降の年を入力してください
西暦年:2005  return
月  :15 return
1~12月を入力してください
月  :10 return
日  :35  return
1~31日を入力してください
日  :15 return
<結果>
2005年10月15日は、土曜日です


一応出来たのはここまでです。
#include <stdio.h>

int get_year(void)
{
int nen;
printf("西暦年・月・日を入力して下さい\n");
printf("西暦年:");
scanf("%d",&nen);
while(nen<1900){
printf("1900年以降の年を入力してください\n");
printf("西暦年:");
scanf("%d",&nen);
}
}

int get_month(void)
{
int tuki;
printf("月:");
scanf("%d",&tuki);
while(tuki<1||tuki>12)
{
printf("1~12月を入力して下さい\n");
printf("月:");
scanf("%d",&tuki);
}
}




int main(void)
{
int a,b;
a=get_year();
b=get_month();

return 0;
}

miki

Re:関数を使って2

#2

投稿記事 by miki » 17年前

3-3以降も、一度ご自分で考えてみてください。
正しくなくてもいいですから。

miki

Re:関数を使って2

#3

投稿記事 by miki » 17年前

get_year関数とget_month関数については、
「呼び出し元に値を返していない」という
大きな問題点があります。

get_year関数の最後に
return nen;

get_month関数の最後に
return tuki;

を付け加えましょう。

keichan

Re:関数を使って2

#4

投稿記事 by keichan » 17年前

/*
    回答例です。 3-9 は 3-8 までを理解できればご自分でコーディングできると
    思いますので、わざと載せていません。
    設問にはテスト用の main 関数を作りなさい。とありましたが省略しています。
    まずは、ソースを眺めてみてください。
    疑問点があれば遠慮なくして下さい。
    #コンパイルしてチェックしていませんのでミスがあるかもしれません。
    #突っ込みをお願いします。
*/
/* 3-1 */
int get_year(void)
{
    int input_year = 0;
    do {
        printf("西暦を入力:");
        scanf("%d", &input_year);
    } while( input_year < 1900 );
    return input_year;
}

/* 3-2 */
int get_month(void)
{
    int input_month = 0;
    do {
        printf("月を入力:");
        scanf("%d", &input_month);
    } while( input_month < 1 || 12 < input_month );
}

/* 3-3 */
int judge_uru(int year)
{
    if( year % 4 == 0 ) {
        if( year % 100 == 0 && year % 400 != 0 ) {
            return 0;
        }
        return 1;
    }
    return 0;
}

/* 3-4 */
int get_lastday(int year, int month)
{
    const int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    return days[month-1] + (month == 2 ? judge_uru(year) : 0);
}

/* 3-5 */
int get_day(int year, int month)
{
    const int last_day = get_lastday(year, month);
    int input_day = 0;
    do {
        printf("日を入力:");
        scanf("%d", &input_day);
    } while( input_day < 1 || last_day < input_day );
    return input_day;
}

/* 3-6 */
int get_year_offset(int year)
{
    const int start_year = 1900;
    int total_day = 0;
    int i;
    for( i=start_year; i<year; ++i ) {
        total_day += 365 + judge_uru(i);
    }
    return total_day;
}

/* 3-7 */
int get_month_offset(int year, int month)
{
    const int start_month = 1;
    int total_day = 0;
    int i;
    for( i=start_month; i<month; ++i ) {
        total_day += get_day(year, i);
    }
    return total_day;
}

/* 3-8 */
/* 問題の引数には int day はありませんでしたが、勝手につけました */
void put_what_day(int year, int month, int day)
{
    const char* const day[7] = {"日", "月", "火", "水", "木", "金", "土"};
    const int total_day = get_year_offset(yaer) + get_month_offset(year, month) + day;
    printf("%s曜日", day[total_day%7]);
}

box

Re:関数を使って2

#5

投稿記事 by box » 17年前

サンプルです。
#include <stdio.h>

int get_year(void);
int get_month(void);
int judge_uru(int year);
int get_lastday(int year, int month);
int get_day(int year, int month);
int get_year_offset(int year);
int get_month_offset(int year, int month);
void put_what_day(int year, int month, int day);

int main(void)
{
	int year, month, day;
	
	printf("西暦年・月・日を入力してください\n");
	year = get_year();
	month = get_month();
	day = get_day(year, month);
	put_what_day(year, month, day);
	return 0;
}

int get_year(void)
{
	int year;
	
	while (1) {
		printf("西暦年:");
		scanf("%d", &year);
		if (year >= 1900)
			break;
		printf("1900年以降の年を入力してください\n");
	}
	return year;
}

int get_month(void)
{
	int month;
	
	while (1) {
		printf("月:");
		scanf("%d", &month);
		if (1 <= month && month <= 12)
			break;
		printf("1~12月を入力してください\n");
	}
	return month;
}

int judge_uru(int year)
{
	return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
}

int get_lastday(int year, int month)
{
	int days[/url][13] = {
		{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
		{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
	};
	
	return days[judge_uru(year)][month];
}

int get_day(int year, int month)
{
	int day;
	
	while (1) {
		printf("日:");
		scanf("%d", &day);
		if (1 <= day && day <= get_lastday(year, month))
			break;
		printf("1~%d日を入力してください\n", get_lastday(year, month));
	}
	return day;
}

int get_year_offset(int year)
{
	int y, d;
	
	for (d = 0, y = 1900; y < year; y++)
		d += 365 + judge_uru(y);
	return d;
}

int get_month_offset(int year, int month)
{
	int m, d;
	
	for (d = 0, m = 1; m < month; m++)
		d += get_lastday(year, m);
	return d;
}

void put_what_day(int year, int month, int day)
{
	int d;
	char *w[/url] = { "日", "月", "火", "水", "木", "金", "土" };
	
	d = get_year_offset(year) + get_month_offset(year, month) + day;
	printf("<結果>\n");
	printf("%d年%d月%d日は、%s曜日です\n", year, month, day, w[d % 7]);
}

すず

Re:関数を使って2

#6

投稿記事 by すず » 17年前

お二人共ありがとうございまいた。分からないところがあるので教えて頂けたらです。
まだ、配列は習ってないのでconstとかday[/url][13]こういうやつが分からないので使わずに出来ませんか。

管理人

Re:関数を使って2

#7

投稿記事 by 管理人 » 17年前

すずさん、詳しくお伝えすることが出来ないのですが、
[/url]と省略されている部分は2がはいります。
int days[/url][13] = {
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
};
これは[2][13]の2次元配列です。
配列を習っていないのでしたら読むのは難しいかもしれませんね。。
どの辺まで理解できました?

box

Re:関数を使って2

#8

投稿記事 by box » 17年前

では、配列を使わない例を提示します。
ifを使う方法とswitchを使う方法がありますが、
今回は前者の例です。
#include <stdio.h>

int get_year(void);
int get_month(void);
int judge_uru(int year);
int get_lastday(int year, int month);
int get_day(int year, int month);
int get_year_offset(int year);
int get_month_offset(int year, int month);
void put_what_day(int year, int month, int day);

int main(void)
{
	int year, month, day;
	
	printf("西暦年・月・日を入力してください\n");
	year = get_year();
	month = get_month();
	day = get_day(year, month);
	put_what_day(year, month, day);
	return 0;
}

int get_year(void)
{
	int year;
	
	while (1) {
		printf("西暦年:");
		scanf("%d", &year);
		if (year >= 1900)
			break;
		printf("1900年以降の年を入力してください\n");
	}
	return year;
}

int get_month(void)
{
	int month;
	
	while (1) {
		printf("月:");
		scanf("%d", &month);
		if (1 <= month && month <= 12)
			break;
		printf("1~12月を入力してください\n");
	}
	return month;
}

int judge_uru(int year)
{
	return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
}

int get_lastday(int year, int month)
{
	if (month == 1 || month ==  3 || month ==  5 || month == 7 ||
	    month == 8 || month == 10 || month == 12)
		return 31;
	if (month == 4 || month ==  6 || month ==  9 || month == 11)
		return 30;
	return 28 + judge_uru(year);
}

int get_day(int year, int month)
{
	int day;
	
	while (1) {
		printf("日:");
		scanf("%d", &day);
		if (1 <= day && day <= get_lastday(year, month))
			break;
		printf("1~%d日を入力してください\n", get_lastday(year, month));
	}
	return day;
}

int get_year_offset(int year)
{
	int y, d;
	
	for (d = 0, y = 1900; y < year; y++)
		d += 365 + judge_uru(y);
	return d;
}

int get_month_offset(int year, int month)
{
	int m, d;
	
	for (d = 0, m = 1; m < month; m++)
		d += get_lastday(year, m);
	return d;
}

void put_what_day(int year, int month, int day)
{
	int d = get_year_offset(year) + get_month_offset(year, month) + day;
	
	printf("<結果>\n");
	printf("%d年%d月%d日は、", year, month, day);
	if (d % 7 == 0) printf("日曜日です\n");
	if (d % 7 == 1) printf("月曜日です\n");
	if (d % 7 == 2) printf("火曜日です\n");
	if (d % 7 == 3) printf("水曜日です\n");
	if (d % 7 == 4) printf("木曜日です\n");
	if (d % 7 == 5) printf("金曜日です\n");
	if (d % 7 == 6) printf("土曜日です\n");
}

box

Re:関数を使って2

#9

投稿記事 by box » 17年前

> まだ、配列は習ってないのでconstとかday[/url][13]こういうやつが分からないので使わずに出来ませんか。

配列を使わないソースを、少しだけ修正しました。
put_what_day関数で、剰余の計算をするタイミングを見直しました。
#include <stdio.h>

int get_year(void);
int get_month(void);
int judge_uru(int year);
int get_lastday(int year, int month);
int get_day(int year, int month);
int get_year_offset(int year);
int get_month_offset(int year, int month);
void put_what_day(int year, int month, int day);

int main(void)
{
	int year, month, day;
	
	printf("西暦年・月・日を入力してください\n");
	year = get_year();
	month = get_month();
	day = get_day(year, month);
	put_what_day(year, month, day);
	return 0;
}

int get_year(void)
{
	int year;
	
	while (1) {
		printf("西暦年:");
		scanf("%d", &year);
		if (year >= 1900)
			break;
		printf("1900年以降の年を入力してください\n");
	}
	return year;
}

int get_month(void)
{
	int month;
	
	while (1) {
		printf("月:");
		scanf("%d", &month);
		if (1 <= month && month <= 12)
			break;
		printf("1~12月を入力してください\n");
	}
	return month;
}

int judge_uru(int year)
{
	return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
}

int get_lastday(int year, int month)
{
	if (month == 1 || month ==  3 || month ==  5 || month == 7 ||
		month == 8 || month == 10 || month == 12)
		return 31;
	if (month == 4 || month ==  6 || month ==  9 || month == 11)
		return 30;
	return 28 + judge_uru(year);
}

int get_day(int year, int month)
{
	int day;
	
	while (1) {
		printf("日:");
		scanf("%d", &day);
		if (1 <= day && day <= get_lastday(year, month))
			break;
		printf("1~%d日を入力してください\n", get_lastday(year, month));
	}
	return day;
}

int get_year_offset(int year)
{
	int y, d;
	
	for (d = 0, y = 1900; y < year; y++)
		d += 365 + judge_uru(y);
	return d;
}

int get_month_offset(int year, int month)
{
	int m, d;
	
	for (d = 0, m = 1; m < month; m++)
		d += get_lastday(year, m);
	return d;
}

void put_what_day(int year, int month, int day)
{
	int d = (get_year_offset(year) + get_month_offset(year, month) + day) % 7;
	
	printf("<結果>\n");
	printf("%d年%d月%d日は、", year, month, day);
	if (d == 0) printf("日曜日です\n");
	if (d == 1) printf("月曜日です\n");
	if (d == 2) printf("火曜日です\n");
	if (d == 3) printf("水曜日です\n");
	if (d == 4) printf("木曜日です\n");
	if (d == 5) printf("金曜日です\n");
	if (d == 6) printf("土曜日です\n");
}

すず

Re:関数を使って2

#10

投稿記事 by すず » 17年前

本当にありがとうございました。
一応理解できました。
また、分からない事があると思うのでその時もお願いします。
ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る