    <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 12</title>
        <link>https://members.accu.org/index.php/articles/1139</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 13, #5 - Oct 2001</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/c118/">135</a>
<br />

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

                    -                        <a href="https://members.accu.org/index.php/articles/c183+118/">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 12</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 03 October 2001 13:15:48 +01:00 or Wed, 03 October 2001 13:15:48 +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="d0e18" id="d0e18"></a></h2>
</div>
<p><span class="bold"><b>prizes provided by Blackwells Bookshops
&amp; Addison-Wesley</b></span></p>
<p>I had a fantastic response to last issues piece. Not only was
the number of responses the highest ever but also the quality was
outstanding with surprisingly little overlap. That is why I have
little hesitation in publishing so many. I wish that it were easier
to drag this talent into the open. I know how I hated writing
essays when I was at school, yet as I have aged I have found a
peculiar satisfaction in sharing my ideas in writing. This is
equalled by the satisfaction I get from reading the ideas and
insights of others.</p>
<p>If you want me to continue to run this item as a way of helping
my successor, you know what to do, don't you?</p>
<p>Now let me start with a contribution based on competition
10.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e29" id="d0e29"></a>Student Code
Critique 10 - Retrospective</h2>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e32" id="d0e32"></a>from Paul
Whitehead</h3>
</div>
<p>Before providing my own solution, I'd like to raise some points
about the solution presented in the August 2001 edition of C Vu.
<span class="bold"><b>Page 7 column 1:</b></span> a header file is
presented with the following points:</p>
<div class="blockquote">
<blockquote class="blockquote">
<p>iostream.h is included directly in the student header file. This
is unnecessary - the ostream class could simply be forward-declared
[<i><span class="remark">only if you have a library that provides
&lt;iosfwd&gt;, in general you are not allowed - read should not
expect to work - to forward declare C++ Standard Library components
other than by inclusion of the designated header file. This may
seem unreasonable until you realise the degree of interaction
between these components, particularly those that are templates.
Ed</span></i>] This issue turns up again with the &quot;new style&quot; C++
solution offered later on, although the solution is slightly
different; more later (point 3(d)).</p>
<p>The <tt class="constant">MAX_ENTRIES</tt> constant is not scoped
- it is a global value, similarly for the <tt class=
"literal">typedef</tt>s</p>
</blockquote>
</div>
<p><span class="bold"><b>Page 7 column 2:</b></span> a continuation
of the header and an implementation file are given, with the
following points:</p>
<div class="blockquote">
<blockquote class="blockquote">
<p>The default <tt class="classname">Student</tt> constructor is
placed inline in a header. Whilst this is perfectly valid, I do not
generally place <span class="bold"><b>any</b></span> code in header
files for the simple reason of compile-time dependencies; it is bad
enough having such dependencies on the interface only without
adding the further burden of making clients of this class also
compile-time dependant on the class implementation. One notable
exception to this is, unfortunately, template code.</p>
<p>None of the constructors make any attempt at initialising the
contained arrays to safe values. At a minimum I would have expected
something like:</p>
<pre class="programlisting">
CStudent::CStudent() : m_numGrades(0){
  ::memset(m_subj, 0, sizeof(m_subj));
  ::memset(m_score, 0, sizeof(m_score));
}
</pre>
<p>which is rather 'C'-like, but then so is the use of such an
array. There are much better solutions to be found for storage of
such data in C++ - more later.</p>
</blockquote>
</div>
<p class="c2"><span class="remark">However there are issues with
doing this in that it assumes that the types of score_t and
subjcode_t can be correctly zeroed by memset. This is not always
true; for example it is incorrect for floating point types.
Ed</span></p>
<p>Use of <tt class="literal">typedef</tt> - Francis commented on
this. The specification required that both subject and mark are
implemented as types. I understand by the use of the word &quot;type&quot;
here to mean &quot;user-defined type&quot;. Francis suggests the use of a
struct. An alternative may be the use of an enumerated type (at
least for the subject code) - which also meets the criteria of a
user-defined type.</p>
<p>The use of <tt class="literal">std::endl</tt> on a generic
<tt class="classname">ostream</tt>. The <tt class=
"classname">ostream</tt> could be a file, in which case you would
most likely not want to use <tt class="literal">std::endl</tt> as
it flushes the stream. A safer alternative is to use &quot;<tt class=
"literal">\n</tt>&quot;</p>
<p>The &quot;<tt class="methodname">add</tt>&quot; method returns an
<tt class="type">int</tt> / discussion of returning index of how
many items added. This is poor OO-design. The client of this class
should neither know nor care whether the class stores the
information in an array or any other sort of container, let alone
be given knowledge of the location (index of the entry in the array
in this case) where the data is stored. A simple <tt class=
"type">bool</tt> would prove entirely adequate. Throw an exception?
Well, why? Is it really an exceptional case or is it more a
standard case? I suspect the latter, in which case again a simple
<tt class="type">bool</tt> is more than adequate.</p>
<p>Name of method: <tt class="methodname">output</tt>. I try to
avoid such names as &quot;input&quot; and &quot;output&quot; as they are so generic
they lose all meaning in a precise context. A suggest made by
Josuttis in his book <i class="citetitle">The C++ Standard
Library</i> is to call the method something like <tt class=
"methodname">printOn()</tt>. This, to my mind, describes more
accurately what the method is trying to accomplish.</p>
<p><span class="bold"><b>Page 8, column 1:</b></span> more elegant
ways of implementing the class / use of &quot;newer&quot; C++:</p>
<p>&quot;Checking for valid input&quot; etc. If the subject codes were taken
from a fixed, pre-defined list (the assumption here is that the
number of subjects is constrained to some finite number) then the
validation for subject codes is implicit. Of course, in line with
Peter Goodliffe's article elsewhere in the same edition of C Vu,
you may wish to code an <tt class="literal">assert</tt> and/or a
run-time check to ensure that subject code does not lie out of the
expected range, although if the subject code is taken from a
pre-defined (assumedly valid) list of subject codes this case
should never arise.</p>
<p>Again, usual comments re: global typedefs, inlined default
constructor etc. (as above).</p>
<p>The author has failed to take advantage of the <tt class=
"literal">typedef</tt> <tt class="literal">subjectlist</tt> for use
in the subsequent <tt class="literal">typedef</tt> of the
<tt class="literal">subjectlist iterator</tt>. There are therefore
two points of maintenance here rather than one.</p>
<p>I did say in point 1(a) above I would return to the issue of
<tt class="literal">#include</tt> vs. forward-declared classes. Now
that the C++ Standard Library of <tt class=
"filename">&lt;iostream&gt;</tt> (as opposed to the earlier
<tt class="filename">&lt;iostream.h&gt;</tt>) is being used, the
correct technique for the header is to <tt class="literal">#include
&lt;iosfwd&gt;</tt> instead of <tt class=
"filename">&lt;iostream&gt;</tt>. The <tt class=
"filename">&lt;iosfwd&gt;</tt> header file has been built to
provide forward declarations of all the types together with their
dependencies precisely for this situation.</p>
<p>The <tt class="literal">for()</tt> loop etc. given towards the
end of the column needs tidying up. Here's the original</p>
<pre class="programlisting">
subjectiter iter = subjects.begin();
for( ; iter != subjects.end(); iter++ ) {
  os&lt;&lt;&quot;Grade:&quot; &lt;&lt;(*iter).first &lt;&lt;&quot; Score: &quot;
    &lt;&lt; (*iter).second &lt;&lt; std::endl;
</pre>
<p>Here's a tidied-up version:</p>
<pre class="programlisting">
subjectlist::const_iterator iter =
                         subjects.begin();
const subjectlist::const_iterator iterEnd = 
                         subjects.end();
while(iter != iterEnd){
  os &lt;&lt;&quot;Grade:&quot; &lt;&lt;(*iter).first &lt;&lt;&quot; Score:&quot; 
     &lt;&lt; (*iter).second &lt;&lt;&quot;\n&quot;;
  ++iter;
}
</pre>
<p>The <tt class="methodname">end()</tt> method is not repeatedly
called around the loop and the iterator type is constant as the
data held in the container is not modified. In addition, the
iterator is incremented correctly in this case by means of the
prefix, not the postfix, increment operator. The output stream is
not flushed as I'm using &quot;<tt class="literal">\n</tt>&quot; rather than
<tt class="literal">std::endl</tt>.</p>
<p>The <tt class="methodname">output()</tt> method could (and
should) be made <tt class="literal">const</tt> as it does not
modify the object.</p>
<p><span class="bold"><b>Page 8, column 2:</b></span> use of
<tt class="literal">std::vector&lt;grade_t&gt;</tt> and use the
subject code as the index into the vector. This is a poor choice
for these reasons:</p>
<p>It does not allow for subject codes being alphanumeric which is
certainly a possibility even if not now but in the future (no
information in the requirements is given on the nature of subject
codes )</p>
<p>Even if the subject codes are numeric only, it would seem
reasonable to assume that they would be allocated ranges per
department/subject area e.g. 100 - 199 for natural science 200 -
299 for engineering, 300 - 399 for languages etc. Assuming the
candidate took, say, 5 natural science courses and 5 language
courses then you would have &quot;wasted&quot; 295 entries in the array,
assuming the 5 language courses the candidate chose happened to be
numbered 300, 301, 302, 303 and 304.</p>
<p>For both these points a map would appear to be a much better
choice, keyed by subject code. Of course, there is nothing wrong
with using some other container such as a list - although finding
an entry for a given subject code is generally a comparatively slow
business.</p>
<p>&quot;<span class="quote">If the subject code must appear more than
once</span>&quot; - I would be inclined to treat this as an error
condition (and one to check for in the <tt class=
"methodname">add()</tt> method) as I think it unlikely a student
would want to be enrolled on exactly the same course twice.</p>
<p>N.B. I purposely haven't attempted to catch any exceptions as I
expect these to be handled a user of the class and that I haven't
put any <tt class="literal">throw()</tt> declarations on any
methods as my compiler doesn't support them.</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e223" id="d0e223"></a>A Solution to
Problem 10</h2>
</div>
<p><i><span class="remark">Note that Paul's code can be found at
http://www.accu.org</span></i>.</p>
<p>As per the requirement, both the <span class=
"structname">Subject</span> and <span class=
"structname">Grade</span> have been made into user-defined types
(<tt class="literal">struct</tt>s). This is, in my opinion, a
somewhat odd stipulation to be placed in the requirements
specification as the requirements should be concerned with what the
solution is required to do and not stipulate exactly how a
particular data type is to implemented. In general, the
requirements for this exercise are very vague and lacking in all
sorts of detail necessary for a satisfactory solution. During the
course of writing the proposed solution I found myself having to
make a lot of assumptions about the data and how it was going to be
used.</p>
<p>The <span class="structname">Subject</span> struct is
straightforward and consists of a <i class=
"structfield"><tt>code</tt></i> string field for the subject code,
a <i class="structfield"><tt>title</tt></i> string field which
contains the full name of the course and a <i class=
"structfield"><tt>max_mark</tt></i> field which contains the
maximum mark possible for that particular course examination. The
assumptions I had to make here were:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>the subject code could be alpha-numeric so I used a <tt class=
"type">string</tt> instead of a numeric built-in type for the
subject code</p>
</li>
<li>
<p>the subject code would be a shorthand for the real course and so
there may well be a requirement to display the full course name for
a given course code, so I added a <i class=
"structfield"><tt>title</tt></i> field</p>
</li>
<li>
<p>the maximum mark available for a given examination for a subject
may not be 100. e.g. the exam may be marked out of, say, 70 in
which case to get the percentage score for a given subject you
would need to divide the actual score by the maximum possible and
multiply by 100. Each subject may have a different maximum score
and so a maximum score per subject belongs in the <span class=
"structname">Subject</span>.</p>
</li>
</ul>
</div>
<p>None of these assumptions would have had to be made if the
requirements were more complete. Part of this &quot;coding&quot; exercise
therefore turned into trying to second-guess what was required.
This is poor practice. Requirements should never be second-guessed
as the guess is almost invariably wrong. If the requirements are
unclear, the requirements should be clarified before proceeding.
Sometimes, of course, it only becomes apparent during design or
even implementation that the requirements are unclear. In these
cases, clarification should be sought before progressing with the
code. However, this is not practical for a coding exercise in a
periodical.</p>
<p>I have made the <span class="structname">Subject</span>
constructor take three parameters to initialise all the data
members correctly. I have purposely included a default &quot;empty&quot;
constructor for use with container classes that may require a
parameterless constructor: consider:</p>
<pre class="programlisting">
std::vector&lt;Subject&gt; subjects(10);
</pre>
<p>This will call the default constructor for <span class=
"structname">Subject</span> ten times [<i><span class=
"remark">actually, no, it calls the default constructor to create a
temporary and then calls the copy constructor ten times.
Ed</span></i>] and. The member initialisation list for the default
constructor and the overloaded constructor are different. This is
because the default constructor for a <tt class=
"classname">std::string</tt> object is guaranteed to be an empty
string. It is therefore unnecessary to put <tt class=
"literal">code_(&quot;&quot;)</tt> and <tt class="literal">title_(&quot;&quot;)</tt> in
the default constructor initialisation list - especially as two
temporary <tt class="classname">std::string</tt> objects will be
created, copied and then destroyed and all with absolutely no
beneficial effect on the newly constructed object.</p>
<p>The usual header include guards have been placed in each of the
headers. I have used the convention of appending a trailing
underscore to indicate class/struct data members. Another commonly
employed method is to prepend &quot;<tt class="literal">m_</tt>&quot; to the
variable name. I have used <tt class="type">unsigned short</tt>
[<i><span class="remark">so you decided that it was all right to
multiply marks by marks? Ed</span></i>] as the data type for marks
as I have assumed that a maximum value of 2^16 - 1 will cover all
possible mark ranges. I could have typedef'ed the <tt class=
"type">unsigned short</tt> to, say, <tt class="literal">mark_t</tt>
but I did not see the need. Again, no mention was made in the
specification of valid mark ranges or whether negative marks may be
passed in. If a negative mark were passed in it would be implicitly
cast into a large unsigned value turning, in most cases, a hopeless
failure into an impossible success! If the user-interface performs
simple validation on data input then we may safely assume the data
lies in a valid range. Again, no indication in the specification is
given as to whether this is the case or not.</p>
<p>The overloaded constructor for the <span class=
"structname">Subject</span> <tt class="literal">struct</tt> uses
<tt class="literal">const</tt> references to the <tt class=
"classname">std::string</tt> class for its first two arguments. In
the case where another <tt class="classname">std::string</tt>
object is being passed, then this will ensure that a copy of the
<tt class="constant">std::string</tt> is not needlessly created.
For the case where the overloaded constructor is called with
<tt class="classname">string</tt> literals (probably the more usual
case) then two temporary string objects will be created and then a
const reference to those temporary objects will be passed as
arguments. The alternative is to use copies of the <tt class=
"classname">string</tt> objects. In this case, nothing is lost for
the string literal case as two temporary objects would need to be
created in the <tt class="literal">const</tt> reference case and
two objects will be created in the case of argument copies.
However, for the case where another string object is passed, an
unnecessary copy will be made of each of the string objects. On
balance, the use of the <tt class="literal">const</tt> reference
would appear to be the preferred one. [<i><span class=
"remark">actually, there is another option and that is to add
overloads for the various combinations of string and char* (C-style
strings). Ed.</span></i>]</p>
<p>Despite my best efforts, I could not see any more use for the
&quot;<span class="structname">Mark</span>&quot; <tt class=
"literal">struct</tt> than simply to contain a single value, which
strikes me as rather unnecessary, although it could be argued that
placing the value in a <tt class="literal">struct</tt> could be
some form of &quot;future-proofing&quot; of the data type. Still, placing the
single mark value inside a <tt class="literal">struct</tt> does at
least meet the rather odd design constraint that both &quot;<span class=
"structname">Subject</span>&quot; and &quot;<span class=
"structname">Mark</span>&quot; should be user-defined types. The
&quot;<span class="structname">Mark</span>&quot; constructor takes one
parameter which is defaulted to zero. This allows the use of an
empty constructor (e.g. as above for the <tt class=
"classname">std::vector</tt> of <span class=
"structname">Subject</span>) and it also allows the single value to
be initialised, if required, with the same single constructor
implementation. The constructor has been marked as &quot;<tt class=
"literal">explicit</tt>&quot; to stop unwanted implicit conversions.</p>
<p>[<i><span class="remark">Let me explain that requirement. Types
have appropriate behaviour. If you do not make Mark a UDT then it
has inappropriate behaviour. You may wish to live with that
initially, but in the long run you may well want to clean it up.
Programmers are often reluctant to properly encapsulate data and so
leave their data vulnerable to erroneous use. All type that have
public visibility should have correctly constrained semantics. None
of the built-in types behave correctly for marks, dates, weights
etc. Ed</span></i>]</p>
<p>Neither of the <span class="structname">Subject</span> or
<span class="structname">Mark</span> structs have user-defined copy
constructors, assignment operators or destructors as the ones
supplied by default (the canonical form) are adequate for our
purposes. The compiler-supplied destructors are non-virtual so if
it is desired to inherit from these <tt class=
"literal">struct</tt>s then a default destructor must be supplied
and marked as virtual in the <tt class="literal">struct</tt>
declaration. However, it is unlikely that <span class=
"structname">Subject</span> and <span class=
"structname">Mark</span> will be inherited from and so I allowed
the default compiler-supplied non-virtual destructor to be
used.</p>
<p>The <tt class="classname">NewStudent</tt> class is where the
proposed solution starts to get a little more interesting. The
header file contains forward declarations for all classes except
<tt class="classname">std::string</tt> because there are two
methods declared to return a <tt class="classname">std::string</tt>
by value so the full header is required. Again, a default
constructor is declared and <tt class="literal">const</tt>
references to the two <tt class="classname">std::string</tt>
arguments are also declared in the overloaded constructor for the
same reasons given above for the <span class=
"structname">Subject</span> <tt class="literal">struct</tt>. A set
of methods are declared which would appear to cover any reasonable
use of the class. Again, assumptions had to be made as the
requirement was so vague in specifying exactly what sort of
operations would be required to be made available. Perhaps the most
interesting part of the whole class is what you don't see: the only
<tt class="literal">private</tt> member is a pointer to a forward
declared class. I named the pointer member &quot;<tt class=
"varname">pImpl</tt>&quot; after one name for this technique, which is
called the &quot;pimpl idiom&quot;. It is also known as the handle/body
idiom, the letter/envelope idiom and the compiler-firewall idiom,
amongst others. I won't discuss this idiom here as it is
well-documented in the extant C++ literature.</p>
<p>I have attempted to make the <tt class=
"classname">NewStudent</tt> class (and the implementation class
thereof) as <tt class="literal">const</tt>-correct as possible. The
encapsulation of the class is keep fairly tight partly by use of
the handle/body idiom and partly by use of the <tt class=
"methodname">printOn()</tt> method. However, the encapsulation is
somewhat violated by use of accessor/mutator methods for the
properties &quot;<i class="structfield"><tt>code</tt></i>&quot; and
&quot;<i class="structfield"><tt>name</tt></i>&quot;. This is because I
wanted to provide a default, no-parameter, constructor for the
<tt class="classname">NewStudent</tt> class such that it could be
used easily in situations where a default constructor is required
(e.g. in STL container classes). Whilst this particular <tt class=
"classname">NewStudent</tt> class is not used in a container of
<tt class="classname">NewStudent</tt> by the test program it is not
difficult to foresee a situation where it may well make sense to
have a container of <tt class="classname">NewStudent</tt>.
Therefore I provided a default constructor and the accessor/mutator
methods. I would have preferred the single constructor containing
two arguments as this would enforce in code what I would like to
constrain as the semantics of using this class, namely that an
object of this must have at least a student name and student
code.</p>
<p>Unfortunately, for the reason given above, I had to provide a
default constructor which means it is legal and possible for an
object of this class to be created without giving it a student name
and student code. It is up to the user of the class to remember to
provide these two parameters afterwards if the default constructor
is used. Given that I cannot express fully the semantic use of the
class in the C++ implementation code, another mechanism would be to
rely on another part of the system (e.g. user input screen)
performing validation before a <tt class=
"classname">NewStudent</tt> object is created. This is more
nebulous than specifying/coding that constraint directly in the
class but it would enforce the semantics as part of the overall
system. The default constructor could then be called by container
classes when required.</p>
<p>For the <tt class="classname">NewStudent</tt> class I have
provided implementations of the copy constructor and assignment
operator as the <tt class="classname">NewStudent</tt> class
contains a pointer member to another class. The correct behaviour
for copying/assigning to this class from another object of the same
class is to provide a deep copy for the pointer to the <tt class=
"classname">NewStudentImpl</tt> class. The <tt class=
"classname">NewStudentImpl</tt> class itself does not need a
specialised copy constructor and/or assignment operator so the
compiler-supplied default ones will be used.</p>
<p>Depending on the requirements, it may be an option to wrap the
bare member pointer to the <tt class=
"classname">NewStudentImpl</tt> class in something like a
<tt class="classname">shared_ptr</tt> smart-pointer class from the
Boost library.</p>
<p>In general, I prefer to use the standard library algorithms for
looping over containers. However, one case where I wrote my own
loop is in the <tt class="methodname">printOn()</tt> method of
<tt class="classname">NewStudentImpl</tt>. There are two reasons
for this:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>one of the reasons the method <tt class=
"methodname">printOn()</tt> is supplied is to avoid violating
encapsulation. By providing a functor outside the scope of the
class I would have to give it &quot;friend&quot; access to the class. This is
not as bad as is usually thought: Marshall Cline makes out a
convincing case for the fact that judicious use of &quot;friend&quot; can
actually increase encapsulation rather than decrease it in his C++
FAQ. However, Josuttis discusses this very point in his book
<i class="citetitle">The C++ Standard Library</i> and the
recommendation there is to use a method such as <tt class=
"methodname">printOn()</tt> - which I have followed here.</p>
</li>
<li>
<p>in displaying the student information, I make use of some member
functions from the <tt class="classname">NewStudentImpl</tt> class.
This would mean that a functor would have to know which object it
is being called from.</p>
</li>
</ul>
</div>
<p>One final point regarding the use of <tt class=
"literal">assert</tt>: although I have <tt class=
"literal">#included&lt;cassert&gt;</tt> I have had to use
<tt class="literal">assert</tt> and not <tt class=
"literal">std::assert</tt> as I would have expected
[<i><span class="remark">The reason is that <tt class=
"literal">assert</tt> is a macro. Ed</span></i>]. This is down to
implementation of the <tt class="literal">cassert</tt> for my
compiler. I have attempted to use <tt class="literal">assert</tt>
in order to document pre-conditions for many methods: the majority
of these being simple pointer checks before de-referencing when
delegating from the <tt class="classname">NewStudent</tt> to the
<tt class="classname">NewStudentImpl</tt> class. Although I perform
a run-time check on these pointers, I also place an <tt class=
"literal">assert</tt> just before the run-time check to remind me
that by design the pointer is supposed to be non-null rather than a
run-time check which says &quot;if it's null, don't use it&quot;. The two
checks emphasise different concerns with the code.</p>
<p>This is just one implementation. No attempt has been made to
address Unicode character encodings - although this could be
achieved fairly easily by using the <tt class="type">wchar_t</tt>
version of <tt class="classname">std::basic_string</tt> and
<tt class="type">wchar_t</tt> where I have used <tt class=
"type">char</tt>.</p>
<p>Although I would hope to have met the original requirement of
providing a class to handle a set of marks and subjects for a given
student, I do not feel that the solution above is necessarily a
pragmatic one. This class of problem lends itself readily to a
database implementation, which would seem to be the most natural
way of implementing the requirements. However, I suspect a database
solution is not what is required by way of a C++ coding
exercise!</p>
<p class="c2"><span class="remark">Good student exercises are
capable of being implemented at many levels. This is a reason that
good tutors under-specify coding exercises (bad ones do so because
they do not know any better). Good students ask for further detail
or make their assumptions explicit. That exercise is valuable in
itself.</span></p>
<p class="c2"><span class="remark">To return to the issue of UDTs;
I think that much code makes poor use of these. Let me give you a
simple example. How often have you seen length (in meters, or
whatever) simply implemented as a double? Now it is quite correct
to multiply a length by a floating-point value to get a length, but
if you multiply a length by a length you get a unit of area (square
metres etc.).</span></p>
<p class="c2"><span class="remark">Much of the design of a program
is selecting and implementing (if not already done) correct types.
There are often surprises, you can subtract dates, but you cannot
add them, you can add and subtract integers from dates but you
should not subtract a date from an integer (should you be allowed
to add a date to an integer rather than the other way
round?)</span></p>
<p class="c2"><span class="remark">It is questions like these that
I would pose to my best students while allowing the weaker ones the
satisfaction of writing a simpler program that works.</span></p>
<p class="c2"><span class="remark">Then there is the issue of time
scale. A perfect solution takes an eternity, but how good is good
enough? Students should have to think about such things. These are
issues that need to be addressed, and too often are not. Good
enough for my own use is not the same as good enough for sale.
Francis</span></p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e590" id="d0e590"></a>Student Code
Critique 11 - The Entries</h2>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e593" id="d0e593"></a>Critique from
Rob Hughes</h3>
</div>
<p>Before we start to look at the code, let me briefly remind
readers what Newton's method (or the Newton-Raphson method if you
prefer) is designed to do. The method provides a means to estimate
a root of a function in n dimensions, although we will consider
only the limiting case of one dimension (i.e. one independent
variable). In other words, at its simplest, Newton's method
attempts to calculate a value of x for which f(x) = 0 is true.
Newton's method tries to evaluate a change in an approximation of x
that will produce a better estimate for the root. Expressed
differently, we seek to find a solution such that f(x + dx) = 0 to
within some arbitrary bounds. We can calculate the shift, dx, as
-f(x)/f'(x), and therefore we must calculate numerical values for
both the function and its derivative (I leave it to the
mathematically deranged to prove this to themselves).</p>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e598" id="d0e598"></a>Reverse
Engineering of the Original Code:</h4>
</div>
<p>Let us firstly consider the functionality of the code before we
address any imperfections in semantics or design. The program
begins by getting an initial approximation for the root from the
user (I will later mention some other improvements which might be
employed). The program then enters the main calculation loop. Here,
the current best guess for the root location is used to calculate a
new value for x, which is, at least in most cases, a closer
approximation to the root sought. When the best guess is precise
enough, in this case within 0.000001 of the root, checked by
comparing the deviate of the new and previous best guess, the
estimation is printed and the program terminates.</p>
<p>The bulk of the work, however, is performed within three
auxiliary functions. Firstly, <tt class=
"function">NewtonRough()</tt> calculates a new best guess for the
root, based on a previous estimate, <i class=
"parameter"><tt>x0</tt></i>, passed as an argument. It does this by
calling function <tt class="function">func()</tt> to calculate the
value of <tt class="literal">f(x)</tt> for <tt class="literal">x =
x0</tt>, and <tt class="function">derivative()</tt> to calculate
the value of the derivative for which <tt class="literal">x =
x0</tt>. The quotient of the function and derivative (<tt class=
"literal">f(x)/f'(x)</tt>) is subtracted from the previous estimate
<i class="parameter"><tt>x0</tt></i> to evaluate the new estimate,
which is returned to <tt class="function">main()</tt>. If we go
further and examine <tt class="function">func()</tt>, when we put
the various components together we find the following function is
evaluated:</p>
<p>f(x) = 25/7 * ln(3750 * (|x| ^ 0.5)) - 1/(|x| ^ 0.5) - 6.</p>
<p>The same process for <tt class="function">derivative()</tt>
shows that</p>
<p>f'(x) = 1/2x * (25/7 + 1/(|x| ^ 0.5)).</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e647" id="d0e647"></a>Corrections and
Improvements:</h4>
</div>
<p>To improve upon the code as set, I will present two programs;
the first will correct some of the immediate problems with the
code, and the second will show a more robust and flexible version
to give a taste of what might be achieved with a little further
work. I will also state up front, that the code is (I hope)
compliant with C89, but doesn't attempt to use any new C99
features. I only have a passing knowledge of C99 having not worked
with C in anger for a couple of years.</p>
<p>I have not, by and large, commented on spacing issues as it
seems clear that this is mostly to fit the code onto the page, and
in any case is largely a matter of preference. I will mention,
however, a couple of details where I am not certain if it is just
publication issue. So onto the code and some specifics, the first
program is given in <tt class="filename">newton1.h</tt>:</p>
<pre class="programlisting">
#ifndef NEWTON1_H
#define NEWTON1_H
#define PRECISION 1E-6
#define MAX_TRIES 30
#define INPUT_BUFFER_LEN 50
#define CONSTANT1 25.0 / 7.0
#define CONSTANT2 3750.0
#define CONSTANT3 6.0
#define CONSTANT4 2.0
double Func(const double current_gues );
double Derivative(const double current_guess);
double Reciprocal(const double val_to_recip);
void NewtonMethod(double current_guess );
double GetNumber(void );
#endif
</pre>
<p>and <tt class="filename">newton1.c</tt></p>
<pre class="programlisting">
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;math.h&gt;
#include &lt;errno.h&gt;
#include &quot;newton1.h&quot;
int main(void){
  double current_guess = 0;
  printf(&quot;Enter an estimate of the root\n&gt; &quot;);
  current_guess = GetDouble();
  NewtonMethod( current_guess );
  return (EXIT_SUCCESS);
}
void NewtonMethod(double current_guess){
  int tries = 1;
  double next_guess = 0;
  for(tries = 1; tries &lt;= MAX_TRIES; tries++){
    errno = 0;
    next_guess = current_guess - (Func(current_guess)/Derivative(current_guess));
    if(errno == EDOM) {
      perror(&quot;Domain error encountered calculating next root estimate\n&quot;);
      break;
    } else if(errno == ERANGE) {
      perror(&quot;Range error encountered calculating next root estimate\n&quot;);
      break;
    } else if (errno != 0 ) {
      perror(&quot;Unexpected error encountered calculating next root estimate\n&quot;);
      break;
    }
    if(fabs(next_guess - current_guess) 
                  &lt; PRECISION) {
      printf(&quot;Estimation of root %f\n&quot;, next_guess);
      break;
    } else if( tries == MAX_TRIES ) {
      printf(&quot;Failed to reach convergence after %d attempts\n&quot;, MAX_TRIES);
      break;
    }
    current_guess = next_guess;
  }
}
double Func(const double current_guess){
  double positive_sq_root = 
              sqrt(fabs(current_guess));
  double ln_eval = log(CONSTANT2 
                  * positive_sq_root);
  return ((CONSTANT1 * ln_eval ) -
  (Reciprocal(positive_sq_root)) - CONSTANT3);
}
double Derivative(const double current_guess){
  double factor = Reciprocal(CONSTANT4 
                    * current_guess);
  double reciprocal_root = 
    Reciprocal(sqrt(fabs(current_guess)));
  return((factor * CONSTANT1) + reciprocal_root);
}
double Reciprocal(const double val_to_recip){
  if(val_to_recip == 0) {
    errno = EDOM;
    return ( HUGE_VAL );
  }
  return (1.0/val_to_recip);
}
double GetDouble(void){
  char number_buf[INPUT_BUFFER_LEN];
  char * end_ptr = number_buf;
  double user_value = 0;
  while (1) {
    fgets(number_buf, INPUT_BUFFER_LEN, stdin);
    errno = 0;
    user_value = strtod(number_buf, &amp;end_ptr);
    if(user_value == 0 &amp;&amp; end_ptr == number_buf){
      printf( &quot;Invalid number format, 
non-numeric input or underflow\n&gt; &quot; );
    } else if ( errno == ERANGE ) {
      printf(&quot;Overflow in number parsing\n&gt; &quot;);
    } else break;
  }
  return (user_value);
}
</pre>
<p>Let us consider the overall structure of the code first of all.
The main changes for the first program are just to farm out some of
the work to extra functions. Most significantly I have moved the
main calculation loop from <tt class="function">main()</tt> to
<tt class="function">NewtonMethod()</tt>. Personally I tend not to
have anything but the most basic of startup code in <tt class=
"function">main()</tt>, and in the original code, <tt class=
"function">NewtonRough()</tt> was hardly earning its keep. The
other new functions are <tt class="function">Reciprocal()</tt> and
<tt class="function">GetNumber()</tt>, which are discussed further
below.</p>
<p>There are also a couple of minor details that are related to my
personal preference which are worth noting. I have capitalised the
first letter of each function (except, of course, <tt class=
"function">main()</tt>) for consistency. As it happens, I tend to
capitalise function names, but whichever way you prefer to name
functions, I feel it ought to be consistent. I have also made all
the function returns consistent. Again, this is a matter of
preference; I always put the return in parentheses, but put a space
between the return keyword and the first parenthesis to indicate it
is not a function. This is one of those places where I am not sure
if the inconsistency in the original code was a space issue, but I
felt it worth flagging.</p>
<p>So onto the more significant details, roughly in the order they
appear as you follow the program execution. The first issue is in
the definition of <tt class="function">main()</tt> itself. To my
knowledge, unless it is different in C99 (with which I am as yet
not totally familiar), in ISO C, main should be defined as one
of:</p>
<pre class="programlisting">
int main(void)
</pre>
<p>or</p>
<pre class="programlisting">
int main(int argc, char *argv[])
</pre>
<p>of which the first form is preferred here as we are not using
command line arguments.</p>
<p>I have added declarations for the user-defined functions as part
of a header file. These are not required, and the code works fine
without them, with the compiler treating the definitions as
prototypes. That said, once larger software is considered, it is
wise to have a declaration for every function (even if you do not
intend to call the function outside of its translation unit in my
opinion), so this is a good habit to develop. I like to give the
compiler every chance to spot my mistakes.</p>
<p>As well as function declarations, I have declared the parameters
as <tt class="literal">const</tt> where they are not modified. Once
again, in a small piece of code, this makes little difference, but
on a larger scale, it enables you to see the intent of the
designer, and gives the compiler a chance to stop you doing
something in error.</p>
<p>Throughout the code, I have renamed many of the variables to
make them somewhat more meaningful. This adds clarity to the
designer's intentions and makes the life of future maintainers (the
original designer included) much simpler. Another potential benefit
of using better names is revealed by a couple of typographical
errors in the code. Those who only glanced over it, may have missed
the upper case identifiers used by mistake in a few places (I
wonder if these were deliberate or accidental on Francis' part?).
To my mind, it is less easy to make this kind of mistake with more
expressive names, as you tend to think about them more as you type,
and once you make the mistake, it is visually more obvious.</p>
<p>The user input facility has been removed into a separate
function, and made more robust. Trying to make decent input code
with <tt class="function">scanf()</tt> is notoriously difficult,
and I guess many would say, impossible. The first issue with the
<tt class="function">scanf()</tt> statement as published, is that
<tt class="literal">%f</tt> is the wrong conversion specifier for
type <tt class="type">double</tt>. Unintuitively, while <tt class=
"literal">%f</tt> is correct for double in <tt class=
"function">printf()</tt>, <tt class="literal">%lf</tt> is used in
<tt class="function">scanf()</tt>. This is just one of the problems
with <tt class="function">scanf()</tt>. The second problem which
might be encountered here is when some kind of sanity check is
placed on the input as I have done. Unfortunately <tt class=
"function">scanf()</tt> doesn't remove unexpected non-numeric data
from the input stream, so any attempt to call <tt class=
"function">scanf()</tt> again if an error is detected results in
<tt class="function">scanf()</tt> picking up the same bad
character. Anyway, if anyone wants to know more about the problems,
I am sure a browse through the <tt class=
"literal">accu-general</tt> archives will probably help, or those
of <tt class="literal">comp.lang.c</tt> if it doesn't.</p>
<p>Furthermore, by rewriting the user input code to use <tt class=
"function">strtod()</tt> from an input string, we can handle any
numeric input (at least within the overflow and underflow
boundaries for a <tt class="type">double</tt> type), and easily
implement a basic sanity check. The only drawback being, at least
as far as I understand, that it is not possible to distinguish
between an underflow and an invalid numeric format in a strictly
ISO conforming library. Others of course, may, and probably will,
know better?</p>
<p>Throughout the code, I have replaced 'magic' numbers with
preprocessor macros. This is probably the most idiomatic way to
deal with magic numbers in C, so is the method I have chosen. Not
only is this more elegant and less error prone during later
maintenance, but in some cases faster as it avoids a function call.
In the case of the constants in the equation, the solution is still
unsatisfying, however, as I couldn't think of great names for them.
When we look at a more advanced version of the program, we will see
a better solution. I have also factored out the taking of
reciprocals into a function (it could equally well be a macro) so
the multiple occurrences of the 'magic' number 1.0 are avoided.</p>
<p>Another problem can be identified from a consideration of
Newton's method. It is not always foolproof in various
circumstances, and no method is bulletproof in the face of a
rootless function. With my maths being a little rusty I am not
certain, but I believe the function implemented in the sample
doesn't have any roots, only a singularity at x = 0. As a safety
net, therefore, the calculation loop in <tt class=
"function">main()</tt> is limited to a maximum number of tries,
defined in this case to be 30. This is sufficient for most purposes
as Newton's method converges rapidly in general.</p>
<p>Whilst the nature of the function under consideration removes
the risk of encountering many of the possible errors in the
standard C maths library, some can still occur. In this code, the
<tt class="function">log()</tt> function can produce a range error
if the value is close to zero. By checking the external errno
variable each loop cycle, we can handle this error, and also
implement error checking in the <tt class=
"function">Reciprocal()</tt> function.</p>
<p>A final change in <tt class="function">main()</tt> is the return
value to <tt class="literal">EXIT_SUCCESS</tt>. Whilst a return of
0 is perfectly valid ISO C, I prefer the standard macros,
especially if the code is for the benefit of people relatively
inexperienced. After all, how many people, inexperienced or
otherwise, have occasionally parsed code such as the idiomatic
(although perhaps unwise)</p>
<pre class="programlisting">
if(!(strcmp(s1, s2))) { ... }
</pre>
<p>as meaning 'if string s1 is not equal to string s2'? Although
the return value of 0 for success in many situations makes sense to
the experienced C coder, it is perhaps a little unintuitive for the
unwary.</p>
<p>So this code deals with the basic aspects of the problem. We
have tidied the code up so that it can be compiled, and is
reasonably idiomatic standard C (well standard C89 anyway). The
overall design is still very limited and lightweight, however.</p>
<p>For those who have managed to read this far, I have also written
a somewhat larger and more flexible version of the software. This
has slightly fewer rough edges, and can be adapted to wide range of
functions with ease. It still maintains a pretty lightweight
approach, but I hope is developed enough to be usable in real root
finding problems. If a student really wanted to pursue the issue,
they could add a fully-fledged parser, e.g. a recursive descent
system, to the code I present below, but that is really beyond the
scope of this article. The modified code is presented in <tt class=
"filename">newton2.c</tt> and <tt class=
"filename">newton2.h</tt>:</p>
<p>(<i><span class="remark">For reasons of space the code has not
been printed but is available on our web site, www.accu.org. -
ed.</span></i>)</p>
<p>All I have done there is break the concept of a mathematical
function down into components separated by + and -, as one tends to
while differentiating by hand. I have illustrated the mechanism
with a simple quadratic equation, f(x) = 6x^2 + 9x - 6, which has
two roots at -2 and -0.5, rather than the more complex function
used before. I have created three calculation functions for the
quadratic, linear and constant components of this equation, but it
is a simple task to add further functions for other standard
differentials. Each calculation function needs to be able to handle
the calculation for both f(x) and f'(x) based on an enumerated mode
parameter passed as an argument. With a library of standard
calculation functions in place, to work with different equations
all the user has to do is alter the static array of structures in
<tt class="function">CalculateBetterApprox()</tt> to use the right
constants and calculation function. The <i class=
"parameter"><tt>op</tt></i> parameter of the structure determines
whether the component is to be added to or subtracted from the
evaluation, or in the case of <tt class="literal">op_end</tt>,
indicates that the end of the equation has been reached. To create
functions to handle more complex standard differentials we might
need to add further constants to the structure, but again, this is
a simple task.</p>
<p>This still isn't the most flexible system, but represents a
significant improvement on the single function program originally
outlined. This code can at least be used reasonably successfully in
a real world situation, and could be extended to be friendlier if
required. For example, it would be relatively trivial to add
functionality to read the equation details from a file into a
dynamically allocated list rather than having to recompile each
time.</p>
<p>Finally we can briefly mention a few other additions that could
be used to make the system more flexible. Adding a search facility
to locate an initial estimate for a root rather than relying on the
user might be useful. Other improvements might revolve around
combining Newton's method with other root finding algorithms to
improve global convergence and handle cases where one particular
method runs into difficulties.</p>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e821" id="d0e821"></a>Critique from
James Holland</h3>
</div>
<p>I thought Francis has chosen quite an interesting problem for
the code critique competition. It makes a change to have a
numerical example and so I thought I would give it a whirl.</p>
<p>The first thing I did was to find out what Newton's method is
for finding the roots of an equation. It turns out to be quite
simple, in theory anyway. First of all, you guess where you think a
root of the equation might be. Then you plug your guess into
Newton's formula and it gives you a better approximation to the
root of the equation. Newton's formula is</p>
<pre class="programlisting">
x<sub>n+1</sub> = x<sub>n</sub> - f(x<sub>n</sub>)/f'(x<sub>n</sub>).
</pre>
<p>Not horrendously complicated and so I thought I could, at least,
get the student's program working. As you have probably guessed by
now it was not all plain sailing. Lets tackle the easy bits
first.</p>
<p>As it stands, the student's code won't even compile with out
errors. It is a simple matter, even for the student, to find and
correct the syntax errors and so I list them here with a brief
description of the solution.</p>
<p>The parameter of the <tt class="function">derivative</tt>
function is a lower case 'x'. The body of the <tt class=
"function">derivative</tt> function makes references to an upper
case 'X'. I suggest changing the code to refer to the lower case
'x'. Lower case letters are normally used for depicting unknowns in
mathematics.</p>
<p>The <tt class="literal">if</tt> statement within main has a
missing closing bracket. One way to check that an expression does
not have mismatched parentheses is to count the number of opening
and closing brackets. There should be an equal number of each. It
does not confirm that you have the correct number of brackets or
that they are in the right place, but it can be a help.</p>
<p>The last parameter of the penultimate statement of <tt class=
"function">main</tt> should be <i class="parameter"><tt>x0</tt></i>
(a lower case 'x'). I am sure that I am just as bad as anybody at
making typing errors but you just have to sit back and read through
your code carefully and methodically. See Pete Goodliffe's
<i class="citetitle">Professionalism in Programming #9</i>, second
bullet point entitled 'Don't code in a hurry'.</p>
<p>I think the code should compile now, but there are still one or
two outstanding issues. The <tt class="function">printf</tt> and
<tt class="function">scanf</tt> formatting strings should include a
lower case <tt class="literal">l</tt> between the <tt class=
"literal">%</tt> and the <tt class="literal">f</tt>, i.e., the
string should be <tt class="literal">%lf</tt>. This is because we
wish to print and read variables that have been declared as
<tt class="type">double</tt> as opposed to <tt class=
"type">float</tt>. All this business of defining the type of
variable that is to be printed or used to receive a numerical value
is, in my view, not very satisfactory. You just have to make sure
you have the correct format specifier for the type and number of
variables. Get a good book or read the Help files that come with
the compiler. I find formatted input and output troublesome when
programming in C. C++ has a different method of providing formatted
input and output that knows the types of variables are being used.
It is much safer and easer to use.</p>
<p>There are other oddities, such as evaluating <tt class=
"literal">pow(10.0, -6.0)</tt>. I am sure this would work but it is
a lot simpler to write the constant <tt class="constant">1e-6</tt>
in its place. Also the student has created a loop by means of an
empty <tt class="literal">for</tt> statement and has used the break
statement to leave the loop. Although this has the desired effect,
it is usually better (because in is easer to understand) to use a
<tt class="literal">while</tt> loop or, more appropriately in this
case a <tt class="literal">do</tt> <tt class="literal">while</tt>
loop. The logical condition of the <tt class="literal">do</tt>
<tt class="literal">while</tt> loop being true if function has not
yet converged sufficiently. An example of the <tt class=
"literal">do</tt> <tt class="literal">while</tt> loop is shown in
my version of the code, described later.</p>
<p>It is often stated that complicated expression should be split
up into smaller ones. While this is probably true, it should not be
taken to extremes as the meaning of the expression will be lost
(for the human reader, that is). I think this has happened with the
two functions <tt class="function">func()</tt> and <tt class=
"function">derivative()</tt>. In fact I would go so far as to say a
single statement should represent each function. So, the body of
func() should be</p>
<pre class="programlisting">
return 25.0/7.0 * log(3750 * sqrt(fabs(x))) - 1.0/sqrt(fabs(x)) - 6.0;
</pre>
<p>I have no idea what the expression means but at least I can see
it all in one go. The same goes for the body of <tt class=
"function">derivative()</tt>. Incidentally, I would not worry too
much about repeating small sub expressions such as <tt class=
"literal">sqrt(fabs(x))</tt> as the compiler will optimise common
sub expressions (if the appropriate compiler options have been
set). It is more important that the code is easy to read.</p>
<p>Now we come to the difficult bit, making the program do what it
is supposed to do. Even when all the problems with the student's
program have been put right it would not produce the correct
result. In fact the estimate of the root kept on getting larger for
each iteration. Eventually the value of the root became too large
to be represented in a <tt class="type">double</tt>. The program
came crashing to a halt.</p>
<p>After some investigation, I decided that the function the
student was using was not all that willing to be solved by Newton's
method. I think it has something to do with the derivative having a
very small value near the root. This has a tendency to cause the
function to diverge rather than converge on a solution. The only
way I could get Newton's method to converge was to enter an initial
estimate very close to the root, a value greater than 1e-6 and less
than 2e-2 seemed to provide the desired result and give a root at x
= 0.005122. It is a pity that the student was given such a
troublesome function to start with. A better-behaved function
would, at least, encourage the student to get the basic program
working correctly. Only then would it be appropriate to test
Newton's method with more wayward function.</p>
<p>With the hints and tips I have provided, the student should be
able to correct the problems with the code and get the program
working. For this reason I do not provide a corrected version of
the student's program. Instead, I thought I would have a go at
writing a program to find the roots of a whole class of functions,
not just one specific one.</p>
<p>As well as the function to be solved, Newton's method requires
the derivative of the function to be known. In the case of the
student's program this was entered directly in the code. Working
out the derivative of functions in general can be quite daunting
for anybody with my level of skill in mathematics. Even if the
derivative can be found it has to be entered into the code, along
with the original function. The program, therefore, can only solve
one particular equation. To solve another equation the program will
have to be edited to include the new equation and its derivative
and recompiled. There is one important class of function that has a
fixed structure and for which its derivative is easily calculated,
even by a simple program. The class is that of the polynomial,
specifically</p>
<pre class="programlisting">
p(x) = a<sub>0</sub> + a<sub>1</sub>x + a<sub>2</sub>x<sup>2</sup> + ... + a<sub>n</sub>x<sup>n</sup> = 0.
</pre>
<p>The derivative is simply</p>
<pre class="programlisting">
p'(x) = a<sub>1</sub> + 2a<sub>2</sub>x + ... + na<sub>n</sub>x<sup>(n-1)</sup>.
</pre>
<p>The two equations can be rewritten in the form of nested
multiplication for the sake of computational efficiency.</p>
<pre class="programlisting">
p(x) = a<sub>0</sub> + x(a<sub>1</sub> + x(a<sub>2</sub> + ... + x(a<sub>n-1</sub> + a<sub>n</sub>x) ...)

p'(x) = a<sub>1</sub> + x(2a<sub>2</sub>  + x(3a<sub>3</sub> + ... + x((n-1)a<sub>n-1</sub> + x(na<sub>n</sub>))...)
</pre>
<p>The nested form of p(x) requires only n additions and n
multiplications. The original form of p(x) requires n additions and
2n - 1 multiplications. Similar savings are also made for
p'(x).</p>
<p>With a little thought it can be seen that, given an array of
coefficients, both p(x) and p'(x) can be calculated by means of a
looping structure. This had been adopted in the following program
for finding the roots of polynomial equations using Newton's
method.</p>
<pre class="programlisting">
#include&lt;stdio.h&gt;
#include&lt;math.h&gt;
double coefficient[10];
double estimate;
int order;
char reply;
int get_order(void);
double get_coefficient(int);
double get_estimate(void);
double evaluate_function(void);
double evaluate_derivative(void);
int main(void){
  int i;
  double f;
  double d;
  double new_estimate;
  int iterations = 0;
  order = get_order();
  for (i = 0; i &lt; order + 1; ++i)
    coefficient[i] = get_coefficient(i);
  do{
    new_estimate = get_estimate();
    do{
      estimate = new_estimate;
      f = evaluate_function();
      d = evaluate_derivative();
      new_estimate = estimate - f/d;
      ++iterations;
    } while (fabs(new_estimate - estimate) &gt; 1e-10 &amp;&amp; iterations != 50);
    if (iterations == 50)
      printf(&quot;The function did not converge within %i iterations.\n&quot;, 50);
    else
      printf(&quot;Root located at x = %.10lf\n&quot;, new_estimate);
    printf(&quot;Would you like to enter another initial estimate? &quot;);
    scanf(&quot;%c&quot;, &amp;reply);
  } while (reply != 'n' &amp;&amp; reply != 'N');
  return 0;
}
int get_order(void){
  int order;
  puts(&quot;The program attemts to solve the polynomial equation&quot;);
  puts(&quot;a0x^0 + a1x^1 + ... + anx^n = 0&quot;);
  puts(&quot;where a0 .. an are the coefficients and n is the order of the polynomial&quot;);
  printf(&quot;\nEnter the order of the polynomial: &quot;);
  scanf(&quot;%d&quot;, &amp;order);
  return order;
}
double get_coefficient(int i){
  double coefficient;
  printf(&quot;Enter the value of coefficient a%d: &quot;, i);
  scanf(&quot;%lf&quot;, &amp;coefficient);
  return coefficient;
}
double get_estimate(void){
  double estimate;
  printf(&quot;Enter your initial guess: &quot;);
  scanf(&quot;%lf&quot;, &amp;estimate);
  return estimate;
}
double evaluate_function(void){
  int i;
  double f = coefficient[order];
  for (i = order - 1; i &gt; -1; --i) {
    f *= estimate;
    f += coefficient[i];
  }
  return f;
}
double evaluate_derivative(void){
  int i;
  double d = coefficient[order] * order;
  for (i = order - 1; i &gt; 0; --i) {
    d *= estimate;
    d += coefficient[i] * i;
  }
  return d;
}
</pre>
<p>When the program runs, the user is asked to enter the order of
the polynomial followed by the coefficients. The user then enters
an estimate of the location of root to be found. If a solution is
found within 50 iterations the location of the root is displayed.
If no solution is found a warning message is displayed.</p>
<p>Like most demonstration programs, my program can be improved in
many ways. Probably the most dangerous aspect of the program is
that there is no check on the order of the polynomial. A high order
(greater than 9 in this case) will overrun the end of the
coefficients buffer with, no doubt, disastrous results. Characters
entered by the user are not checked to allow only those that are
valid. To correct these defects takes a considerable amount of code
that would detract from the main program (that is my excuse, at any
rate).</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e1037" id="d0e1037"></a>Critique from
Catriona O'Connell <tt class="email">&lt;<a href=
"mailto:catriona38@hotmail.com">catriona38@hotmail.com</a>&gt;</tt></h3>
</div>
<p>Here are my thoughts on the Student Code Critique 11 (C Vu
13.4).</p>
<p>There are two major errors in the code as it is printed:</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>A <tt class="type">double</tt> should use <tt class=
"literal">%lf</tt> conversion in <tt class="function">scanf</tt>
and <tt class="function">printf</tt> rather than <tt class=
"literal">%f</tt> which is meant for <tt class="type">float</tt>.
[<i><span class="remark">actually it is more confusing, <tt class=
"literal">%f</tt> is correct for <tt class="function">printf</tt> -
there is no <tt class="literal">%lf</tt> in the C Standard - but as
you say, it needs to be <tt class="literal">%lf</tt> for <tt class=
"function">scanf</tt>. Ed.</span></i>]</p>
</li>
<li>
<p>There is a missing closing &quot;)&quot; in convergence test.</p>
</li>
</ol>
</div>
<p>Had these errors been fixed the code would have worked within
the limitations of the Newton-Raphson method. There are however a
number of undesirable traits in the code.</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Infinite loop potential.</p>
</li>
<li>
<p>Fixed convergence criteria.</p>
</li>
<li>
<p>No checks for valid input although scanf does a partial check on
the input.</p>
</li>
<li>
<p>No checks for &quot;divide by zero&quot;.</p>
</li>
<li>
<p>No prototypes for functions.</p>
</li>
<li>
<p>Lack of comments - even though the code is almost
self-commenting.</p>
</li>
</ul>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e1110" id="d0e1110"></a>Reverse
engineered code.</h4>
</div>
<p><tt class="function">func()</tt>: Returns the value of a
function for argument <i class="parameter"><tt>x</tt></i>. The
function is</p>
<p>(25/7)(ln(3750*sqrt(abs(x)) - 1/sqrt(abs(x)) - 6</p>
<p>where <tt class="function">abs</tt> is the absolute value
function. The function can be simplified slightly using the
properties of logarithms to separate the constant factor. The
function is symmetric about the &quot;y-axis&quot; and has a singularity at x
= 0</p>
<p><tt class="function">derivative()</tt>: Returns the value of the
derivative (with respect to <i class="parameter"><tt>x</tt></i>) of
<tt class="function">func()</tt> at <i class=
"parameter"><tt>x</tt></i>.</p>
<p>The (derivative) function is</p>
<p>(1/(2x))*( (25/7) + 1/(sqrt(abs(x))) )</p>
<p>Note that the factor of <i class="parameter"><tt>x</tt></i>
outside the sum correctly allows for the change in sign of the
derivative with the sign of <i class="parameter"><tt>x</tt></i>.
Note also that the value of the derivative is undefined for x = 0
(that is the limit from both sides does not exist). If the
derivative function is called with a value of zero, then it will
fail with a divide by zero error.</p>
<p><tt class="function">NewtonRough()</tt>: Returns one iteration
of the Newton-Raphson algorithm. The choice of name is poor.
Something like <tt class="function">doNewtonRaphsonIteration()</tt>
would have been more descriptive.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e1159" id="d0e1159"></a>General
Comments and suggested improvements:</h4>
</div>
<p>The Newton-Raphson algorithm is not guaranteed to converge to a
steady value. The convergence depends critically on the nature of
the function and the initial starting point. In some pathological
cases NR may appear to converge but will not converge to a genuine
zero of the function. The student should not be surprised by this
behaviour, but all too frequently such routines are used without
the users being aware of the restrictions. When it works the
Newton-Raphson method is quadratically convergent, but when it
doesn't work it can rapidly diverge or enter a loop of values. so,
the answer to the direct question is that the student's
understanding of numerical analysis and algorithms is lacking. The
student should be made aware of other root-finding methods to
enrich his/her armoury of techniques.</p>
<p>No iterative algorithm should have a potentially infinite loop.
If it hasn't converged after a reasonable number of iterations then
a new starting point or algorithm needs to be considered. If the
number of iterations is set too high then consideration will have
to be given to numerical stability and accumulated rounding
errors.</p>
<p>There has been much discussion in C Vu in the past about how
convergence tests should be done. In this instance the absolute
difference in the value of <i class="parameter"><tt>x0</tt></i>
returned by two consecutive iterations is a reasonable measure
since graphing the function shows that the zeros lie at around
(+/-) 0.005.The maximum number of iterations and the convergence
criterion need to be made more visible and stop being magic
numbers. The lack of function prototypes forces an order of
function definition that is restrictive for future devel</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
