COBOL学习第四天

2007-08-13 COBOL语言程序随堂笔记摘要

今天没有太多的笔记,都看的老师的课件。因为讲的是表格,而且考试又不考,所以就干脆不怎么听,用一天的时间来写出了一个程序。

程序内容:获取系统当前的时间并显示出星期和当月的日历。(当前时间可以直接获取而星期需要自己用算法算出,日历采用标准格式输出。)。

最终的显示结果:

WINDOWS系统日历的对比

程序源码:

*****************星期算法所用到的公式:

*****************Year=Year%400

*****************Week=(Year+[Year/4]-[Year/100]+R[Month]+Day+C)%7

*****************R[MONTH] 03 3 6 1 4 6 2 5 0 3 5

*****************************************************************

 IDENTIFICATION DIVISION.

  PROGRAM-ID. COUTWEEK.

  AUTHOR. JIANGBI.

 ENVIRONMENT DIVISION.

 DATA DIVISION.

  WORKING-STORAGE SECTION.

 01 DATESTR PIC 9(6).

 01 YEARSTR PIC 99.

 01 MONTHSTR PIC 99.

 01 DAYSTR   PIC 99.

 01 YEARSTR2 PIC 9999.

************CHANGSHU C**************

 01 DAYNUM PIC 99.

 01 NUM PIC 9.

**RILI SHUCHU SHI HUANHANG TIAOJIAN**

 01 HUANHANG PIC 99.

 01 HHXUNHUAN PIC 9.

************MEIYUE D TIANSHU********

 01 COUNTDAY PIC 99.

******PANDUAN SHIFOU WEI RUN NIAN***

 01 SHANG4 PIC 9(4).

 01 YUSHU4 PIC 9.

 01 SHANG100 PIC 9(4).

 01 YUSHU100 PIC 99.

 01 SHANG400 PIC 9(4).

 01 YUSHU400 PIC 999.

***********ZUI HOU D  JIEGUO********

 01 WEEK PIC 9.

 01 WEEK1 PIC 999.

 01 WEEK2 PIC 99.

****************************************************

 PROCEDURE DIVISION.

***********************CONG XITONG HUODE SHIJIAN****************

 SHIJIAN.

     ACCEPT DATESTR FROM DATE.

     DISPLAY "TODAY IS :" DATESTR.

     UNSTRING DATESTR

            INTO YEARSTR, MONTHSTR, DAYSTR

        END-UNSTRING.

     STRING "20" DELIMITED BY SIZE

            YEARSTR DELIMITED BY SPACES

        INTO YEARSTR2                    

     END-STRING.

*******************CONG YONGHU HUODE SHIJIAN********************

/     ACCEPT YEARSTR2.

/     ACCEPT MONTHSTR.

/     ACCEPT DAYSTR.

***************PANDUAN SHIFOU WEI RUNNIAN***********************

     DIVIDE 4 INTO YEARSTR2 GIVING SHANG4 REMAINDER YUSHU4.

     DIVIDE 100 INTO YEARSTR2 GIVING SHANG100 REMAINDER YUSHU100.

     DIVIDE 400 INTO YEARSTR2 GIVING SHANG400 REMAINDER YUSHU400.

     IF YUSHU4 = 0 

        IF YUSHU100 NOT EQUAL TO 0 OR YUSHU400 IS EQUAL TO 0

           IF MONTHSTR < 3

           MOVE 5 TO NUM

            IF MONTHSTR = 02 MOVE 29 TO COUNTDAY

            END-IF

           END-IF

        END-IF

     ELSE MOVE 6 TO NUM 

          IF MONTHSTR = 02 MOVE 28 TO COUNTDAY

          END-IF

     END-IF.

***********************GUANYU YUEFEN D  BIANQIAN****************

     IF MONTHSTR = 01 MOVE 0 TO MONTHSTR MOVE 31 TO COUNTDAY.

     IF MONTHSTR = 02 MOVE 3 TO MONTHSTR.

     IF MONTHSTR = 03 MOVE 3 TO MONTHSTR MOVE 31 TO COUNTDAY.

     IF MONTHSTR = 04 MOVE 6 TO MONTHSTR MOVE 30 TO COUNTDAY.

     IF MONTHSTR = 05 MOVE 1 TO MONTHSTR MOVE 31 TO COUNTDAY.

     IF MONTHSTR = 06 MOVE 4 TO MONTHSTR MOVE 30 TO COUNTDAY.

     IF MONTHSTR = 07 MOVE 6 TO MONTHSTR MOVE 31 TO COUNTDAY.

     IF MONTHSTR = 08 MOVE 2 TO MONTHSTR MOVE 31 TO COUNTDAY.

     IF MONTHSTR = 09 MOVE 5 TO MONTHSTR MOVE 30 TO COUNTDAY.

     IF MONTHSTR = 10 MOVE 0 TO MONTHSTR MOVE 31 TO COUNTDAY.

     IF MONTHSTR = 11 MOVE 3 TO MONTHSTR MOVE 30 TO COUNTDAY.

     IF MONTHSTR = 12 MOVE 5 TO MONTHSTR MOVE 31 TO COUNTDAY.

*************JISHUAN XINGQI*************************************

 XINGQI.

     COMPUTE WEEK1 = ( YUSHU400 + YUSHU400 / 4 - YUSHU400 / 100 +

                     MONTHSTR + DAYSTR + NUM ).

     DIVIDE 7 INTO WEEK1 GIVING WEEK2 REMAINDER WEEK.

***************SHUCHU JINTIAN XINGQI JI*************************

 SHUCHUXINGQI.

     DISPLAY "AND THAT IS :" WITH NO ADVANCING.

     IF WEEK = 0 DISPLAY "SUNDAY".

     IF WEEK = 1 DISPLAY "MONDAY".

     IF WEEK = 2 DISPLAY "TUESDAY".

     IF WEEK = 3 DISPLAY "WEDNESDAY".

     IF WEEK = 4 DISPLAY "THURSDAY".

     IF WEEK = 5 DISPLAY "FRIDAY".

     IF WEEK = 6 DISPLAY "SATURDAY".

****************SHUCHU RILI*************************************

 MAIN.

     MOVE 01 TO DAYSTR.

     DISPLAY "SU MO TU WE TH FR SA ".

     PERFORM. XINGQI 1 TIMES.

     PERFORM. ONE WEEK TIMES.

     SUBTRACT WEEK FROM 7 GIVING HUANHANG.

     PERFORM. VARYING DAYNUM FROM 1 BY 1 UNTIL DAYNUM > COUNTDAY

          DISPLAY DAYNUM " " WITH NO ADVANCING

          PERFORM. VARYING HHXUNHUAN FROM 1 BY 1 UNTIL HHXUNHUAN > 5

               IF DAYNUM = HUANHANG

               DISPLAY " "

               ADD 7 TO HUANHANG

             END-IF

          END-PERFORM

     END-PERFORM.

     STOP RUN.

************************SHUCHU RIQI JIANGE**********************

 ONE.

      DISPLAY "   " WITH NO ADVANCING.

**********************2007-08-14*********************************

补充:关于星期算法的几种经典算法。

一:常用公式

 

W = [Y-1] + [(Y-1)/4] - [(Y-1)/100] + [(Y-1)/400] + D

 

Y是年份数,D是这一天在这一年中的累积天数,也就是这一天在这一年中是第几天。

 

二:蔡勒(Zeller)公式

 

w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1

 

公式中的符号含义如下,w:星期;c:世纪;y:年(两位数); m:月(m大于等于3,小

于等于14,即在蔡勒公式中,某年的12月要看作上一年的1314月来计算,比如20031

1日要看作2002年的131日来计算);d:日;[ ]代表取整,即只要整数部分。

 

相比于通用通用计算公式而言,蔡勒(Zeller)公式大大降低了计算的复杂度。

 

三:对蔡勒(Zeller)公式的改进

 

作者:冯思琮

相比于另外一个通用通用计算公式而言,蔡勒(Zeller)公式大大降低了计算的复杂度。

不过,笔者给出的通用计算公式似乎更加简洁(包括运算过程)。现将公式列于其下:

W=[y/4]+r (y/7)-2r(c/4)+m’+d

 

公式中的符号含义如下,r ( )代表取余,即只要余数部分;m’是m的修正数,现给出1

12月的修正数112如下:(110=6;(2311=2;(47

=55=06=38=1;(912=4(注意:在笔者给出的公式中,y为润年时

1=52=1)。其他符号与蔡勒(Zeller)公式中的含义相同。

 

四:基姆拉尔森计算公式

 

这个公式名称是我给命名的,哈哈希望大家不要见怪。

 

W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7

 

在公式中d表示日期中的日数,m表示月份数,y表示年数。

 

注意:在公式中有个与其他公式不同的地方:

 

把一月和二月看成是上一年的十三月和十四月,例:如果是2004-1-10则换算成:2003-13-10来代入公式计算。

 

花絮:程序总算是完成了但还是有很多的不足,代码写的也相当的复杂,很多的地方都透着菜味,8过俺也不担心,总会好起来的,毕竟我正用心的来学习。

下面说说这次的程序,一开始的星期算法的学习运用到代码的编写用了1个半小时,后来的很长的时间都用在了输出的显示上面。说实话这样的一个简单的输出花这么长时间真的很汗颜!汗~~8过,5天学完一门语言,毕竟有很多的东西用不熟或是更本就还不懂,所以在写这个程序的时候我尽可能的把记得住记不住只要是学过的东西都尽量的用到这个程序中,所以写的过程是写了改改了写,编译通过改后再编译,就一直持续了一天。上面的代码是其中的一种。

 在书写中,最让人恼火的就是关于日历格式的输出。

              SU MO TU WE TH FR SA.

                         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  

其中判断每月一号排在那里(我是说它前面有多少个空格,如这个日历中,1号是星期三,那它前面就必须要有三个日期位的空白)和到底什么时候换行,一共要排列几行这几个问题让我费了不少的精力。对于这几个问题,一开始的时候想了想没什么好方法,根据以前学习C等语言的经验我采用了“最简单最有效”的原则,用我最熟悉最会用最简单的语句来进行编写,所以我就用了最简单的DISPLAY直接输出和STRING UNSTRING 等最基本的语句直接进行排列和输出,对于换行的操作就直接是加7换行。这样半小时后程序写完运行调试成功。但我并不满足,因为写的实在是太简单,于是便又注释掉原由的代码进行重新的改写。这里也建议各位在编程的时候,不论你用那种语言,怎么编,希望你在编译不过,找不到错误原因,想要编写更加简练的代码或是其他什么原因而选择重新书写代码的时候,最好不要删除掉原来的代码,因为不管那代码有多差有多菜那都是你写的,是你的真实水平的体现,母不嫌儿丑,而且现在写的代码也还可以为你将要写的代码提供些思路,就算是它现在什么都帮不了你,也不要删除,日后这些都是你进步的阶梯,退一万步说,你不删除的话当你新代码写完后看见新旧代码颜色分明,加在一起又那么的长,至少会很有成就感的吧!!!哈哈,扯闲话了哈,接着说我的程序。注释掉旧代码后写新代码的过程就很痛苦了,一共尝试了8种方法,结果只有3种成功,其中包含上面代码的那一种。想用GO TO ,用了,过不了,改,还是过不了 ,再改,终于过了,但结果错误。再换用PERFORM的嵌套,写了个3重循环的PERFORM的嵌套(注意:COBOL最多只允许三重循环嵌套),结果死循环,CPU100%,花了5分钟才恢复(学校电脑太差了,可恶的四川大学!)后来又改了几遍还是死循环,才突然想起最开始在定义变量的时候,A PIC 9。结果循环的时候条件是A >9,结果肯定死的嘛!改过来后输出的结果又不对,日历的换行处理没问题了,最开始的空格又出现问题了,显示的结果不对,于是又改啊改啊,摆弄了1个小时才终于明白原来定义前面空白个数的时候我用的是系统当前的日期而不是每月的一号,所以你知道如果不是当前时间与月一号星期相同的话那输出就会是错的,知道原因后总算是顺利了些,用5分钟把代码改完了,就是上面的那个版本。后来又常识着换了几种写法,只写出一种,此时,时间下午5点,今天一共花了7个小时来做这个活!那叫一个累啊!!!

总结:可以在适当的位置加上STOP 常数 ,可以暂时的挂起程序,便于检查程序可以执行但运行结果不对的错误。

因为是菜鸟,所以这样的一个程序就花了我一天的时间,主要是对COBOL的语法规则,语句的嵌套等等内容的不熟悉以及眼高手低造成的。但一天的编写和调试,也巩固了俺的理论知识,增加了动手能力,对所学的东西真正的有了点滴的理解。所以学程序的各位啊!注重实践啊!!!好了,今天就到这里吧!累了,去休息了。

你可能感兴趣的