基于Win32控制臺的萬年歷的實現(上)
本程序是基于Win32控制臺的,當用戶輸入要顯示日歷的年份后,會顯示該年的每一天所對應的星期,如圖1所示。
圖1 萬年歷程序效果
1 流程圖
萬年歷程序的流程圖如1-1所示。
圖1-1 萬年歷程序流程
2 代碼實現
2.1 確定要查詢年份的1月1日
要實現指定年份中所有12個月份的顯示,就必須要確定該年份的起始日期即1月1日是星期幾。前提是公元1年1月1日為星期一,之后計算從公元1年1月1日起,到指定要查詢年份的1月1日止,這個時間段中的天數,通過該天數得到查詢年份的1月1日是星期幾。
2.1.1 獲取時間段內的天數
(1)判斷閏年
要獲取時間段內的天數,就要判斷這個時間段內哪些年份是閏年。通過一個自定義函數實現閏年的判斷,該函數的參數是指定的年份,如果指定的年份是閏年,則函數的返回值是366,否則是365。
int IsLeapYear(int year)
{
if ((year % 4 == 0) && (year % 100 != 0) || year % 400 == 0)
return 366;
else
return 365;
}
(2)獲取要顯示的年份
通過scanf_s()函數獲取輸入的年份。
int year;
printf("請輸入要顯示的年份:");
scanf_s("%d", &year);
(3)獲取總天數
在獲取了要顯示的年份之后,循環調用IsLeapYear()函數對時間段內的年份包含的天數進行判斷和累加,最后得到總天數。
int days_sum;
for (i = 1; i<y; i++)
days_sum += IsLeapyear(i);
2.1.2 判斷指定年份的1月1日是星期幾
在獲取了時間段內的總天數之后,用該天數與7(一個星期包含7天)進行取余運算,即可得到1月1日是星期幾。假設星期天的值是0,星期一的值是1,依次類推:
int start_week;
start_week = (days_sum + 1) % 7;
其中,days_sum是在“2.1.1”中獲取到的總天數,因為公元1年1月1日為星期一,即起點的值是1,所以需要對days_sum進行加1操作。
2.2 循環顯示日歷標題、星期列表及1號前的空格
從圖1中可以看到,顯示每個月份的日期時,需要顯示當前月份的名字以及星期的列表;如果當前月份的1號不是星期天,則還需要在其前面顯示空格。
通過for循環實現指定年份12個月的遍歷。
for (int i = 0; i<12; i = i + 1)
{
........
}
2.2.1 顯示日歷標題
在for循環內部,i的值即為要顯示的月份數。因此,通過以下代碼顯示日歷標題,即月份數:
printf(" %d月 \n", i + 1);
其中,i的值是從0開始,而月份是從1開始,所以需要對i進行加1操作。
2.2.2 顯示星期列表
通過printf()函數輸出字符串即可實現星期列表的顯示。
printf(" 日 一 二 三 四 五 六 \n");
printf("=============================\n");
2.2.3 顯示1號前面的空格
在“2.1.2”中提到,start_week變量表示每個月的1號是星期幾,而日歷是從星期天開始顯示的,星期天的值是0。所以,每個月的1號是星期幾,則在1號前面就顯示幾個空格。
for (int j = 0; j<start_week; j++)
printf(" ");
2.3 顯示日期
首先定義一個整形數組,該數組中包含12個元素,分別對應12個月包含的天數。之后,判斷當前月份的天數是否已經全部顯示,如果沒有全部顯示,則繼續顯示天數。
2.3.1 定義月份天數數組
int days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
if (IsLeapYear(year) == 366)
days[1] = 29;
其中,year是要顯示的年份,如果該年份是閏年,則將2月份的天數設置為29天。
2.3.2 判斷當前月份的天數是否已經全部顯示
int day_month = 1;
while (day_month <= days[i])
{
printf("%4d", day_month);
day_month++;
}
其中,i是“2.2”中12個月的循環變量;用當前顯示的天數day_month與相應月份的天數days[i]進行比較,如果顯示的天數小于等于相應月份的天數,則說明當前月份的天數沒有全部顯示,則調用printf()函數進行顯示。
2.4 判斷當前星期是否全部顯示
在顯示日歷時,一個星期為一行。因此,還需要判斷當前星期是否全部顯示,如果全部顯示,則換行后繼續顯示日期。
start_week變量表示當前日期的星期數。因此,在“2.3.2”中的while()循環中,在顯示了當前日期之后,接下來對start_week進行操作,判斷當前星期是否全部顯示。
start_week = (start_week + 1) % 7;
if (start_week == 0)
printf("\n");
start_week的值是0,則說明當前日期是星期天,此時就應該換行,開始顯示下一個星期。
#include "stdafx.h"
#include <stdio.h>
int IsLeapYear(int year)
{
if ((year % 4 == 0) && (year % 100 != 0) || year % 400 == 0)
return 366;
else
return 365;
}
int main()
{
int year;
int i, j, days_sum = 0, t = 0;
int day_month, start_week;
int days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
printf("請輸入要顯示的年份:");
scanf_s("%d", &year);
for (i = 1; i<year; i++)
days_sum += IsLeapYear(i);
start_week = (days_sum + 1) % 7;//表示該年1月1日為星期幾
if (IsLeapYear(year) == 366)
days[1] = 29;
printf("\n%d年日歷如下:\n\n", year);
for (i = 0; i<12; i = i + 1)
{
printf(" %d月 \n", i + 1);
printf(" 日 一 二 三 四 五 六 \n");
printf("=============================\n");
day_month = 1;
for (j = 0; j<start_week; j++)
printf(" ");
while (day_month <= days[i])
{
printf("%4d", day_month);
day_month++;
start_week = (start_week + 1) % 7;
if (start_week == 0)
printf("\n");
}
printf("\n\n");
}
return 0;
}
智能推薦
LeetCode-47.全排列Ⅱ、深度優先搜索
深度優先搜索 深度優先搜索(DFS)就是在每一步時對每一種可能的選擇一條道走到底,然后再回過頭嘗試另外一種選擇。 深度優先搜索的關鍵是要考慮“當前這一步”該如何做,至于“下一步”該怎么做和當前這一步的解決方法是一樣的。在進行當前步的選擇之前要確定已經做出的選擇列表,然后在剩余可供選擇的每一種可能進行遍歷,對于每一種選擇將選擇結果以及選擇狀態代入下一步...
知識點最全的數據庫面試題
來源:https://zhuanlan.zhihu.com/p/150959652 13道sql,基本上覆蓋了所有sql的核心點。 要求寫出一下SQL語句 1、查詢位于“華東”或“華南”地區的供應商的ID、公司名稱、地區、城市和電話字段的值 a. 地區=”華東” OR a.地區=”華南”; 2、查詢&l...
面向切面編程(AOP)知識總結
目錄 1.存在問題 2.AOP的概念 3.AOP應用范圍 3.AOP實現方式 4.應用舉例 5.結束語 本文在學習【老張的哲學】系列文章AOP相關章節后,自己歸納總結的筆記。 1.存在問題 最近,其它項目小組在開發的過程中遇到了一個問題,在日志記錄時,用戶明明點擊的是更新操作,可翻看記錄時卻發現是查詢操作,起初是一頭霧水,后面跟蹤該更新操作的代碼后才發現,在日志記錄時確實是寫著查詢,說到這里,大家...
猜你喜歡
集合中出現的問題
1.Java集合框架的長處? 2.集合框架中的泛型有什么長處? 3.Java集合框架的基礎接口有哪些? 4.為何Map接口不繼承Collection接口? 5.Iterater和ListIterator之間有什么差別? 6.fail-fast與fail-safe有什么差別? 7.在迭代一個集合的時候,怎樣避免ConcurrentModificationException?8.在Java中,Hash...
三元運算符引起的bug
三元運算符引起的bug 前言 延伸 總結 前言 今天測試提交了一個bug,跟蹤發現了一段代碼,初看還沒什么問題,簡易后的代碼: 這段代碼想要實現的功能是返回 細看發現后面使用的是三元運算符,這就是造成這個bug的元兇。 解決方案:使用括號括起來。 延伸 在做這個例子的時候,使用ideal,習慣性的使用sonar掃描: 這里很明顯的提醒這里表達式有問題。 總結 三元運算符格式:expression1...
利用dom4j來生成xml
xml比較常用,處理xml的方式也比較多。現在就聊聊如何用dom4j來生成xml吧 先看看效果。。。 上傳代碼: 大概說下主要步驟吧: 1.創建document對象,創建root根節點,然后通過根節點繼續生成節點。其中也可以給該節點添加屬性,復制等。 2.創建輸出流,將該對象輸出到xml文件中去。需要設置好路徑和文件名等。...
Android輪播圖原理思路分析+實現方案
來自:http://blog.csdn.net/wubihang/article/details/52512597 ListView的headerView設置為輪播圖之后結合上/下拉刷新/加載的模式成為現在大多數APP的一個必須具備的功能,對于許多初學者來說想要實現輪播圖這樣一個集線程睡眠、自動處理、替換過程中刷新UI界面的組合功能非常困難,沒有思路,感覺無從下手,去搜索各種實現方案,發現目前充斥...
Lambda的編寫和使用---java8編程實戰
目錄 1.使用匿名類來表示不同的行為來實現行為參數,代碼有點啰嗦,解決這個問題的新工具--Lambda表達式。 2.Lambda的概念 3.Lambda語法測試 4.在程序中如何使用Lambda表達式 1.使用匿名類來表示不同的行為來實現行為參數,代碼有點啰嗦,解決這個問題的新工具--Lambda表達式。 Lambda可以讓你很簡潔地表示一個行...