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

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

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

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

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Q&A

解決済

3回答

1221閲覧

関数の中で関数を使いたい。breakの場所

yu3sukei22

総合スコア8

C

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

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

0グッド

0クリップ

投稿2021/05/13 19:28

編集2021/05/13 19:29

c

1#include <stdio.h> 2#include <math.h> 3int calc_a(int year,int month,int day){ //何日経ったか 4 int monthdays[]={0,31,59,90,120,151,181,212,243,273,304,334}; 5 int eachmonth2[]={31,28,31,30,31,30,31,31,30,31,30,31}; 6 if(fx(year)==0 && (month==1 || month==2) && day<eachmonth2[month-1]){ //閏年かつ1月か2月かつ2/29じゃなかった場合 7 int days = (year-1)*365+(((year-1)/4)-((year-1)/100)+((year-1)/400))+(monthdays[month-1])+day-1; 8 }else if(fx(year)==0 && month==2 && day==29){ //閏年かつ2/29だった場合 9 int days = (year-1)*365+(((year-1)/4)-((year-1)/100)+((year-1)/400))+(monthdays[month-1])+day-1; 10 }else if (fx(year)==0 && month>3){ //閏年かつ3月以降だった場合 11 int days = (year-1)*365+(((year-1)/4)-((year-1)/100)+((year-1)/400))+(monthdays[month-1])+day; 12 }else{ //閏年じゃなかった場合 13 int days = (year-1)*365+(((year-1)/4)-((year-1)/100)+((year-1)/400))+(monthdays[month-1])+day-1; 14 } 15 return days; 16} 17int fx(int a){ //閏年判定 18 if(a%4==0 && a%100!=0){ 19 return 0; 20 }else if (a%400==0){ 21 return 0; 22 }else{ 23 return 1; 24 } 25} 26 27int main(void){ 28 int year,month,day,days,z,nowyaer,nowmonth,nowday,nowdays; 29 int eachmonth[]={31,28,31,30,31,30,31,31,30,31,30,31}; 30 int lyeachmonth[]={31,29,31,30,31,30,31,31,30,31,30,31}; 31 printf("記念日の西暦を入力してください"); 32 scanf("%d",&year); 33 printf("記念日月を入力してください"); 34 scanf("%d",&month); 35 if(month>12){ //12より大きい数字が打たれた時にエラーを出す 36 printf("正しい月を入力してください"); 37 break; 38 } 39 printf("記念日日付を入力してください"); 40 scanf("%d",&day); 41 if(fx(year)==0 && day>lyeachmonth[month-1]){ //ありもしない日を打たれた時にエラーを出す 42 printf("正しい日付を入力してください"); 43 }else if(day>eachmonth[month-1]){ 44 printf("正しい日付を入力してください"); 45 } 46 days=0; 47 days=calc_a(year,month,day); 48 printf("%d年%d月%d日は西暦1年1月1日から%d日経っています\n",year,month,day,days); 49 return 0; 50}

閏年を考えに入れて場合分けをしました。このようにした場合最初の関数で閏年判別の関数を使いたかったのですがそこでエラーが出てしまいました。どこを直せばいいかわからずとりあえずいろいろ手を出したのですが解決には至らず。。。
3つほどエラーが出ました。breakの場所がループの中に入っていないと言われましたが{}の中に入っているのにどこが間違ってるのかもわかりません。
よろしければ回答の程をお願いします。以下エラーコード

ex3.c:6:8: error: implicit declaration of function 'fx' is invalid in C99 [-Werror,-Wimplicit-function-declaration] if(fx(year)==0 && (month==1 || month==2) && day<eachmonth2[month-1]){ //閏年かつ1月か2月かつ2/29じゃなかった場合 ^ ex3.c:15:12: error: use of undeclared identifier 'days'; did you mean 'day'? return days; ^~~~ day ex3.c:3:35: note: 'day' declared here int calc_a(int year,int month,int day){ //何日経ったか ^ ex3.c:37:9: error: 'break' statement not in loop or switch statement break; ^ 3 errors generated.

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

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

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

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

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

guest

回答3

0

回答ではありませんが calc_a を(現状ままに)整理してみました。

c

1int calc_a(int year,int month,int day){ //何日経ったか 2 int monthdays[] = {0,31,59,90,120,151,181,212,243,273,304,334}; 3 int eachmonth2[] = {31,28,31,30,31,30,31,31,30,31,30,31}; 4 int days = ((year-1)*365) 5 + (((year-1)/4) - ((year-1)/100) + ((year-1)/400)) 6 + monthdays[month-1] 7 + day; 8 9 if (fx(year) == 0) { 10 if ((month==1 || month==2) && day<eachmonth2[month-1]) { //閏年かつ1月か2月かつ2/29じゃなかった場合 11 days = days - 1; 12 } else if (month==2 && day==29) { //閏年かつ2/29だった場合 13 days = days - 1; 14 } else if (month>3) { //閏年かつ3月以降だった場合 15 ; 16 } 17 } else { 18 days = days -1; 19 } 20 21 return days; 22}

--- 追記 ---
現状を踏襲するならこんなかんじでしょか

c

1 while(1){ 2 int b = fx(year); 3 if (b == 0) { 4 if (day>lyeachmonth[month-1]){ //ありもしない日を打たれた時にエラーを出す 5/*(略)*/ 6 } else { 7 break; 8 } 9 } else { 10 if(day>eachmonth[month-1]) { 11/*(略)*/ 12 } else { 13 break; 14 } 15 }

投稿2021/05/13 22:38

編集2021/05/14 01:04
takasima20

総合スコア7466

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

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

yu3sukei22

2021/05/14 00:30

回答ありがとうございます!とてもわかりやすく助かりました! その上で自分でコードを書き換えたのですが #include <stdio.h> #include <math.h> int fx(int a){ //閏年判定 int b; if (a % 400 == 0) { b=0; } else if (a % 100 == 0) { b=1; } else if (a % 4 == 0) { b=0; } else { b=1; } return b; } int calc_a(int year,int month,int day){ //何日経ったか int monthdays[]={0,31,59,90,120,151,181,212,243,273,304,334}; int eachmonth2[]={31,28,31,30,31,30,31,31,30,31,30,31}; int days = (year-1)*365+(((year-1)/4)-((year-1)/100)+((year-1)/400))+(monthdays[month-1])+day; int b=fx(year); if(b==0){ if ((month==1 || month==2) && day<eachmonth2[month-1]){ days=days-1; }else if(month==2 && day==29){ days=days-1; }else if(month>=3){ ; } }else{ days=days-1; } return days; } int main(void){ int year,month,day,days,z,nowyaer,nowmonth,nowday,nowdays; int eachmonth[]={31,28,31,30,31,30,31,31,30,31,30,31}; int lyeachmonth[]={31,29,31,30,31,30,31,31,30,31,30,31}; printf("記念日の西暦を入力してください"); scanf("%d",&year); printf("記念日月を入力してください"); scanf("%d",&month); while(1){ if(month>12){ printf("正しい月を入力してください\n"); printf("記念日月を入力してください"); scanf("%d",&month);//12より大きい数字が打たれた時にエラーを出す printf("正しい月を入力してください\n"); }else{ break; } } printf("記念日日付を入力してください"); scanf("%d",&day); while(1){ int b=fx(year); if(b==0 && day>lyeachmonth[month-1]){ //ありもしない日を打たれた時にエラーを出す printf("正しい日付を入力してください\n"); printf("記念日日付を入力してください"); scanf("%d",&day); }else if(day>eachmonth[month-1]){ printf("正しい日付を入力してください\n"); printf("記念日日付を入力してください"); scanf("%d",&day); }else{ break; } } days=0; days=calc_a(year,month,day); printf("%d年%d月%d日は西暦1年1月1日から%d日経っています\n",year,month,day,days); return 0; } このように変えた場合に西暦4年2月29日と打ち込んだ場合にwhile文に引っかからずに通るようにしたかったのですがどうしても引っかかってしまいループしてしまいます。何故なんでしょうか?
yu3sukei22

2021/05/14 01:18

解決しました!!!本当にありがとうございます!!!!!!!
guest

0

回答ではありませんが、もう少し簡単に書けます。

C

1#include <stdio.h> 2 3int isleap(int y) 4{ 5 return y%4 == 0 && (y%100 != 0 || y%400 == 0); 6} 7 8int calc_days(int year, int month, int day) 9{ 10 static int monthdays[] = { 365,393,59,90,120,151,181,212,243,273,304,334 }; 11 if (month < 3) year--; 12 return year*365 + year/4 - year/100 + year/400 13 + monthdays[month-1] + day - 366; 14} 15 16int main(void) 17{ 18 int year, month, day; 19 static int eachmonth[] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; 20 printf("記念日の西暦を入力してください: "); 21 scanf("%d", &year); 22 printf("記念日月を入力してください: "); 23 scanf("%d", &month); 24 if (month < 1 || month > 12) { 25 puts("正しい月を入力してください"); return 1; 26 } 27 printf("記念日日付を入力してください: "); 28 scanf("%d", &day); 29 if (day < 1 || day > eachmonth[month-1] + (month==2 && isleap(year))) { 30 puts("正しい日付を入力してください"); return 2; 31 } 32 printf("%d年%d月%d日は西暦1年1月1日から%d日経っています\n", 33 year, month, day, calc_days(year, month, day)); 34 return 0; 35}

現在のグレゴリオ暦は1582年10月15日から採用されたもので、
それ以前は、4年に1度閏年があるだけのユリウス暦だったので、
西暦1年1月1日からの日数というのは厳密に言えば異なった値になります。

投稿2021/05/14 01:14

編集2021/05/14 01:17
kazuma-s

総合スコア8224

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

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

yu3sukei22

2021/05/14 01:44

なるほど.... 暦の違いも考えないといけなくなりますか....
guest

0

ベストアンサー

ex3.c:6:8: error: implicit declaration of function 'fx' is invalid in C99

直訳すると「関数 fx の暗黙的な宣言は無効」ですが、原因は fx より前に calc_a があって、その中で fx が使われているからですね。fx と calc_a の順番を入れ替えるか、calc_a の前に fx の宣言を書くと良いでしょう。

diff

1 #include <stdio.h> 2 #include <math.h> 3+int fx(int a); // 関数 fx の宣言を追加。 4 int calc_a(int year,int month,int day){ //何日経ったか

ex3.c:15:12: error: use of undeclared identifier 'days'; did you mean 'day'?

days という変数が if や else if などの中で宣言されているために、その外にある return では使えないということです。days の宣言だけ、if の前に書くと良いでしょう。

diff

1+ int days; // if の前で変数 days を宣言だけする。 2 if(条件){ 3- int days = 〜; 4+ days = 〜; // if の中では days に代入だけする。 5 }else if(別の条件){ 6- int days = 〜; 7+ days = 〜; // 以下同様。

ex3.c:37:9: error: 'break' statement not in loop or switch statement

break は、for や while などのループや、switch の中でしか使えません。if の中に break がありますが、if から break することはできません。(ループや switch の中に if があるなら、if の中に break を書けますが、その場合 if から break するのではなく、その外側にあるループなどから break することになります。)


閏年の 2/29 の日付入力がうまくいかない件ですが、最初の if では 29 日は通りますが、最初の if の条件を満たさないので次の else if の条件もチェックされて、ここで引っかかってしまいます。
else if (b != 0 && day > eachmonth[month - 1]) { のように、else if でも b をチェックする必要があります。

c

1 printf("記念日日付を入力してください"); 2 scanf("%d",&day); 3 while(1){ 4 int b=fx(year); 5 if(b==0 && day>lyeachmonth[month-1]){ //ありもしない日を打たれた時にエラーを出す 6 printf("正しい日付を入力してください\n"); 7 printf("記念日日付を入力してください"); 8 scanf("%d",&day); 9 }else if(day>eachmonth[month-1]){ // 上の条件を満たさなかった場合、この条件もチェックされる。 10 printf("正しい日付を入力してください\n"); 11 printf("記念日日付を入力してください"); 12 scanf("%d",&day); 13 }else{ 14 break; 15 } 16 }

個人的には同じ scanf やエラーメッセージを何度も書きたくないので、次のように書くのが好みです。

c

1 while (1) { 2 printf("記念日日付を入力してください"); 3 scanf("%d", &day); 4 int b = fx(year); 5 if ((b == 0 && day <= lyeachmonth[month - 1]) || 6 (b != 0 && day <= eachmonth[month - 1])) { 7 break; // 正しい日を入力されたので、ループを抜ける。 8 } 9 printf("正しい日付を入力してください\n"); 10 }

ちなみに、西暦1年1月1日からの日数ですが、ユリウス暦からグレゴリオ暦への切り替え (国によって違う) とかあるので、微妙かもしれません。

投稿2021/05/13 20:01

編集2021/05/14 01:13
hoshi-takanori

総合スコア7901

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

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

yu3sukei22

2021/05/14 00:30

回答ありがとうございます!とてもわかりやすく助かりました! その上で自分でコードを書き換えたのですが #include <stdio.h> #include <math.h> int fx(int a){ //閏年判定 int b; if (a % 400 == 0) { b=0; } else if (a % 100 == 0) { b=1; } else if (a % 4 == 0) { b=0; } else { b=1; } return b; } int calc_a(int year,int month,int day){ //何日経ったか int monthdays[]={0,31,59,90,120,151,181,212,243,273,304,334}; int eachmonth2[]={31,28,31,30,31,30,31,31,30,31,30,31}; int days = (year-1)*365+(((year-1)/4)-((year-1)/100)+((year-1)/400))+(monthdays[month-1])+day; int b=fx(year); if(b==0){ if ((month==1 || month==2) && day<eachmonth2[month-1]){ days=days-1; }else if(month==2 && day==29){ days=days-1; }else if(month>=3){ ; } }else{ days=days-1; } return days; } int main(void){ int year,month,day,days,z,nowyaer,nowmonth,nowday,nowdays; int eachmonth[]={31,28,31,30,31,30,31,31,30,31,30,31}; int lyeachmonth[]={31,29,31,30,31,30,31,31,30,31,30,31}; printf("記念日の西暦を入力してください"); scanf("%d",&year); printf("記念日月を入力してください"); scanf("%d",&month); while(1){ if(month>12){ printf("正しい月を入力してください\n"); printf("記念日月を入力してください"); scanf("%d",&month);//12より大きい数字が打たれた時にエラーを出す printf("正しい月を入力してください\n"); }else{ break; } } printf("記念日日付を入力してください"); scanf("%d",&day); while(1){ int b=fx(year); if(b==0 && day>lyeachmonth[month-1]){ //ありもしない日を打たれた時にエラーを出す printf("正しい日付を入力してください\n"); printf("記念日日付を入力してください"); scanf("%d",&day); }else if(day>eachmonth[month-1]){ printf("正しい日付を入力してください\n"); printf("記念日日付を入力してください"); scanf("%d",&day); }else{ break; } } days=0; days=calc_a(year,month,day); printf("%d年%d月%d日は西暦1年1月1日から%d日経っています\n",year,month,day,days); return 0; } このように変えた場合に西暦4年2月29日と打ち込んだ場合にwhile文に引っかからずに通るようにしたかったのですがどうしても引っかかってしまいループしてしまいます。何故なんでしょうか?
yu3sukei22

2021/05/14 01:43

回答ありがとうございます!!わざわざ綺麗な形に直していただきありがとうございました!グレゴリオ暦なども考えなきゃならないですね....
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問