ページ 11

カレンダーについて

Posted: 2008年1月24日(木) 21:50
by カル
#include<stdio.h>

	int main() {

	int iyear,imonths,iday;
	int sum,i;
	int m_array[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
	char*cweek[7] = {"日","月","火","水","木","金","土"};

	sum =0;
	printf ("input (e.g. ****/**/**)\n>>");
	scanf ("%d/%d/%d",&iyear,&imonths,&iday);
	/*閏年の判定*/
	if ((imonths >2) && ((iyear % 4 == 0) && ((iyear % 100 !=0) || (iyear % 400 == 0)))) {
	sum++;
	}
	/*前月までの日数*/
	for (i =0; i < imonths-1; i++) {
	sum += m_array;
	}

	iyear--;
	/*前月と前年度と今月の日数の合計*/
	sum = sum + iyear * 365 + (((iyear / 4)-(iyear / 100))+(iyear / 400))+iday;
	printf("%s曜日",cweek[sum%7]);
	return 0;

}

「このプログラムを利用した今年のカレンダーを表示させる」
外部変数、goto文は使わない、途中でreturn exitは使えない
意味のある定数はマクロ(define文)とする
関数名 変数名の命名規約を守る

カレンダー表示の問題なんですがさっぱりわかりません
ググってはみたのですがわかりませんでした
まずはどうしたらいいのでしょうか?

Re:カレンダーについて

Posted: 2008年1月25日(金) 12:46
by カル
スイマセン完全に丸投げでした

Re:カレンダーについて

Posted: 2008年1月25日(金) 13:03
by やそ
そうですねえ^^;

見るからに丸投げですよね~(苦笑)

<pre>
の”<”、”>”も半角で書いてくださいね。

で、前回作成したプログラムを使ってカレンダーを表示する。ですか。

難しいことはそれほどないと思います。

2008年1月1日から2008年12月31日を1日ずつ曜日取得して表示して、日めくりカレンダーの出来上がり(笑)










ゴメンナサイm(_ _)m


ですけど、
「このプログラムを利用した今年のカレンダーを表示させる」
だけでは仕様が確定できません^^;

カルさんも知っておられると思いますが、市販されているカレンダーだけでも千差万別。
1ヶ月ごとのカレンダーでも横一列だったり縦一列だったり、一行=1週間だったり、
一行=1週間でも日曜始まりとは限らず、月曜始まりのほうがビジネスマンには便利だったりします(笑)
また、土日、祝祭日に色が付いているものいないもの。ブラックマンデー・・・じゃない(笑)ハッピーマンデーなんて迷惑な制度が出来たために、祝日も決め打ちが出来ず、曜日判定にて行わなければなりません。

出題者さんがどの程度のカレンダーを想定しておられるのかを今一度ご確認されたほうがよろしいかと思います。

Re:カレンダーについて

Posted: 2008年1月25日(金) 13:40
by 管理人
カレンダーというからには、
日曜日から土曜日まで書いてあって、
日月火水木金土
     1 2 3
 4 5 6 7 8 910
........
 
みたいなのを想像していらっしゃるのでしょう。
とりあえず、引数に「月の始まりの曜日、その月の日数」を渡したら、
カレンダーを表示する関数を作ってみてください。
それが出来ればあとは簡単だと思います。

そのプログラムをいじろうと思わず、一から書いてみてください。そのほうが簡単だと思います。

Re:カレンダーについて

Posted: 2008年1月25日(金) 14:18
by カル
アドバイスありがとうございます。
1から10まで教えてもらおうとした自分が恥ずかしいです

Re:カレンダーについて

Posted: 2008年1月25日(金) 14:27
by 管理人
時間があったらもうちょっと丁寧に書くんですけどね(T_T
今日は午後7時までに論文提出なので特に忙しくて・・。

なので若干30秒で書いたようなプログラムなので
間違ってる可能性大ですが、とりあえず、こんな感じでやれば出来ますよね。
がんばってください。
#include <stdio.h>

void display(int day, int total_day){
	int i,j,t;
	char str_day[7][3]={"日","月","火","水","木","金","土"};
	for(i=0;i<7;i++)
		printf("%s ",str_day);
	printf("\n");

	for(i=0;i<day;i++)
		printf("   ");
	for(j=i,t=1;t<=total_day;j++,t++){
		printf("%2d ",t);
		//jを使ってうまく改行を
	}
}

int main(){
	display(2,30);
}

Re:カレンダーについて

Posted: 2008年1月25日(金) 17:06
by 管理人
お答えできるかわからないので、添削待ちの間に・・。

#include <stdio.h>

void display(int day, int total_day){
	int i,j,t;
	char str_day[7][3]={"日","月","火","水","木","金","土"};
	for(i=0;i<7;i++)
		printf("%s ",str_day);
	printf("\n");

	for(i=0;i<day;i++)
		printf("   ");
	for(j=i,t=1;t<=total_day;j++,t++){
		printf("%2d ",t);
		if(j%7==6)
			printf("\n");	}
	printf("\n");
}

int main(){

	int iyear,imonths,iday;
	int sum,i;
	int m_array[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
	char*cweek[7] = {"日","月","火","水","木","金","土"};

	sum =0;
	printf ("input (e.g. ****/**)\n>>");
	scanf ("%d/%d",&iyear,&imonths);
	iday=1;
	/*閏年の判定*/
	if ((imonths >2) && ((iyear % 4 == 0) && ((iyear % 100 !=0) || (iyear % 400 == 0)))) {
	sum++;
	}
	/*前月までの日数*/
	for (i =0; i < imonths-1; i++) {
	sum += m_array;
	}

	iyear--;
	/*前月と前年度と今月の日数の合計*/
	sum = sum + iyear * 365 + (((iyear / 4)-(iyear / 100))+(iyear / 400))+iday;
	printf("\n%d年%d月は%s曜日から始まって%d日間あるから・・\n\n",iyear+1,imonths,cweek[sum%7],m_array[imonths-1]);

	display(/*コ コ*/);
}

実行結果

input (e.g. ****/**)
>>2008/1

2008年1月は火曜日から始まって31日間あるから・・

日 月 火 水 木 金 土
       1  2  3  4  5
 6  7  8  9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31

 
もう曜日がわかってるなら後は簡単ですよね。
急いで書いたので違うかもしれませんが、色つきの部分しか変更していません。
後はうるう年を入れてやれば・・。
どうでしょうか、解らないところがあれば聞いてください。

Re:カレンダーについて

Posted: 2008年1月25日(金) 17:42
by やそ
管理人さん、いつも答えすぎ(笑)
コレではカルさん自身が考えねばならないところがほとんどありませぬ^^;

Re:カレンダーについて

Posted: 2008年1月25日(金) 17:58
by 管理人
失礼しました。
これでは丸投げでも答えますよと言っているようなものでしたね。

「display(/*コ コ*/);」

の部分を注釈に変更しておきました。
この部分を補って、うるう年の表示が出来るようにすれば完成です。

Re:カレンダーについて

Posted: 2008年1月25日(金) 19:41
by カル
こんなに・・・わざわざスイマセン
私の身勝手な行動がこのような事を生んでしまったのですね
やそさん、管理人さん、申し訳ないです。

とりあえずやってみますね。
管理人さんは大学生なんですか?
卒論とか大変そうですね

Re:カレンダーについて

Posted: 2008年1月25日(金) 20:03
by 管理人
最後に教授に見てもらおうと思って部屋まで行ったらもう帰ってました・・orz

はい、学生です。
もうすぐ修士論文の期限なので、ヒィヒィ言ってます。
しかもその後2つも他に発表する機会があって、英語にも訳さないといけなかったり、色々追われてまして、・・。

プログラムがさっぱりわからないという気持ちはわかりますよ。
この気持ち、自分がずっと将来熟練者の仲間入りが出来たとしても、忘れないようにしようと思っています。
私もまだまだ入門者の端くれですが、プログラムのコードをある程度見慣れてくると、調べる事や挫けず考えることに抵抗が無くなり、
プログラムがちょっとわからなくても、さっぱりで、嫌になってたころの記憶忘れてくるんですよね。
小さな事でプログラムがわからないといっている人間を見ると、
「それ位ちょっと調べたらわかるはずじゃん。お前が調べる気無いからだろう」
そう思うようになってくると思います。
でも、最初ってちょっとわからなくてもホント嫌になるし、何しらべたらいいかもわからないもんですよね。
今では朝から晩までアホみたいにゲームプログラム書いてたりしますが、
大学入ったころはCとかさっぱりで、よく友達が書いたコードそのまま学校に提出するような人間でした。
プログラムがよくわからないから、ウェブでも聞き方がわからず、丸投げしては怒られて、誰も相手にされない。
誰も相手にしてくれないからわからないし、嫌になるし・・。
悪循環でした。

熟練者からしたら丸投げする人間は「人の力借りて楽しようとするズルい奴」と思われるようです。
丸投げだと力にならないから・・などという言葉は立てまえの場合が多く、多くの場合は丸投げされると答える気が無くなるというのが本音だと思います。
でも、どう聞いたらいいかわからないんですよね。全部わからないんだから、聞きようがないジャン・・。
そう思ってました。
でも、それは自分にやる気がそこまで無かったからなんです。
少しわからなかったら、調べるのやめる・・その姿勢をなくし、もう少し頑張れば解けるものばかりでした。
学校で、出る問題なんて「解かそう」と思って出してるんだから、頑張ったら解けて当然なんです。
頑張って調べているうちに、「わからない場所」っていうのが解ってきます。
そんな「わからない箇所」を特定して質問すればみんな気持ちよく答えてくれます。
「どう質問するか」も解決する為の一つのスキルだと思いました。

なので、他の掲示板で相手にされないような質問者にもその時自分が求めていたような回答をしたいと日々思っています。
今どう思っていらっしゃるかはわかりませんが、Cが楽しくない、とか、別に興味ないと思えるのは、まだまだわかって無いからなんですよね。
解りかけてくると楽しいです。その壁を頑張って乗り越えてください。

Re:カレンダーについて

Posted: 2008年1月25日(金) 23:52
by カル
論文だらけですねw毎日ご苦労様です、明日は土日なのでゆっくりしてくださいといってもまた相談や質問してしまうかもしれませんが・・・管理人さんがおっしゃる通り今は楽しくないです、まったくわからない状態なんですけどわからないなりに勉強はしてるんです。今研修中でCを勉強しています、体験みたいなやつです。
でもさっぱりで・・・・人に聞いても帰ってくる答えの意味すら理解できてないしネットで見ても・・・・あ、基礎の方は最近分かり始めました(まだ全然ですけど)

Re:カレンダーについて

Posted: 2008年1月26日(土) 00:00
by カル
連続投稿失礼します
今日やった課題で疑問に思ったのですが
1234567 1234567 1234567と数字がありましてこれを
123456712345671234567
このように並べて画面に表示させるにはどうしたらいいか
#include <stdio.h>

int main()
{
	int a, b;
	for ( b = 0; b < 1; b++ ) {
		for ( a = 0; a <= 3; a++ ) {
			printf( "1234567");
		}
		printf( "\n" );
	}
	return 0
}
珍しく成功しました。ちょっと嬉しかったですwそれで今度はこの1234567,7個の数字を3回繰り返すようにするということなのですがこれってさっきやったfor文の二重ループと同じことなんでしょうか?

Re:カレンダーについて

Posted: 2008年1月26日(土) 00:23
by box
そのコードの場合、変数bに関するループは
不要であることがおわかりになりますか?

Re:カレンダーについて

Posted: 2008年1月26日(土) 00:26
by 管理人
大学までまた来て見ました。

まず、プログラムについてですが、
お喜びのところ水を差すようですが、、、二重ループの意味が無いです。
外側のfor文を消しても同じ結果になることでしょう。
for ( b = 0; b < 1; b++ ) {
ってことは1回しか通らないからです。
もしやるならこうでしょう。
#include <stdio.h>

int main()
{
	int a, b;
	for ( b = 0; b < 3; b++ ) {
		for ( a = 1; a <= 7; a++ ) {
			printf("%d",a);
		}
	}
	printf( "\n" );
	return 0;
}
 
 
%dで値が表示できることはおkでしょうか?
あと、次の課題として出されている「1234567,7個の数字を3回繰り返すようにするということなのですが」という課題は
どういうことでしょう?

Re:カレンダーについて

Posted: 2008年1月26日(土) 02:37
by カル
確かに一回しか通ってないですね
うわぁbのループ意味ないよ・・orz
boxさん、指摘ありがとうございます。


なるほど、管理人さんの言うとおりですね
説明不測でした

今日出された課題は先ほど言った1,2,3,4,5,6,7 1,2,3,4,5,6,7 1,2,3,4,5,6,7
これを123456712345671234567と並べて表示させる
そこで私は例の無意味なループを使ったコードで担当の人に見せました
「確かに出てはいるけどコレの意味がないよね」と言われました(無意味なループの件)
この時わたしはその意味を理解していませんでした
で、今度は1,2,3,4,5,6,7 この一つ一つの数字全部で7個あります
これをfor文2つ使って7個表示させるのを3回繰り返せ
と言われました。for文2つ使ってなのでおそらく「二重ループを使って出せ」と言ってると思うのですが
私はこの時点でまだ無意味なコードに気付いていなかったので「なんでもっかい同じ事するの?」
と思ったんです。
説明ヘタですいません、これでいいでしょうか?

Re:カレンダーについて

Posted: 2008年1月26日(土) 03:00
by 管理人
え~と、、、それは先ほど私が書いたコードじゃダメなんでしょうか??
for文を二回使って「123456712345671234567」ですよね??
出来てると思うんですが。

あ、それとも、
理解したし、解決したけど、先ほどの補足だけしていただいたのでしょうか?

もしまだ未解決で、
あの方法がいやなら、やる方法はいくらでもあります。
先ほど紹介した

#include <stdio.h>
int main(){
	for ( int b = 0; b < 3; b++ )
		for ( int a = 1; a <= 7; a++ )
			printf("%d",a);
	return 0;
}

これ以外にも


#include <stdio.h>
int main(){
	for ( int b = 0; b < 3; b++ )
		for ( int a = 1; a <= 7; a++ )
			printf("%c",'0'+a);
	return 0;
}

他にもこんなのとか


#include <stdio.h>
int main(){
	char str[8]="1234567";
	for ( int b = 0; b < 3; b++ )
		for ( int a = 1; a <= 7; a++ )
			printf("%c",str[a-1]);
	return 0;
}

ひねくれてこんなのとかも


#include <stdio.h>
int main(){
	int t=0;
	char str[8]="1234567";
	for ( int b = 0; b < 100000000; b++ ){
		for ( int a = 1; a <= 100000000; a++,t++ ){
			printf("%c",str[t%7]);
			if(t==7*3-1)
				return 0;
		}
	}
	return 0;
}

アドレス使えばこんなのとか


#include <stdio.h>
int main(){
	char str[8]="0000000";
	for ( int b = 0; b < 3; b++ )
		for ( int a = 1; a <= 7; a++)
			printf("%d",(&str[a-1]-&str[0])+1);
	return 0;
}


やり方しだいでいくらでも出来ます。
一応どれも出力は「123456712345671234567」です。
求められている答えは①だと思います。
研修中ってことはお仕事ですか?
家ではネットが繋がらないのでしばし家からは携帯でこちら来ますので(_ _|||)

Re:カレンダーについて

Posted: 2008年1月26日(土) 10:02
by やそ
うわ、なんだか、別の展開になってますね(笑)

私も、C言語初心者と言えば初心者なので、「プログラムが分からない」という気持ちは十分理解できます。
プログラムを習い始めたばかりの頃は・・・
「何だこの呪文の羅列は?」、
「意味のなさそうなこの命令は一体何のため?」、
などとちんぷんかんぷんでした。
問題文を読んでも一向にアルゴリズムが構築できなくて(イメージすら湧かない)誰かに質問しようにも、「一体全体なにをどうしていいやら分かりません」としか言えなかった(ココでいう丸投げ状態ですね(笑))記憶があります。

なので、出来る限り、答えてあげたいと言う気持ちは十分あるのですが、
どこまで答えるのがいいのだろう?(管理人さんやboxさんら古強者(ベテラン)勢には敵うべくもありませぬが^^;)
と、自問自答しつつ、自分の知識&経験の及ぶ範囲内で答えているつもりです。
丸投げのように見える投稿でも、自身の経験を踏まえて、何が分からないのか、どのように質問すればよいのか、を導き出して上げられればいいなと思っています。(その日の気分により多少口調などは違ってしまうかもしれませんが^^;)

自身、C言語は専門学生時代にAI研究で使用したくらいなのでリハビリが大変です^^;
Z80マシン語(アセンブラ)やBASIC、COBOL、CASL(情報処理試験対策で覚えた)辺りを中学生頃からやっているのでプログラムそのものについては多少知識なり経験なりあると思います。
そのへんの経験が活かせられればいいのですが^^


さて、今回のプログラムですが、
今日出された課題は先ほど言った1,2,3,4,5,6,7 1,2,3,4,5,6,7 1,2,3,4,5,6,7
これを123456712345671234567と並べて表示させる
これをfor文2つ使って7個表示させるのを3回繰り返せ

という問題のようですが、
管理人さんの紹介された①
①
#include <stdio.h>
int main(){
	for ( int b = 0; b < 3; b++ )
		for ( int a = 1; a <= 7; a++ )
			printf("%d",a);
	return 0;
}
がシンプルな形で分かりやすいのではないでしょうか。
また、出題者の意図(イメージ)もこのようなループ構造だと思いますよ。

Re:カレンダーについて

Posted: 2008年1月26日(土) 15:36
by カル
ですね、私もやそさんや管理人さんがおっしゃってる①が近い回答だと思います
私がループの仕組みを完全に把握していなかったから
担当さんもあの課題を出してくれたんだと思います
気付かせてくれてありがとうございました
これからは質問内容をよく確認してから投稿しますね。
>管理人さんへ
いろんなやり方ってあるんですね、勉強になります
意図と答えは理解できたのでさっきのは捕捉です
仕事といえばそうですね、研修して勉強してる感じなので
携帯からわざわざありがとうございました。
>やそさんへ
「何がわからないのか、どのように質問すればいいのか」
ここらへんをよく考えていませんでした・・・
これからは意識しつつ質問していきたいと思います。

Re:カレンダーについて

Posted: 2008年1月27日(日) 19:46
by カル
質問なのですが、管理人さんが作ってくれたプログラムで
void display(int day, int total_day){
このvoidというのは実行後、結果を報告しない(値を戻さない)と
書いてあったのですがどういう意味なのでしょうか?

Re:カレンダーについて

Posted: 2008年1月28日(月) 04:46
by 管理人
関数を呼ぶということについてはもうOKでしょうか。
#include <stdio.h>

int display(){
	printf("表示して終わり\n");
	return 0;
}

int main(){
	int a;
	display();
	printf("mainでも表示しちゃいます\n");
	return 0;
}

これすんなり理解できますか?
メインから始まったプログラムはdisplay関数を呼び、そちらの関数にうつって、
return 0にて、関数終了の合図をうけると、メインに戻り、
メインでprintfした後、returnが呼ばれて終了しますね。
return という言葉からして、何かを返すわけですが、
これは関数が終了したときに、呼んだところに何か返すわけです。

return 0;

というのは、呼んできたところに、0を返すというわけです。
ですから、

return 1;

と書けば、よんできたところに、1を返します。
違うサンプルを見てみましょう。

#include <stdio.h>

int display(){
	printf("表示して終わり\n");
	return 1;
}

int main(){
	int a;
	a=display();
	printf("貰ってきたのは%d\n",a);
	return 0;
}

実行結果

表示して終わり
貰ってきたのは1


呼んできたところに1を返すので、aには1が返ります。
何でこんなことが必要かというと、その関数がどういう状態で終わったのか知るためです。
このdisplay関数内で、もし異常が発生したとき、return -1;を返すように書いておけば、
メイン内で-1が返ってきたら、この関数は途中でエラーを起こしたなと言うことがわかるわけです。
この関数の最初につける

int display(){

のintというのは、返り値の型のことです。double型で返したいならdoubleで、structならstructで表します。

一方、void型というのは、何も値を返さないことです。
一番上のサンプルのような場合、途中でエラーが起きる可能性もありませんし、
特に関数がどういう状態で終わったか知りたくないですね。
別に返り値がいらないときは、返り値を持たないと言う意味のvoidと書くわけです。

Re:カレンダーについて

Posted: 2008年1月28日(月) 17:52
by カル
なるほど、メイン関数からよんでいくんですね
よく見たらすごい初歩的なことでした・・・・。

Re:カレンダーについて

Posted: 2008年1月28日(月) 20:22
by カル
続いて質問です
char str_day[7][3]={"日","月","火","水","木","金","土"}
これって2次元配列だと思うんですけど
このプログラムは何を意味してるのでしょうか。

Re:カレンダーについて

Posted: 2008年1月29日(火) 01:04
by 通りすがり
何が聞きたいのかよくわかりませんが、初歩的な疑問は「C言語 入門」で検索すれば解決しますし、
解らないことがあるたびに人に聞かずに自分で解決するのもまたそれも力だと思います。
今回の場合、配列と文字列あたりをキーワードにおしらべ下さい。

Re:カレンダーについて

Posted: 2008年1月30日(水) 16:43
by やそ
char str_day[7][3]={"日","月","火","水","木","金","土"};


ですが、かなり前から使っていたのに、今頃質問ですかっ!?
っていうツッコミはお約束として(笑)
その曜日を表示するソースが以下になっていましたね?
for(i=0;i<7;i++)
		printf("%s ",str_day);
	printf("\n");


char型で宣言してますが、
printf関数では%sの【文字列】として表示していますよね。
ココから何が考えられると思いますか?

str_day[7][3]={"日","月","火","水","木","金","土"};
がどのようにメモリに格納されているかを考えてみれば分かります。

str_day[0][0]="日"
のメモリアドレスを10000とする。(仮)
と・・・

address:10000 0xFA
        10001 0x93
        10002 0x00


というように一文字3バイトで格納されているのです。
漢字は2バイトで表現されているのはご存知ですよね?
そこに、文字列の終端文字である"\0"を追加しています。
でないと%sで表示しようとしたときにバグを起こします。(終端文字を探して三千里?)



どうでしょうか?(笑)

Re:カレンダーについて

Posted: 2008年1月30日(水) 22:29
by box
> char str_day[7][3]={"日","月","火","水","木","金","土"};

カルさんご自身は、このトピックにおいて
配列の配列を使ったコードを投稿なさっていません。
ポインタの配列はお使いでしたけれど。

Re:カレンダーについて

Posted: 2008年2月05日(火) 00:15
by カル
スイマセン、PCの調子が悪くて・・・カキコできませんでした
多分あともうちょっとで分かりそうなので調べて考えてみます
通りすがりさん、やそさんboxさんありがとうございました。