    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Student Code Critique Competition</title>
        <link>https://members.accu.org/index.php/articles/1015</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Student Code Critiques from CVu journal. + CVu Journal Vol 12, #3 - May 2000</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c184/">Journal Columns</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c183/">Code Critique</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c126/">123</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c183-126/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c183+126/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Student Code Critique Competition</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 06 May 2000 13:15:37 +01:00 or Sat, 06 May 2000 13:15:37 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a></h2>
</div>
<p>This is another column that I would be happy to hand on to
someone else. If you are reluctant to volunteer because you do not
think you have a ready source of student code for review, fear not
because I can provide material when needed.</p>
<p>Let me start this time with a reworking of January's problem. I
was delighted to find someone responding to my suggestion to try it
in STL. I think the result shows why I am in the camp that believes
newcomers should start with C++ and then progress to C rather than
the other way round.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e26" id="d0e26"></a>A reworking of
January's problem</h2>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e29" id="d0e29"></a>An STL Solution
from Roger Orr <tt class="email">&lt;<a href=
"mailto:rogero@howzatt.demon.co.uk">rogero@howzatt.demon.co.uk</a>&gt;</tt></h3>
</div>
<p>January's C Vu 'Student code critique' discussed a proposed C
solution to a fairly simple problem. The program read a file and
produced a list of unique items. The first item in the file was the
number of remaining items and the rest of the file contains the
space-separated items.</p>
<p>In the editorial notes the question was asked: &quot;Anyone like to
provide an answer based on an STL set?&quot; I was struck when thinking
about this by the different approach to the problem which using the
STL gives compared to a standard C solution. Let us look at a
possible solution to the problem:</p>
<pre class="programlisting">
#include &lt;set&gt;
#include &lt;string&gt;
#include &lt;algorithm&gt;
#include &lt;iterator&gt;
#include &lt;iostream&gt;
#include &lt;fstream&gt;
using namespace std; // for simplicity
int main() {
  set&lt;string&gt; tokens;
  ifstream infile( &quot;land.dat&quot;, ios::in );
  int count;
  infile &gt;&gt; count; // we ignore the count
  copy(istream_iterator&lt;string&gt;(infile),
            istream_iterator&lt;string&gt;(),
  inserter( tokens, tokens.begin() ) );
  copy( tokens.begin(), tokens.end(),
       ostream_iterator&lt;string&gt;(cout, &quot; &quot; ));
}
</pre>
<p>Now what is different compared to a &quot;traditional&quot; C solution?
Firstly there are only three lines of code (!) - a definite
simplification. This is of course because we are pulling in a lot
of code from the standard headers.</p>
<p>Hence, there are many header files included - there were only
three in the C solution. We include everything but the kitchen
sink. In fact, I got stuck when I first typed this code because I
omitted <tt class="literal">#include &lt;string&gt;</tt> and the
compiler I was using gave me a hard to decipher error message about
a missing operator - although the code worked unchanged with a
different compiler!</p>
<p>Secondly we have written no memory management code. In a C
solution there would typically be some <tt class=
"literal">#define</tt>s - to specify the maximum string length and
maybe even the maximum number of strings. These are to prevent
over-running fixed C arrays, or if using dynamic memory to make it
easier to program.</p>
<p>In the STL solution we are automatically freed from worrying
about these issues because the STL containers manage their own
memory. In fact, if the specification had, for example, required
strings over a certain length to be rejected or required all
strings to be the same length we would have to <span class=
"bold"><b>add</b></span> code to our STL solution to detect this.
The code written with the STL tends to be more generic, simply
because the STL is generic.</p>
<p>In fact I could replace the three occurrences of <tt class=
"filename">&lt;string&gt;</tt> with a different data type and
handle a similar problem with, for example, integers - or even use
a <tt class="literal">typedef</tt> for <tt class=
"classname">set&lt;string&gt;</tt> and then use the <tt class=
"type">value_type</tt> <tt class="literal">typedef</tt>. It would
be quite hard to make an equivalent change with C code.</p>
<p>Next, once I fixed the missing <tt class=
"literal">#include</tt>, this code worked first time (amazing) -
and I do not expect there are any obscure memory problems lurking
to trap me later.</p>
<p>Lastly, I do not have to remember to close or delete anything -
the objects all take care of their own tidying up. None of these
are particularly revolutionary comments, but I was struck by them
more forcefully when reflecting on the process of trying to
re-write some simple C code using the STL.</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e81" id="d0e81"></a>Competition
Result</h2>
</div>
<i><span class="remark">Prizes for this competition are provided by
Blackwells Bookshops in co-operation with Addison-Wesley. This time
there was a hundred per cent improvement in that I had two entries.
I am sure you can all do better than that. Even if you do not get
the prize, the benefit of critiquing someone else's code is
considerable.</span></i>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e86" id="d0e86"></a>Last Issue's
Code</h3>
</div>
<p>I have to process a set of files, one per employee, that
contains data about an employees working times. A typical file
would be:</p>
<pre class="screen">
Kaiser
18.12.1999 6.0 K1001 Praktikum GIP
17.12.1999 4.5 K0002 Fachbereichssitzung
19.12.1999 2.0 K1001 Vorlesung GIP
19.12.1996 3.0 K0001 Weihnachtsfeier
01.01.2000 2.5 K3001 Klausur GIP erstellen
</pre>
<p>I am required to read the data into a structure and sort it by a
bubblesort on the dates. I should also be able to generate a list
for a specific time period (e.g. provide a list from 19.12.1999
till 30.01.2000)</p>
<p>Here is the C code. As I am German, the identifiers are in that
language.</p>
<p>This is my structure in the header file:</p>
<pre class="programlisting">
/*** Datenstrukturen ***/
struct stunden {
 float std;
 char kostenstelle[6];  char datum[11];
 char name[21];  char arbeit[41];
};
/*** Globale Variablen ***/
extern struct stunden std[100];
extern int anz_daten;
</pre>
<p>Here I will read my data from a file into the structure:</p>
<pre class="programlisting">
int datei_einlesen(char datei[13]) {
FILE *pf;
  char name[21];
  pf = fopen(datei, &quot;r&quot;);
  if(!pf)  return 0;
  fscanf(pf, &quot;%s&quot;, name);
  while(!feof(pf)){
     fscanf(pf, &quot;%s %f %s&quot;, std[anz_daten].datum,
               &amp;std[anz_daten].std,
               std[anz_daten].kostenstelle);
    fgets(std[anz_daten].arbeit, 40, pf);
    if(strpbrk(std[anz_daten].arbeit, &quot;\n&quot;))          std[anz_daten].arbeit[strlen(
      std[anz_daten].arbeit)- 1] = 0;
    strcpy(std[anz_daten].name, name);
    anz_daten++;
  }
  fclose(pf);
  return 1;
}
</pre>
<p>And here I want to list a period of time:</p>
<pre class="programlisting">
void datum_zerlegen(char datum[11], int *tag
            , int *monat, int *jahr) {
  char t[3], m[3], j[5];
  strncpy(t, datum, 2);
  t[2] = 0;
  strncpy(m , datum + 3, 2);
  m[2] = 0;
  strncpy(j, datum + 6, 4);
  j[4] = 0;
  *tag = atoi(t);
  *monat = atoi(m);
  *jahr = atoi(j);
}
void zeitraum_ausgeben(char von[11], char bis[11]) {
  int x, vtag, vmonat, vjahr;
  int btag, bmonat, bjah, xtag, xmonat, xjahr;
  datum_zerlegen(von, &amp;vtag, &amp;vmonat, &amp;vjahr);
  datum_zerlegen(bis, &amp;btag, &amp;bmonat, &amp;bjahr);
  for(x = 0; x &lt; anz_daten; x++){
    datum_zerlegen(std[x].datum, &amp;xtag, &amp;xmonat, &amp;xjahr);
    if( (xjahr  &gt;= vjahr ) &amp;&amp; (xjahr  &lt;= bjahr ) 
        &amp;&amp;(xmonat &gt;= vmonat) &amp;&amp; (xmonat &lt;= bmonat) 
        &amp;&amp;(xtag   &gt;= vtag) &amp;&amp; (xtag &lt;= btag  )){
      printf(&quot;%s %5.2f %s %-10s %s\n&quot;,
            std[x].datum, std[x].std,
             std[x].kostenstelle, std[x].name,
             std[x].arbeit);
    }
  }
  printf(&quot;\n&quot;);
}
</pre></div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e109" id="d0e109"></a>The Winning
Critique from James Holland</h3>
</div>
<p>The student is not that far from getting a working program.
There are, however, one or two areas where assistance is required.
I have tried to keep the same general style adopted by the student
and to modify the program as little as possible. I have, of course,
corrected faulty code and provided comments and suggestions where
necessary.</p>
<p>The first problem I had is working out what the program is
supposed to do, as my knowledge of German is non-existent. This
turned out not to be such a great problem after all. I have kept
the German variable names as much as possible but where I have
added variables and functions I have used English names. This has
resulted in rather strange mixture of German and English, but I am
sure that the student is better at English than I am at German.</p>
<p>I have organised the various files in the following way. The
file student.c contains <tt class="function">main()</tt> that
provides a means of testing the functions provided by the student.
The student code is contained in <tt class="filename">unit1.c</tt>
with declarations in <tt class="filename">unit1.h</tt>.</p>
<p>The variables (in <tt class="filename">unit1.c</tt>) must not be
declared as <tt class="literal">extern</tt>. The keyword <tt class=
"literal">extern</tt> indicates that the declaration of <tt class=
"varname">std</tt> and <tt class="varname">anz_daten</tt> is just a
declaration and not a definition. The variables need to be defined
here and so the <tt class="literal">extern</tt> keyword is not
required. As the two variables are defined in <tt class=
"filename">unit1.c</tt> they do not have global scope. It is only
required for them to be visible in <tt class=
"filename">unit1.c</tt>. <tt class="filename">Unit1.h</tt> only
contains references required by <tt class=
"filename">student.c</tt>. This keeps the scope on variables and
functions as local as possible.</p>
<p>The job of function <tt class="function">datei_einlesen()</tt>
is to read employee data from a file and to load it into the
<tt class="varname">std</tt> array. If the file fails to open
correctly the function returns a 0. There is nothing wrong with
returning a 0 to represent failure but it is more usual to return a
1 for failure and 0 for success.</p>
<p>The function <tt class="function">datei_einlesen()</tt> contains
a <tt class="literal">while</tt> loop to detect when the end of
file has occurred and, therefore, when to stop reading data from
the file. Unfortunately, feof is set when attempting to read beyond
the last record. As the student's code stands, the body of the
<tt class="literal">while</tt> loop will be executed one too many
times. To prevent this I have made use of the <tt class=
"literal">comma</tt> operator. I have added the statement
(<tt class="function">fgets()</tt> in my case) to the test of the
<tt class="literal">while</tt> loop. Now, when a record is read, a
test is made to see if it is the end of file before the record is
processed within the body of the <tt class="literal">while</tt>
loop. In this way the correct number of records is read.</p>
<p>The modified while loop requires that a complete record be read
from the file. I have chosen to store the record in a <tt class=
"type">char</tt> array called <tt class="varname">buffer</tt>. The
individual fields now have to be extracted from a <tt class=
"type">char</tt> array rather than from the file stream. The
<tt class="function">fscan()</tt> function will, therefore, have to
be changed to <tt class="function">sscanf()</tt> and its first
parameter changes from <tt class="varname">pf</tt> to <tt class=
"varname">buffer</tt>. The <tt class="function">fgets()</tt>
function will also have to be changed. In this case <tt class=
"function">strncpy()</tt> will suffice. If the <tt class=
"varname">arbeit</tt> data is longer than 40 characters the null
terminator character will not be copied by <tt class=
"function">strncpy()</tt> and so an additional line is added to
ensure <tt class="varname">std[anz_daten].arbeit</tt> is properly
terminated.</p>
<p>Formatted input is never an easy business and there will be many
ways to achieve the same result. I have not tried to make the file
reading routing fool proof. It relies on the data file having the
correct format. Also no attempt has been made to ensure the
<tt class="varname">std</tt> array is not over written. At present,
if there are more that 100 records in the data file this will
happen.</p>
<p>The way the student removes any new line characters (<tt class=
"literal">\n</tt>) is unnecessarily complicated. The function
<tt class="function">strpbrk()</tt> returns a pointer to the
<tt class="literal">\n</tt> character if one is found, <tt class=
"literal">NULL</tt> otherwise. So it is simply a matter of testing
the pointer to see if it is <tt class="literal">NULL</tt> and if it
is not assign a <tt class="literal">\0</tt> character to the
location pointed to by the pointer.</p>
<p>Now we come to the routine that prints records within a certain
date range. Unfortunately, the method is more complicated than the
student suggests. It is not sufficient to ensure that the year,
month and day are all within their respective ranges. It is a bit
more involved. The method I have adopted is as follows. First work
out if the record date is equal to or greater than the start date.
This is achieved by considering three conditions.</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>If the record year is greater than the start year, then the
record is greater than the start date.</p>
</li>
<li>
<p>If the record year is equal to the start year and the month is
greater than the start month then the record is greater that the
start date.</p>
</li>
<li>
<p>If the record year and the record month is equal to the start
year and start month respectively and the record day is equal or
greater than the start day then the record date is equal to or
greater than the start date.</p>
</li>
</ul>
</div>
<p>If any of these tests are true then the record date is equal to
or greater than the start time. A similar series of tests is
conducted on the record date and the end date, but this time
testing to see if the record date is less than or equal to the end
date. If both conditions hold true, then the record is within
range. This idea is converted to C code as shown in the revised
<tt class="function">zeitraum_ausgeben()</tt> function.
Incidentally, the declaration of <tt class="varname">bjahr</tt> is
missing the '<tt class="literal">r</tt>' in the student's code.</p>
<p>The student states that the records are to be sorted by means of
a bubble sort. For completeness, I provide a simple bubble sort
routine. It should be noted that the bubble sort is not very
efficient and that the C library provides a much better sort
routine. I give an example of how <tt class="function">qsort()</tt>
is used to sort the employee records in descending order. To sort
in ascending order simply swap the parameters in the <tt class=
"function">compare()</tt> function.</p>
<p>When defining functions with arrays as parameters the student
includes the size of the array. It is not necessary to state the
array size as the compiler will ignore it in any case. There is an
implicit conversion from an array to a pointer which means that the
size of the array is lost to the called function. To avoid the
impression that the function knows the size of the array it is best
not to mention the size at all.</p>
<p>It is perhaps unfortunate that the student has chosen <tt class=
"varname">std</tt> as the name of an array. If the program was
compiled under a C++ compiler the name will clash with the C++
standard library namespace.</p>
<p>I hope this is of some help and I include a modified version of
the student's code.</p>
<p>[<i><span class="remark">Please note that though this is the
prize winner there is certainly room to do a code review on the
code.</span></i>]</p>
<pre class="programlisting">
#include &quot;Unit1.h&quot;
#include &lt;stdio.h&gt;
#include &lt;conio.h&gt;
#include &lt;stdlib.h&gt;
int main(void) {
  if (datei_einlesen(&quot;student.dat&quot;)) {
    puts(&quot;The file could not be&quot;
          &quot;opened.\nProgram terminated.&quot;);
    getch();
    return 1;
  }
  zeitraum_ausgeben(&quot;19.12.1999&quot;, &quot;30.01.2000&quot;);
  zeitraum_ausgeben(&quot;01.01.1900&quot;, &quot;01.01.2100&quot;);
  bouble_sort();
  zeitraum_ausgeben(&quot;01.01.1900&quot;, &quot;01.01.2100&quot;);
  quick_sort();
  zeitraum_ausgeben(&quot;01.01.1900&quot;, &quot;01.01.2100&quot;);
  getch();
  return 0;
}
</pre>
<p><tt class="filename">Unit.h</tt>:</p>
<pre class="programlisting">
#ifndef UNIT_H
#define UNIT_H
int datei_einlesen(char datei[]);
void zeitraum_ausgeben(char von[], char bis[]);
void bouble_sort(void);
void quick_sort(void);
#endif
</pre>
<p><tt class="filename">Unit.c</tt></p>
<pre class="programlisting">
/*  Program modified by James Holland */
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include &lt;stdlib.h&gt;
struct studen {
  float std;
  char kostenstelle[6];
  char datum[11];
  char name[21];
  char arbeit[41];
} std[100];
int anz_daten;
int greater(char const *, char const *);
int compare(void const *, void const *);
void datum_zerlegen(const char datum[], int *
           tag, int * monat, int * jahr);
int datei_einlesen(char datei[]) {
  FILE * pf;
  char buffer[100];
  char name[21];
  char * p;
  pf = fopen(datei, &quot;r&quot;);
  if (!pf) return 1;
  fgets(buffer, 100, pf);
  sscanf(buffer, &quot;%s&quot;, name);
  while (fgets(buffer, 100, pf), !feof(pf)) {
    sscanf(buffer, &quot;%s %f %s&quot;, 
          std[anz_daten].datum,
           &amp;std[anz_daten].std,
          std[anz_daten].kostenstelle);
    strncpy(std[anz_daten].arbeit, 
              buffer + 21, 40);
    std[anz_daten].arbeit[40] = '\0';
    p = strpbrk(std[anz_daten].arbeit, &quot;\n&quot;);
    if (p) *p = '\0';
    strcpy(std[anz_daten].name, name);
    anz_daten++;
  }
  fclose(pf);
  return 0;
}
void datum_zerlegen(char const datum[], int *
          tag, int * monat, int * jahr) {
  char t[3], m[3], j[5];
  strncpy(t, datum, 2);
  t[2] = 0;
  strncpy(m, datum + 3, 2);
  m[2] = 0;
  strncpy(j , datum + 6, 4);
  j[4] = 0;
  *tag = atoi(t);
  *monat = atoi(m);
  *jahr = atoi(j);
}
void zeitraum_ausgeben(char von[], char bis[]){
  int x, vtag, vmonat, vjahr;
  int btag, bmonat, bjahr, xtag, xmonat, xjahr;
  int a, b, c, d, e, f, g, h, i, j; 
/* Terms in the boolean expresion. */
  datum_zerlegen(von, &amp;vtag, &amp;vmonat, &amp;vjahr);
  datum_zerlegen(bis, &amp;btag, &amp;bmonat, &amp;bjahr);
  for (x = 0; x &lt; anz_daten; x++)   {
    datum_zerlegen(std[x].datum, &amp;xtag, 
                 &amp;xmonat, &amp;xjahr);
    a= xjahr &gt; vjahr;  /* x.year&gt;start.year*/
    b= xjahr == vjahr;  /* x.year==start.year*/
    c= xmonat &gt; vmonat;  /* x.month&gt;start.month*/
    d= xmonat == vmonat;  /* x.month==start.month*/
    e= xtag &gt;= vtag;  /* x.day &gt;= start.day */
    f= xjahr &lt; bjahr;  /* x.year&lt;end.year */
    g= xjahr == bjahr;  /* x.year ==end.year*/
    h= xmonat &lt; bmonat;  /* x.month&lt;end.month*/
    i= xmonat == bmonat;  /* x.month==end.month*/
    j = xtag &gt;= btag;  /* x.day &gt;= end.day */
    if ((a || b &amp;&amp; (c || d &amp;&amp; e)) &amp;&amp; 
            (f || g &amp;&amp; (h || i &amp;&amp; j))){
      printf(&quot;%s %5.6f %s %-10s %s\n&quot;,
            std[x].datum, std[x].std, 
            std[x].kostenstelle,
             std[x].name, 
            std[x].arbeit);
    }
  }
  printf(&quot;\n&quot;);
}
void bouble_sort(void) {
  int a, b;
  struct studen temp;
  for (a = 1; a &lt; anz_daten; ++a) {
    for (b = anz_daten - 1; b &gt;= a; --b) {
      if (greater(std[b-1].datum, std[b].datum)) {
        temp = std[b-1];
        std[b-1] = std[b];
        std[b] = temp;
      }
    }
  }
}
int greater(char const * s1, char const* s2) {
  int vtag, vmonat, vjahr;
  int xtag, xmonat, xjahr;
  int a, b, c, d, e; 
/* Terms in the boolean expresion. */
  datum_zerlegen(s1, &amp;xtag, &amp;xmonat, &amp;xjahr);
  datum_zerlegen(s2, &amp;vtag, &amp;vmonat, &amp;vjahr);
  a = xjahr &gt; vjahr;    /* x.year&gt;start.year */
  b= xjahr == vjahr;    /* x.year== start.year*/
  c= xmonat &gt; vmonat;   /* x.month&gt;start.month */
  d= xmonat == vmonat;  /* x.month==start.month*/
  e= xtag &gt; vtag;       /* x.day &gt;= start.day */
  return a || b &amp;&amp; (c || d &amp;&amp; e);
}
void quick_sort(void) {
  qsort(std, anz_daten, sizeof std[0], compare);
}
int compare(const void * b, const void * a) {
  char const * ap = (*(struct studen *)a).datum;
  char const * bp = (*(struct studen *)b).datum;
  if (strcmp(ap, bp) == 0) return 0;
  if (greater(ap, bp)) return 1;
  return -1;
}
</pre>
<p class="c2"><span class="remark">Brett Fishburne also provided an
excellent critique which I will make avaible on our
website.</span></p>
<p class="c2"><span class="remark">If James contacts me we can
discuss his prize.</span></p>
<p>This issue's code is a little different because it is an
instructor's code. Obviously I am not goin to name names but I
thought you might like to see what some students get to work
with.</p>
<p>As always there will be a prize provided by Blackwells Bookshops
in colaboration with Addison-Wesley. By the way if other book
sellers and/or publishers would like to sponsor one of uour columns
I would be very happy to discuss it with them.</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e321" id="d0e321"></a>Student Code
Critique Competition No 4</h2>
</div>
<p><span class="bold"><b>sponsored by Blackwells Bookshops &amp;
Addison Wesley</b></span></p>
<pre class="programlisting">
// header: array.h
#ifndef _MYARRAY
#define _MYARRAY
#include &lt;assert.h&gt;
#include &lt;iostream.h&gt;
template &lt;class BType, class IType = int&gt;  
// defaults are OK here too
class Array {
protected:
  BType *arrayData;      // pointer to data
  int lobound, hibound;     // 'actual' bounds
  bool outOfRange(IType i);    
            // function to test bounds
public:
// constructor
  Array(int SZ = 16, IType lo = 0);  
// copy constructor
  Array(const Array &amp;x);     
  ~Array();          // destructor
  IType lo() const;      // return this-&gt;lobound
  IType hi() const;      // return this-&gt;hibound
// overload the [] operator
  BType&amp; operator[](IType i);    
// overload the = operator
  Array&lt;BType, IType&gt;&amp; operator= 
          (const Array&lt;BType, IType&gt; &amp;x);
  void grow(int);       // increase array size
};
// implementation
template &lt;class BType, class IType&gt;
Array&lt;BType, IType&gt;::Array(int SZ, IType lo)
       : lobound(lo), hibound(lo + SZ - 1) {
  assert(SZ &gt; 0);
  arrayData = new BType[SZ];
  assert (arrayData != 0);
}
template &lt;class BType, class IType&gt;
Array&lt;BType, IType&gt;::Array(const Array&lt;BType,
        IType&gt; &amp;x) : lobound(x.lobound),
        hibound(x.hibound) {
  arrayData = new BType[hibound - lobound + 1];
  assert (arrayData != 0);
(*this) = x; // use assignment
}
template &lt;class BType, class IType&gt;
Array&lt;BType, IType&gt;::~Array() {
  delete [] arrayData;
}
template &lt;class BType, class IType&gt;
inline IType Array&lt;BType, IType&gt;::lo() const {
  return lobound;
}
template &lt;class BType, class IType&gt;
inline IType Array&lt;BType, IType&gt;::hi() const {
    return hibound;
}
template &lt;class BType, class IType&gt;
bool Array&lt;BType, IType&gt;::outOfRange(IType i) {
  if (i &lt; lobound || i &gt; hibound) {
    cout &lt;&lt; &quot;Array index &quot; &lt;&lt; i 
        &lt;&lt; &quot; is out of range&quot; &lt;&lt; endl;
    return true;
  }
  else return false;
}
template &lt;class BType, class IType&gt;
BType&amp; Array&lt;BType, IType&gt;::operator[](IType i) {
  assert (!outOfRange(i));
  return(arrayData[i - lobound]);
}
template &lt;class BType, class IType&gt;
Array&lt;BType, IType&gt;&amp; Array&lt;BType, IType&gt; 
    ::operator=(const Array&lt;BType,IType&gt; &amp;x) {
  assert (hibound-lobound == x.hibound-x.lobound);
// arrays must be same size
  for (int i = 0; i &lt;= hibound - lobound; ++i)
    arrayData[i]=const_cast&lt;Array&lt;BType, IType&gt; 
              &amp;&gt;(x).arrayData[i];
  return *this;
}
template &lt;class BType, class IType&gt;
void Array&lt;BType, IType&gt;::grow(int newS) {
 // YOU ARE TO CODE THIS
}
#endif
</pre>
<p>The problem set by the instructor was to write the code for that
last template function. The result must compile, link and execute
with a file of code the instructor had got written. When you come
to critique the code a good place to start would be to consider the
problem the students actually have. This is the only place that
they are allowed to add code. They are not allowed to change any of
the code provided by the instructor.</p>
<p>I would like you then to look at all aspects of the code.
Remember that code provided by an instructor under the limitations
stated would be exemplar code. Do you think this is, if not why
not.</p>
<p>Would you also comment on the suitability of the problem. For
example would you develop template code this way?</p>
<p><span class="bold"><b>Entries in by June 14th.</b></span></p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
