追蹤
愛瑋斯坦の冒險日記にようこそ
關於部落格
「星屑のなかで出會えた奇跡が 」
  • 182111

    累積人氣

  • 7

    今日人氣

    23

    追蹤人氣

簡易萬年曆教學 (使用C語言)

有鑒於上篇文章似乎對我的形象造成了不小影響....(掩臉)




原本是要鼓勵大家遇到困難要勇於面對,
沒想到變成搞笑文.......嗚         (版主淚奔)




因此今天就來個教學篇提升一下我的專業形象吧~>.0y * (閃亮) 




 
 
 



---------*本文開始*----------


恩~在開始之前,請先對著本月份的月曆(開版圖也可以)觀察10秒鐘,

.
.
.
.
.
.請仔細看看數字是怎麼變化的,
.
.
.
.
.
.
.
.
.
觀察好了嗎~本文結束    (版主被拖去打)
.
.
.
.
.
.
好啦,開始認真了ˋˊ
正所謂遇到麻煩的問題時,要先簡化簡單的小問題,
我們先來試看看能不能先利用C語言去打出一個月的月曆,
因此我們可以想出第一個方法:(註:以下程式碼均使用DEV C++ 4.9.9.2版本)





法一(直接印出法):




#include <stdio.h>
 
int main()
{
    int i;
  
    printf("              2008年8月             nn");
    printf("      日   ㄧ   二   三  四  五   六 n");
    printf("                                 1   2 n");
    printf("       3   4    5   6    7   8    9 n");
    printf("     10  11  12  13  14  15  16 n");
    printf("     17  18  19  20  21  22  23 n"); 
    printf("     24  25  26  27  28  29  30 n");
    printf("     31                                n"); 
   
    printf("n");
    system("pause");
    return 0;


.
.
.
.
.
.
.
.
.
.
.
.
.

路人:!!馬上把這個版主拖出去斬了!!!  竟然拿這種白爛方法來教學,


這....明眼人一看就知道,這根本是直接印出來,毫無技巧可言阿!!!!!!  居然害老子花了20秒在這裡.....(翻桌)




(版主此時內心OS:嗚嗚....沒想到開個小玩笑也會惹來殺身之禍...)



好啦....在哈啦下去本部落格可能永遠變成搞笑版,更別說版主想轉型了...(認真)









相信比較眼尖的讀者可以觀察出三個特色.......




1.何謂「空白天數」呢? 也就是把一個月曆當成一格一格的格子來看,就會發現大多數的月份,第一天通常都不是從禮拜日開始排,因此我們可以假想成「空白天數」,這點雖然在製作一個月份的月曆來說不是很重要,但對於後面製作萬年曆來說非常重要,愛瑋我稍後解釋。




2.何謂「換行關鍵點」呢? 因為電腦這種東西其實很笨,你看到螢幕上顯示的圖式其實都是一個一個「列印」出來的,就像打字機一樣,只是速度太快讓我們以為是瞬間產生。同理,要印出一個月的天數也是一格一格印,那何時換行呢? 電腦怎麼知道要在星期六的地方換到下一行呢?請仔細看星期六那排的數字....


  2、9、16、23、30



喂喂!我可不是在報明牌嘿!!! 上次竟然有讀者把那篇「尋找質數」裡面的數字當成大樂透明牌使用,不過效果好不好就不知道了...如果全都槓龜請不要怨恨版主我呢.....


(路人:喂喂! 你話中還不是有「這是明牌」的意味!!!)



沒錯!這些數字除以7以後的餘數都等於2,而C語言裡面剛好提供了「%」運算子(唸成mod),例如7%5=2 , 7%7=0。如此一來我們就可以利用if判斷式,如果遇到除7餘2的數字就換行,就可以達到我們要的效果了。



3.那何謂一個月之總天數呢? 這個不用解釋了吧...就是設定迴圈產生的數字列印到哪裡為止,例如本月份就31天。不過後面要找尋2月份的總天數就比較麻煩了。



因此我們有了以下程式碼:


法二:


#include <stdio.h>
 
int main()
{
    int i;
  
    printf("             2008年8月nn");
    printf("     日  ㄧ  二  三  四  五  六 n");
    printf("                       ");
    for(i=1;i<=31;i++)
    {   
         printf(" %3d",i);
        
         if(i%7==2)
         printf("n   ");
    }
    printf("n");
    system("pause");
    return 0;
}
 

以下是上面程式碼的解析圖:










-------------------------第二階段-----------------------------



說了這麼久終於可以進入正題來做萬年曆摟~!!!

為什麼我上面說「每個月之空白天數」很重要呢?
正如我們從製作單月份月曆的經驗可以知道,
只要知道了下面三點就可以印出不同月份的月曆來:
1.空白天數
2.換行關鍵點
3.總天數
其中換行關鍵點可以靠空白天數來推出,總天數除了2月份以外都式固定的,因此我們可以知道:



能夠掌握空白天數的人,就能稱霸萬年


歷阿!!!!!




1.那如何來算空白天數呢?
我們可以先找到每年第一個月的空白天數
再推算出那年每個月的空白天數」 
我們可以利用一個基準年(版主是用1900年)的1月份空白天數(1900年的第一個月空白天數為1天)當基準點,利用迴圈及下列閏年的定義找出每年的1月份空白天數
閏年:(可被4整除 且 不能被100整除) 或 可被400整除
化成C語言的寫法就是
  n%4==0   &&   n%100!=0   ||   n%400==0
 
 

2.那如何用空白天數去推出換行關鍵點呢?
仔細一看的話我們可以發現:
 若n取7的餘數  = ( 7 - 空白天數)的話即換行關鍵點
以這個月為例子的話,
空白天數=5,7-5=2
而我們換行的數字除以7的餘數正是2呢!!!






----------------------最終成品----------------------


(註:版主寫了兩個方法,不過最初想的方法是利用switch去選擇空白天數....不過又長又麻煩,既然有了陣列的概念就可以簡化許多! 以下為最終修訂版)



※不好意思之前有貼過程式碼的人會發現不能執行,版主實際再試了之後發現原來是貼文時隱藏字元造成的編譯失敗,如今已經改回可直接貼上執行瞜!

#include <stdio.h>

int main()
{
    int i,m,n,q;
    int year, month, first_space, feb_days;
   
    printf("請輸入西元");
    scanf("%d",&year);
      
    printf("請輸入月份");
    scanf("%d",&month);
   
   
    if(month<=12 && month>=1)
    {
    for(first_space=1,q=0;q<(year-1900);q++)
    {
      if(q%4==0 && q%100!=0 || q%400==100)
       first_space=(first_space+366)%7;
      else
       first_space=(first_space+365)%7;
     } 
    
      //計算2月天數
      if(year%4==0 && year%100!=0 || year%400==0)
       feb_days =29;
    else
       feb_days =28;
   
    
    int space[13]={0,first_space,0,0,0,0,0,0,0,0,0,0,0};  
    int days[13]={0,31,feb_days,31,30,31,30,31,31,30,31,30,31};
   


    for(i=1;i<month;i++)
    space[i+1]=(space[i]+days[i])%7;
   
   
     printf("             %d年%d月nn",year,month);
     printf("     日  一  二  三  四  五  六 n   ");
        for(m=1;m<=space[i];m++)
             printf("    ");
             
        for(n=1;n<=days[i];n++)
         {   
             printf(" %3d",n);
         
             if(n%7==(7-space[i])%7)
             printf("n   ");
          }
          
     printf("n");
     }
     system("pause");
     return 0;
    
}




以下為上面程式解析圖:(看不到可點圖放大


--------------------------本文結束-------------------------
 



後記:
阿阿啊!!!
各位讀者不好意思,
等愛瑋我回過神來又不小心打了這麼一大篇文章。。。。。
明明經過前幾次的教訓我想說盡量減短了說。。。
因為這個是版主當初學C語言第一次自己寫出來的程式...
個人覺得蠻有紀念性的ˊˇˋ
所以一不注意打太長..
好像又再次荼毒了你們的眼睛說0.0 


本人在此說聲:
下次再來喔!!!

 

(讀者:喂!!不是說抱歉喔。。)



          以上




                                ........By 愛瑋斯坦

相簿設定
標籤設定
相簿狀態