home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / PNL001.ZIP / PNL001.TXT
Encoding:
Text File  |  1990-04-21  |  24.5 KB  |  1,057 lines

  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.                                   Pascal NewsLetter         
  31.                                        Issue #1              
  32.                                       May, 1990             
  33.                                                             
  34.                                                             
  35.                                   Editor: Pete Davis         
  36.                                                             
  37.                                                             
  38.                                                             
  39.                                                             
  40.                                                             
  41.                                                             
  42.                                                             
  43.                                                             
  44.                                                             
  45.                                                             
  46.                                                             
  47.                                                             
  48.                                                             
  49.                                                             
  50.                                                             
  51.                                                                 
  52.                     The Programmer's Forum BBS is the home of
  53.                     PNL. It can be reached in Washington, DC at
  54.                     (202)966-3647. Information is available 
  55.                     through the following locations:        
  56.                                                             
  57.                     FidoNet: Pete Davis@1:109/138           
  58.                     GEnie: PDAVIS5                          
  59.                     BitNet: HJ647C@GWUVM & UE356C@GWUVM     
  60.                                                                 
  61.                                                             
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.  
  76.                                                             
  77.                                                             
  78.                                                             
  79.                                 Table Of Contents           
  80.                                                             
  81.                                                             
  82.                                                             
  83.           Introduction .......................... Page 3  (Pete Davis)
  84.           Generic Structures in Turbo Pascal .... Page 5  (Pete Davis)
  85.           Turbo Pascal Program Optimization ..... Page 10 (Pete Davis)
  86.           Conclusion ............................ Page 16 (Pete Davis)
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.                                                
  110.           Turbo Pascal is a Registered Tradmark of Borland
  111.           International.
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144.                                   Introduction
  145.  
  146.  
  147.  
  148.                Well, welcome to the  premier issue of the Pascal  News
  149.  
  150.           Letter. Since this is  the first issue, it's  important that
  151.  
  152.           the purpose of  the newsletter be  stated. I run a  bulletin
  153.  
  154.           board in Washington, and I often come across newsletters and
  155.  
  156.           magazine. I  have yet  to  find any  geared towards  Pascal,
  157.  
  158.           though.  (Save  for a  few  which  aren't really  worthy  of
  159.  
  160.           mention.)  Because  I  use  Pascal  quite  often,  I  became
  161.  
  162.           frustrated that there  wasn't a free source  of information.
  163.  
  164.           Sure, I could  go out and buy some magazines that are Pascal
  165.  
  166.           oriented, but  when there  are newsletters  like CNews,  and
  167.  
  168.           MicroCornucopia  about,  why should  I  have to  bother with
  169.  
  170.           that? There should be a Pascal oriented one. Well, now there
  171.  
  172.           is.  
  173.  
  174.                My  main purpose  with the newsletter  is to  provide a
  175.  
  176.           good place for the solutions to common problems. Many people
  177.  
  178.           have  questions regarding pascal and have  a lot of problems
  179.  
  180.           getting those questions  answered. There are  also a lot  of
  181.  
  182.           people  with  fantastic  concepts and  ideas  waiting  to be
  183.  
  184.           passed around, but  no means to  pass it around. There  will
  185.  
  186.           now be a  way. Because this is the first issue, all articles
  187.  
  188.           are written by  myself, this is also  why it might be  a bit
  189.  
  190.           skimpy. Hopefully this will improve  with further issues. It
  191.  
  192.           is my  hope that people with interesting  ideas and concepts
  193.  
  194.           will  pass them  along  to me,  preferably  with an  article
  195.  
  196.  
  197.                                                                      3
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207.  
  208.  
  209.  
  210.  
  211.  
  212.           attached.
  213.  
  214.                Most of the  articles are geared towards  Turbo Pascal.
  215.  
  216.           This is not meant as a  limitation, however. Turbo Pascal is
  217.  
  218.           about as  standard as  the IBM  compatible pascal  compilers
  219.  
  220.           get. Many of the ideas will be portable to other versions of
  221.  
  222.           pascal, if possible.
  223.  
  224.                Like many of  you, I'm sure,  I'm a busy person.  Doing
  225.  
  226.           this newsletter will  take a significant amount  of my time,
  227.  
  228.           but from  this, I would like  to explain my articles  a bit.
  229.  
  230.           Complete pieces of  code are  not always provided.  Instead,
  231.  
  232.           partial pieces of code  and algorithms will make up  a large
  233.  
  234.           part of my articles. (I am only  speaking for myself and not
  235.  
  236.           others, who in  the future may  provide full pieces of  code
  237.  
  238.           for the newsletter.) My  purpose is to get the  concepts and
  239.  
  240.           ideas across and  let you, the  reader, implement them in  a
  241.  
  242.           way that suits you.
  243.  
  244.                I am  very fond of  feedback, and  would love to  get a
  245.  
  246.           message  now and  then  about what  you, the  reader, thinks
  247.  
  248.           about PNL,  and what you would like to see in future issues.
  249.  
  250.           Please feel  free to  send your  feedback, suggestions,  and
  251.  
  252.           articles,  especially,  to any  of  the above  addresses. As
  253.  
  254.           editor,  you  may  expect several  topical  changes  to your
  255.  
  256.           articles, but nothing major.
  257.  
  258.                                               Pete Davis
  259.  
  260.                                               Editor
  261.  
  262.  
  263.  
  264.  
  265.                                                                      4
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276.  
  277.  
  278.  
  279.  
  280.                        Generic Structures in Turbo Pascal
  281.  
  282.             
  283.  
  284.                I have to  thank my  current professor, Raymond  Thomas
  285.  
  286.           for the ideas and concepts covered in this article. Although
  287.  
  288.           I had thought only  a bit about the generic  structures, his
  289.  
  290.           class forced me too look at them more closely. 
  291.  
  292.                The  structure  provided  in our  class  was  a generic
  293.  
  294.           linked list, but  the idea can  be carried out into  several
  295.  
  296.           other implementations. The  idea is to  have a unit of  code
  297.  
  298.           that  can  be re-used  for  different  types  of  data.  For
  299.  
  300.           example,  one  could  write  a   unit  that  performs  stack
  301.  
  302.           operations of POP and PUSH, but have it be able to work with
  303.  
  304.           integers, strings, real  numbers, or  even records. This  is
  305.  
  306.           very useful if you  want to write units and  distribute them
  307.  
  308.           in the public  domain or  as shareware, and  have people  be
  309.  
  310.           able to use them for themselves. Such procedures as  generic
  311.  
  312.           linked  lists, stacks,  queues,  B-Trees, sorting  routines,
  313.  
  314.           etc...
  315.  
  316.                There are several  features of  Turbo Pascal that  make
  317.  
  318.           this possible. Among them is the untyped pointer, the SizeOf
  319.  
  320.           function, the Move, GetMem, and  FreeMem procedures, and the
  321.  
  322.           untyped parameter. 
  323.  
  324.                The heart of any  generic structure is going to  be the
  325.  
  326.           source   of  information   about  the   structure  and   the
  327.  
  328.           information holder. In  our example, it  is going to be  the
  329.  
  330.           head of the stack:
  331.  
  332.  
  333.                                                                      5
  334.  
  335.  
  336.  
  337.  
  338.  
  339.  
  340.  
  341.  
  342.  
  343.  
  344.  
  345.  
  346.  
  347.  
  348.  
  349.  
  350.  
  351.           type
  352.             StackPtr = ^StackItem;
  353.             StackItem = record
  354.               NextItem : StackPtr;
  355.               DataItem : pointer;
  356.             end;
  357.  
  358.             HeadPtr = ^Header;
  359.             Header = record
  360.               Size  : word;
  361.               Top   : StackPtr;
  362.             end;
  363.  
  364.  
  365.                Now for a bit of  an explanation of our stack. For  the
  366.  
  367.           most part,  it follows  the standard  structure of  a linked
  368.  
  369.           list implementation  of a  stack. The  main differences  one
  370.  
  371.           notices are the Size (in the Header record) and DataItem (in
  372.  
  373.           the StackItem record).  Size is the  size of the data  items
  374.  
  375.           being  placed in  the stack.  This is  where  Turbo Pascal's
  376.  
  377.           SizeOf function comes  in handy. To  show how this works,  I
  378.  
  379.           will present the StackInit procedure.
  380.  
  381.  
  382.  
  383.           procedure InitStack(var H_Ptr : Header; ItemSize : word);
  384.  
  385.           begin
  386.             New(H_Ptr);
  387.             H_Ptr^.Size := ItemSize;
  388.             H_Ptr^.Top  := nil;
  389.           end;
  390.  
  391.  
  392.                A typical call to the InitStack procedure would be like
  393.  
  394.           this:
  395.  
  396.           InitStack(H, SizeOf(MyData));
  397.  
  398.  
  399.  
  400.  
  401.                                                                      6
  402.  
  403.  
  404.  
  405.  
  406.  
  407.  
  408.  
  409.  
  410.  
  411.  
  412.  
  413.  
  414.  
  415.  
  416.                Now, let's examine the  StackItem record. The  DataItem
  417.  
  418.           field provides only a generic pointer. Here is where the big
  419.  
  420.           difference between the  Generic Data Structure and  the Pre-
  421.  
  422.           Defined Data Structure  shows itself. Because DataItem  is a
  423.  
  424.           Generic pointer, it has  no size associated with it.  One is
  425.  
  426.           unable  to  use  the  New and  Dispose  procedures  for  the
  427.  
  428.           individual  data items  in the stack.  Instead, the  New and
  429.  
  430.           Dispose procedures are used to handle the StackItem records,
  431.  
  432.           while  the GetMem and FreeMem procedures  are used to handle
  433.  
  434.           the data  in those StackItem records. Here  is a sample of a
  435.  
  436.           Push procedure:
  437.  
  438.  
  439.           procedure Push(H_Ptr : Header; var Data);
  440.  
  441.           { Notice that Data is an un-typed variable }
  442.  
  443.           var
  444.             ANode : StackPtr;  { Our temporary node }
  445.  
  446.           begin
  447.             { Allocate memory for the node itself. }
  448.             New(ANode);  
  449.  
  450.             { Allocate space for the user's data and set a 
  451.               pointer to it in ANode.                      }
  452.             GetMem(ANode^.DataItem, H_Ptr^.Size);
  453.  
  454.             { Since it's a stack, and it's the newest item,
  455.               have it point to the previous top of the stack }
  456.             ANode^.NextItem := H_Ptr^.Top;
  457.  
  458.             { and have the new top point to our new node }
  459.             H_Ptr^.Top      := ANode;
  460.  
  461.             { Now physically move the data from it's current
  462.               unprotected space, and into the space acquired for it.}
  463.             Move(Data, ANode^.NextItem^, H_Ptr^.Size);
  464.           end;
  465.  
  466.  
  467.  
  468.  
  469.                                                                      7
  470.  
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484.                Ok, so now we have our Push procedure. The comments are
  485.  
  486.           a little  thick, but  they can be  removed to  make it  look
  487.  
  488.           nicer.  I don't  really think  I need  to go  into  too much
  489.  
  490.           discussion of the operations in the  Push procedure, for the
  491.  
  492.           most part they are pretty straight  forward. I would like to
  493.  
  494.           caution about  the use of  the Move procedure,  however. You
  495.  
  496.           need  to know exactly where you  are moving your data to and
  497.  
  498.           from. It  might take a little  work to get  exactly what you
  499.  
  500.           want. 
  501.  
  502.                Now,  what  good  is a  stack  that  you  can only  put
  503.  
  504.           information into, and not get any back? Not much, so here is
  505.  
  506.           the Pop procedure:
  507.  
  508.  
  509.  
  510.           procedure Pop(H_Ptr : Header; var Data);
  511.  
  512.           { It would be nice to have the Pop procedure be a function 
  513.             returning the value, but we can't return an untyped  
  514.           value                                                   }
  515.  
  516.           var
  517.             ANode : StackPtr;   { Our temporary node }
  518.  
  519.           begin
  520.             { First, make sure we're working with a
  521.               non-empty stack!                      }
  522.             if not StackEmpty(H_Ptr) then
  523.               begin
  524.               
  525.                 { Set ANode to the top of the list }
  526.                 ANode := H_Ptr^.Top;
  527.  
  528.                 { Have the Top now point to the second item
  529.                  in the list                                  }
  530.                 H_Ptr^.Top := ANode^.NextItem;
  531.  
  532.                 { Move the contents of the data to the user's
  533.                   variable.                                   }
  534.                 Move(ANode^.DataItem^, Data, H_Ptr^.Size);
  535.  
  536.  
  537.                                                                      8
  538.  
  539.  
  540.  
  541.  
  542.  
  543.  
  544.  
  545.  
  546.  
  547.  
  548.  
  549.  
  550.  
  551.  
  552.                 { Return our data's memory and our node
  553.                   itself to the heap.                         }
  554.                 FreeMem(ANode^.DataItem, H_Ptr^.Size);
  555.                 Dispose(ANode);
  556.               end
  557.             else
  558.               ... Error routine goes here ...
  559.           end;
  560.             
  561.  
  562.                Well, that just about covers  the basics of our generic
  563.  
  564.           data structure. I  left out some  of the routines, but  they
  565.  
  566.           should be  pretty easy to  add. For example,  the EmptyStack
  567.  
  568.           function would return a boolean value of true  if H_Ptr^.Top
  569.  
  570.           was nil. So, I'll  leave the rest of it to you.  There are a
  571.  
  572.           multitude  of  possibilities  and  uses   for  generic  data
  573.  
  574.           structures.  It's just  one more  way to make  your routines
  575.  
  576.           'user friendly'.
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.  
  590.  
  591.  
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.  
  601.  
  602.  
  603.  
  604.  
  605.                                                                      9
  606.  
  607.  
  608.  
  609.  
  610.  
  611.  
  612.  
  613.  
  614.  
  615.  
  616.  
  617.  
  618.  
  619.  
  620.                         Turbo Pascal Program Optimization
  621.  
  622.  
  623.  
  624.                This   article  will   cover  a   portion  of   program
  625.  
  626.           optimization in Turbo Pascal.  I say it  covers a portion of
  627.  
  628.           optimization  only  because  optimization  is  such  a  vast
  629.  
  630.           subject that it would be impossible to cover completely in a
  631.  
  632.           single  article. I  also gear it  towards Turbo  Pascal, but
  633.  
  634.           most  of  the tips  here  will  apply to  almost  all pascal
  635.  
  636.           compilers.
  637.  
  638.  
  639.  
  640.           WHERE TO OPTIMIZE:
  641.  
  642.  
  643.  
  644.                The  most  important step  in  optimizing a  program is
  645.  
  646.           deciding where to  optimize. A good programmer  is compelled
  647.  
  648.           to  optimize  as he/she  writes  the  code. This  is  a good
  649.  
  650.           programming  practice,  which  once  you  know most  of  the
  651.  
  652.           important optimizations secrets, is easy to implement as you
  653.  
  654.           code. A big  problem occurs when  you try to optimize  after
  655.  
  656.           writing the  code. The reason this is a problem is one tends
  657.  
  658.           to try to  optimize every  bit of code.  This is  incredibly
  659.  
  660.           time  consuming   and   usually   results   in   only   mild
  661.  
  662.           improvements. Knowing where to optimize, however, can save a
  663.  
  664.           lot of time in coding and a lot of time in execution. 
  665.  
  666.                There are a lot of  places where optimization will make
  667.  
  668.           huge improvements in code speed. Learning to recognize where
  669.  
  670.           your program is  spending it's  time is easy  once you  know
  671.  
  672.  
  673.                                                                     10
  674.  
  675.  
  676.  
  677.  
  678.  
  679.  
  680.  
  681.  
  682.  
  683.  
  684.  
  685.  
  686.  
  687.  
  688.           what to look  for. First of  all, loops! Loops should  stick
  689.  
  690.           out like  a sore  thumb when  optimizing a  program. A  user
  691.  
  692.           recently  came into  work  with a  program  that he  thought
  693.  
  694.           wasn't working. He  complained that  he had let  it run  for
  695.  
  696.           fifteen minutes and  still didn't get his  results. Although
  697.  
  698.           his program was  only about 20 lines of code,  it would take
  699.  
  700.           at least 2 hours to run. Why? He had 4  loops. Each loop was
  701.  
  702.           inside another loop.  That adds up pretty  quickly. Each one
  703.  
  704.           looped 100 times. Now, let's figure  out how many loops that
  705.  
  706.           is: 100 * 100 * 100 * 100 = 100,000,000 loops total. To make
  707.  
  708.           things worse, he  had some pretty heavy  calculations inside
  709.  
  710.           the inner loop.  Ok, so  loops are definitely  one place  to
  711.  
  712.           look for optimization.
  713.  
  714.                Don't just look at loops, though, look at what's inside
  715.  
  716.           a loop. Sometimes redundant data is placed inside loops that
  717.  
  718.           can  be taken out of the loop. Declaring a variable inside a
  719.  
  720.           loop that is always the same: 
  721.  
  722.           example ->
  723.  
  724.           for x:=1 to 80 do
  725.             begin
  726.               y:=1
  727.               gotoxy(x,y);
  728.               write('x');
  729.             end;
  730.  
  731.  
  732.                Here  we have the  variable y being  declared 80 times,
  733.  
  734.           while it never  changes. This  can be fixed  by declaring  y
  735.  
  736.           before  entering into  the  loop.  This  is a  very  obvious
  737.  
  738.           example, but sometimes it isn't quite so obvious.
  739.  
  740.  
  741.                                                                     11
  742.  
  743.  
  744.  
  745.  
  746.  
  747.  
  748.  
  749.  
  750.  
  751.  
  752.  
  753.  
  754.  
  755.  
  756.           SPEED vs. SIZE
  757.  
  758.  
  759.  
  760.                Optimization really  covers two areas: Speed  and Size.
  761.  
  762.           Unfortunately, optimizing for one usually ends up making the
  763.  
  764.           other  worse.  There  are  some  exceptions,  however,  like
  765.  
  766.           passing variable  parameters as opposed  to value parameters
  767.  
  768.           as we'll  cover later.  Speed  is almost  always of  primary
  769.  
  770.           importance and I will usually emphasize it. 
  771.  
  772.  
  773.  
  774.           VALUE vs. VARIABLE PARAMETERS
  775.  
  776.  
  777.  
  778.                When writing procedures or functions, there  is usually
  779.  
  780.           a  little  thought about  whether to  use variable  or value
  781.  
  782.           parameters. The normal train  of thought is that you  pass a
  783.  
  784.           variable parameter  only if  that value  will change  in the
  785.  
  786.           procedure or  function. Now lets look at  what actually goes
  787.  
  788.           on behind the scenes. When a parameter is a value parameter,
  789.  
  790.           there are  no changes made  to the  actual variable  itself.
  791.  
  792.           This means  that an exact copy  of the variable  needs to be
  793.  
  794.           made in memory. With  a character or byte value,  this isn't
  795.  
  796.           real  significant, but  what if  you're passing an  array of
  797.  
  798.           1000 integers. That means an exact  copy of 2000 bytes needs
  799.  
  800.           to be copied in memory. This not only takes time but it also
  801.  
  802.           takes up quite a bit of memory. If your routine is recursive
  803.  
  804.           or  occurs  inside a  loop,  you  are looking  at  a serious
  805.  
  806.           decrease in speed and a huge increase in memory use. One way
  807.  
  808.  
  809.                                                                     12
  810.  
  811.  
  812.  
  813.  
  814.  
  815.  
  816.  
  817.  
  818.  
  819.  
  820.  
  821.  
  822.  
  823.  
  824.           to  repair  this  is to  pass  variable  parameters whenever
  825.  
  826.           possible. There are some times when it is impossible to pass
  827.  
  828.           a  variable parameter.  In these  cases you'll be  forced to
  829.  
  830.           pass a value parameters. 
  831.  
  832.                For   those   unfamiliar   with  variable   and   value
  833.  
  834.           parameters, here are two examples:
  835.  
  836.  
  837.  
  838.           procedure ShowIt1(S : string);
  839.  
  840.           begin
  841.             write(S);
  842.           end;
  843.  
  844.           procedure ShowIt2(var S : string);
  845.  
  846.           begin
  847.             write(S);
  848.           end;
  849.  
  850.                The first procedure,  ShowIt1, uses a  value parameter.
  851.  
  852.           This means that an exact copy of the string S has to be made
  853.  
  854.           in  memory. Since a string can be up to 255 characters, this
  855.  
  856.           can add up.
  857.  
  858.                The second procedure uses a variable parameter. Instead
  859.  
  860.           of passing a complete copy of the variable, a pointer to the
  861.  
  862.           string S  itself is  passed. Since  this pointer  is only  4
  863.  
  864.           bytes long, you can make a very significant improvement.
  865.  
  866.  
  867.  
  868.           COMPILER DIRECTIVES
  869.  
  870.  
  871.  
  872.                When  testing a  new program, it  is very  important to
  873.  
  874.           have  compiler  options, such  as  range checking  and stack
  875.  
  876.  
  877.                                                                     13
  878.  
  879.  
  880.  
  881.  
  882.  
  883.  
  884.  
  885.  
  886.  
  887.  
  888.  
  889.  
  890.  
  891.  
  892.           checking active. Truth  is, though,  that these options  add
  893.  
  894.           quite a  bit  of time-consuming  code to  your programs.  Of
  895.  
  896.           course, it is good  to have them in  when writing the  first
  897.  
  898.           copy of your program, but when compiling a final version, it
  899.  
  900.           is a good idea  to disable these options. The  results are a
  901.  
  902.           significant increase in speed, and a nice cut in the size of
  903.  
  904.           the final program.
  905.  
  906.  
  907.  
  908.           IF/THEN vs. IF/THEN/ELSE vs. CASE
  909.  
  910.  
  911.  
  912.                The  last point of  optimization that  I will  cover in
  913.  
  914.           this issue is the decision structures. Here is a short piece
  915.  
  916.           of code. The variable C is type char:
  917.  
  918.  
  919.  
  920.           1>  ---- IF/THEN ----
  921.           if C = 'A' then writeln('You Win!');
  922.           if C = 'B' then writeln('You Lose!');
  923.           if C = 'C' then writeln('Tie Game!');
  924.  
  925.           2> ---- IF/THEN/ELSE ----
  926.           if C = 'A' then writeln('You Win!') else
  927.           if C = 'B' then writeln('You Lose!') else
  928.           if C = 'C' then writeln('Tie Game!');
  929.  
  930.           3> ---- CASE ----
  931.           case C of
  932.             'A' : writeln('You Win!');
  933.             'B' : writeln('You Lose!');
  934.             'C' : writeln('Tie Game);
  935.           end;
  936.  
  937.  
  938.           The first example is  the slowest of  the three. It is  also
  939.  
  940.           the  least  clear  of the  code.  It  is  rarely a  required
  941.  
  942.           structure, and can usually be  replace by the more efficient
  943.  
  944.  
  945.                                                                     14
  946.  
  947.  
  948.  
  949.  
  950.  
  951.  
  952.  
  953.  
  954.  
  955.  
  956.  
  957.  
  958.  
  959.  
  960.           IF/THEN/ELSE structure.  When possible,  though, one  should
  961.  
  962.           use the CASE structure. It is  the best method for something
  963.  
  964.           like  the  above  coding. It  is  faster  and  requires less
  965.  
  966.           memory.
  967.  
  968.  
  969.  
  970.  
  971.  
  972.  
  973.  
  974.  
  975.  
  976.  
  977.  
  978.  
  979.  
  980.  
  981.  
  982.  
  983.  
  984.  
  985.  
  986.  
  987.  
  988.  
  989.  
  990.  
  991.  
  992.  
  993.  
  994.  
  995.  
  996.  
  997.  
  998.  
  999.  
  1000.  
  1001.  
  1002.  
  1003.  
  1004.  
  1005.  
  1006.  
  1007.  
  1008.  
  1009.  
  1010.  
  1011.  
  1012.  
  1013.                                                                     15
  1014.  
  1015.  
  1016.  
  1017.  
  1018.  
  1019.  
  1020.  
  1021.  
  1022.  
  1023.  
  1024.  
  1025.  
  1026.  
  1027.  
  1028.                                    Conclusion
  1029.  
  1030.  
  1031.  
  1032.                Well, like I  said in the  beginning, this is a  little
  1033.  
  1034.           skimpy, but it  is the first  issue. I hope  to have a  more
  1035.  
  1036.           full second  issue.  If you  have  some good  ideas,  please
  1037.  
  1038.           submit them. Since this is the end of the spring semester, I
  1039.  
  1040.           will  be  looking  at  quite  a  bit  more  time  as  summer
  1041.  
  1042.           approaches.  So,  with my  extra  time and,  hopefully, your
  1043.  
  1044.           submissions,  the second and later issues  will be larger. I
  1045.  
  1046.           am  also planning on including  complete pieces of code with
  1047.  
  1048.           the newsletter itself.
  1049.  
  1050.                Please send your submissions to the addresses provided.
  1051.  
  1052.           I hope you enjoy this and I look forward to your comments!
  1053.  
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062.  
  1063.  
  1064.  
  1065.  
  1066.  
  1067.  
  1068.  
  1069.  
  1070.  
  1071.  
  1072.  
  1073.  
  1074.  
  1075.  
  1076.  
  1077.  
  1078.  
  1079.  
  1080.  
  1081.                                                                     16
  1082.  
  1083.  
  1084.  
  1085.  
  1086.  
  1087.  
  1088.  
  1089.