++と +1,および関数のインクリメントについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Rum
記事: 3
登録日時: 10ヶ月前

++と +1,および関数のインクリメントについて

#1

投稿記事 by Rum » 10ヶ月前

C言語を勉強し始めて,一か月がたとうとしている者です。
任意の年月を入力して,その時のカレンダーを出力するというプログラムを作成しています。

参考書のコードを写して考えていたのですが,わからないことが2つありました。

 コードでは先にインクリメントしているのですが,後にインクリメントするとカレンダーが崩れてしまいました。また,後に+1するとさらにカレンダーが崩れてしまいました。
そこで,このコードにおいて先にインクリメントすることと後にインクリメントすることの違いというのは何ですか? そして,インクリメントすることと+1することのちがいとは何ですか?


 dayofweek関数ツェラーの公式を使って,曜日を求めています。その関数を変数wdに置き換えて使っていました。 直接この関数を入れると,エラーとなりました。
関数をインクリメントすることはできないのでしょうか?

なお,質問しているところは二か所とも(/* Q */)のところです。

長くなってしまってごめんなさい。 よろしくお願いします。

コード:

#include <stdio.h>
/*---各月の日数---*/
int mday[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
/*---年月日の曜日を求める---*/
int dayofweek(int year, int month, int day)
{
	if (month == 1 || month == 2)
	{
		year--;
		month += 12;
	}
	return (year + year / 4 - year / 100 + year / 400 + (13 * month + 5) / 5 + day) % 7; //ツェラーの公式(決めた年月の曜日を計算する)


}
/*---うるう年を計算---*/
int is_leap(int year)
{
	return year / 4 && year / 100 != 0 || year / 400 == 0;

}
/*---年月の日数計算---*/
int monthdays(int year, int month)
{
	if (month-- != 2)									//二月以外の時
	{
		return mday[month];
	}
	return mday[month] + is_leap(year);					//二月の時
}
/*---年月のカレンダーを表示---*/
void put_calender(int y, int m)							//選択した年月を引数で持ってくる
{
	int i;
	int wd = dayofweek(y, m, 1);						//y年m月1日の曜日を求める(0~6で返ってくる)
	int days = monthdays(y, m);							//y年m月の日数を求める

	printf("San Mon Tue Wed Thu Fri Sat\n");
	printf("---------------------------\n");

	printf("%*s", 4 * wd, "");							//ついたち前の曜日を空欄にする
							  
	for (i = 1; i <= days; i++)							//その月の曜日を出力する
	{
		printf("%3d ", i);								//土曜日になったら 改行
		if (++wd % 7 == 0)				/* Q */
		{
			putchar('\n');
		}
	}
	if (wd % 7 != 0)					//カレンダーの一番最後の日付けで 改行
	{
		putchar('\n');
	}
}

int main(void)
{
	int y, m;

	printf("カレンダーを表示します。");
	printf("Year\n");
	scanf_s("%d", &y);
	printf("Month\n");
	scanf_s("%d", &m);

	putchar('\n');

	put_calender(y, m);
}

box
記事: 1745
登録日時: 9年前

Re: ++と +1,および関数のインクリメントについて

#2

投稿記事 by box » 10ヶ月前

コード:

    return year / 4 && year / 100 != 0 || year / 400 == 0;
本題とそれてしまって申し訳ありませんが、この閏年の判定って
間違ってませんか?
私はこう書きます。

コード:

    return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
あたっしゅ
記事: 261
登録日時: 9年前
住所: 東京23区
連絡を取る:

Re: ++と +1,および関数のインクリメントについて

#3

投稿記事 by あたっしゅ » 10ヶ月前

(1) if(++wd % 7 == 0) は、

wd = wd +1;
if(wd % 7 == 0)


また、 if((wd++)% 7 == 0) は、

if(wd % 7 == 0)
{
}
wd = wd +1;


「足してから、判断する」と「判断してから、足す」の違い。

http://www.ohshiro.tuis.ac.jp/~ohshiro/ ... ncdec.html
++演算子と--演算子(ja)


>また,後に+1するとさらにカレンダーが崩れてしまいました。

「後に」ではなく、正確にコードで示してください。

(2) if (++dayofweek(y, m, 1) % 7 == 0) こんな風に書いたのかな ?
++演算子は、変数に対してじゃないと、使えないようです。
書くとしたら、if ((dayofweek(y, m, 1)+1) % 7 == 0) { ですが、
wd を後に使っているのでif ((wd = dayofweek(y, m, 1)+1) % 7 == 0)
ですかね。
手提鞄あたっしゅ、[MrAtassyu] http://ameblo.jp/mratassyu/
手提鞄屋魚有店(てさげかばんやうおありてん)
レスがついていないものを優先して、レスしています。時々、見当外れなレスをします。

アバター
あたっしゅ
記事: 261
登録日時: 9年前
住所: 東京23区
連絡を取る:

Re: ++と +1,および関数のインクリメントについて

#4

投稿記事 by あたっしゅ » 10ヶ月前

追加:

 昔は、人間が読みにくくても、短く書くのが、カッコいい、みたいな風潮がありました。今でも、このコードのように、昔のコードが使い回されているので、読めるようには、しておいてください。

 今、新たに書くなら、人間が読みやすいように、書いてください。
手提鞄あたっしゅ、[MrAtassyu] http://ameblo.jp/mratassyu/
手提鞄屋魚有店(てさげかばんやうおありてん)
レスがついていないものを優先して、レスしています。時々、見当外れなレスをします。

Rum
記事: 3
登録日時: 10ヶ月前

Re: ++と +1,および関数のインクリメントについて

#5

投稿記事 by Rum » 10ヶ月前

boxさん
 ご指摘ありがとうございます。
間違えていました。

ありがとうございます。

Rum
記事: 3
登録日時: 10ヶ月前

Re: ++と +1,および関数のインクリメントについて

#6

投稿記事 by Rum » 10ヶ月前

あたっしゅさん
 返信ありがとうございます。
(1)で
if(++wd % 7 == 0)と if((wd++)% 7 == 0)のちがいが

wd = wd +1;
if(wd % 7 == 0)



if(wd % 7 == 0)
{
}
wd = wd +1

で理解できました。

また,
++演算子が変数で使えることもわかりました。
ありがとうございます。

C言語を学んでまだ日が浅く,あまり多くのコードを見てきていないので,昔のようなコードや新たなコードなどがあること自体初めて知りました。
今後,数多くのコードに目を通して,人が読みやすいコードを学習していきます。

ありがとうございました。

かずま

Re: ++と +1,および関数のインクリメントについて

#7

投稿記事 by かずま » 10ヶ月前

box さんが書きました:
10ヶ月前
私はこう書きます。

コード:

    return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
それでも間違いではありませんが、
4 で割り切れない時はすぐに平年だと分かるのに
400 での割り算を必ず実行してしまいます。

次のように書けば、多くの場合、割り算は 1回だけで済みます。

コード:

	return (year % 4 == 0) && ((year % 100 != 0)) || (year % 400 == 0));

返信

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