    <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  :: Everything You Wanted To Know About C ......</title>
        <link>https://members.accu.org/index.php/articles/1649</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">Programming Topics + CVu Journal Vol 1, #2 - Dec 1987</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/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</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/c226/">012</a>
<br />

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

                    -                        <a href="https://members.accu.org/index.php/articles/c65+226/">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;Everything You Wanted To Know About C ......</h1>
<p><strong>Author:</strong>&nbsp;Martin Moene</p>
<p>
<strong>Date:</strong> 20 June 2010 08:58:00 +01:00 or Sun, 20 June 2010 08:58:00 +01:00</p>
<p><strong>Summary:</strong>&nbsp;Tips and Tricks from Steven Palmer</p>
<p><strong>Body:</strong>&nbsp;<p>The following tips and tricks were collected together after a study of some potential problems encountered by beginners to C. Space does not permit me to include many other, similiarily useful, tips. If you have any to contribute, please send them to the editor.</p>

<h2>1. Constants</h2>

<p>All integer literal constants are stored as integer, unless you supply the L suffix. Beware of calling a function that expects a argument of type long using a literal. For example</p>

<p><pre class="programlisting">
lseek(fh, 0, SEEK_BEG);
</pre></p>

<p>may not work because lseek() expects the second argument, the offset, to be a long integer. It should be re-written as</p>

<p><pre class="programlisting">
lseek(fh, 0L, SEEK_BEG);
</pre></p>

<p>All floating-point literal constants are stored as double, rather than just plain float. So the following</p>

<p><pre class="programlisting">
float count;
...
count = 8.95;
</pre></p>

<p>will elicit a 'Data Conversion' warning from some compilers because the 8.95 has type double which has to be converted down to float. If you feel picky about minor warnings, you can get round this by casting the literal</p>

<p><pre class="programlisting">
count = (float)8.95;
</pre></p>

<p>Again, beware of calling functions with literals if they are expecting an argument of type float. All mathematical libraries tend to use arguments of type double as a sort of safety catch. You should also #include &lt;math.h&gt; so that the compiler can catch and warn about unintended conversions.</p>

<h2>2. Operator Precedence</h2>

<p>You have probably come across the case where assignments inside a conditional, such as</p>

<p><pre class="programlisting">
while ((c = getchar()) != ' ')
</pre>
have to be bracketed, otherwise they will be interpreted by the compiler as</p>

<p><pre class="programlisting">
while (c = (getchar() != ' '))
</pre>
Take some time to learn the C operator precedence levels. There are some other catches for the unwary. For example</p>

<p><pre class="programlisting">
if (p &amp; 0xC0 == 0xC0)
</pre>
does NOT mean what it seems. The == operator has higher precedence than the &amp;, so the expression must be re-written as</p>

<p><pre class="programlisting">
if ((p &amp; 0xC0) == 0xC0)
</pre></p>

<p>A good C compiler should catch the former and warn the user about possible missing parenthesis.</p>

<h2>3. #define macros</h2>

<p>Except for simple macros, place the definition part of all #define preprocessor statements inside brackets. This avoids any ambiguity arising from apparently innocent usage such as the following</p>

<p><pre class="programlisting">
#define TABLE_BASE 0x2000
#define TABLE_LIMIT TABLE_BASE+0x1000
#define TABLE_SIZE TABLE_LIMIT-TABLE_BASE/sizeof(long)
</pre></p>

<p>TABLE_SIZE is definitely NOT set to the correct value. The macro will actually be interpreted as</p>

<p><pre class="programlisting">
0x2000+0x1000-0x2000/4
</pre></p>

<p>(assuming sizeof(long) is 4 bytes), or 0x2800. The second and third #defines must be rewritten as</p>

<p><pre class="programlisting">
#define TABLE_LIMIT (TABLE_BASE+0x1000)
#define TABLE_SIZE (TABLE_LIMIT-TABLE_BASE)/sizeof(long)
</pre></p>

<p>If the macro takes any arguments, always place the arguments inside the definition in brackets.</p>

<p><pre class="programlisting">
#define isdigit(c) ((c) &gt;= '0' &amp;&amp; (c) &lt;= '9')
</pre></p>

<p>Finally, never call a macro with an expression that modifies itself, or any other part of the expression in that same macro. For example, the following are very suspect</p>

<p><pre class="programlisting">
isdigit(*c++)
isdigit(*c += 1)
isdigit(getchar())
</pre></p>

<h2>4. Type declarations</h2>

<p>Complex type declarations, while they are fun to explore and show off in listings, are one of the biggest headaches in C maintainability. Beware that if you make use of complex declarations, your code may be difficult to port to another language, such as Pascal or Ada. However if this is not too much of an issue, you can sometimes create very sophiscated and efficent data structures this way. For example</p>

<p><pre class="programlisting">
typedef char (* fchr)[4];
fchr (*routine)(char *);
</pre></p>

<p>declares a pointer to a function that returns a pointer to a character array of four elements. It can be assigned an address by</p>

<p><pre class="programlisting">
fchr lookup(char *);
...
routine = lookup;
</pre></p>

<p>and called by</p>

<p><pre class="programlisting">
fchr cptr;
cptr = (*routine)(&quot;HELP&quot;)
</pre></p>

<p>On return, cptr will point to the start of a 4-element character array, and can be used to skip over those characters to the start of the next 4 characters using</p>

<p><pre class="programlisting">
++cptr;
</pre></p>

<p>If your compiler allows you to examine the generated object code in assembler form, you can get some idea of how much more efficent the object code is over a more straightforward approach.</p>

<h2>5. Debugging</h2>

<p>If you are unlucky enough not to be using a proper C development system which includes a source-code debugger, like C-trace or Codeview, you will probably be wasting time tracking down obscure bugs that a source-code debugger would track down within minutes. However, there are a few tricks that you can use to help debug your program without having to restort to a machine-code debugger. Here are some...</p>

<p>(1)&emsp;Use the serial or printer port to route diagnostic messages. If you have a spare terminal, you can connect it to the serial port of your computer and direct all diagnostics so that they appear on the terminal. You can also use a printer, but be careful of placing the diagnostics inside large loops ... you can end up wasting a lot of good printer paper!</p>

<p>(2)&emsp;Use assertions. Assertions allow you to check that a specific condition is true before you execute the next statement. If your compiler does not support assertions, you can use the following. Place it in a file called &quot;assert.h&quot; in your header directory</p>

<p><pre class="programlisting">
#ifdef DEBUG
#define assert(n,e) {if (!(e)) { \ fprintf(stderr,&quot;Assertion number %d failed!\n&quot;, (n)); \ exit(1); } }
#else #define assert(n,e) #endif
</pre></p>

<p>Use it like this</p>

<p><pre class="programlisting">
/* Switch on assertions */
#define DEBUG
#include &lt;assert.h&gt;
...
/* Check that x is non-zero */
assert(1,x != 0);
p = q/x;
...
</pre></p>

<p>If the assertion failed because x has the value 0, then the program will print the following and stop.</p>

<p>Assertion number 1 failed!</p>

<p>(3)&emsp;Predefine all functions. By predefining functions, you are telling the compiler what types of arguments it expects and what type it returns. This</p>

<p>way, you will be warned if you accidently pass a floating-point value to a function that expects an integer, or try to use the result of a function that does not return a value. An example of a predefined function is</p>

<p><pre class="programlisting">
char *malloc(unsigned int);
</pre></p>

<p>This says that function malloc() takes one argument of type unsigned int, and returns a pointer to a character.</p>

<p>(4)&emsp;LINT your source code, or use the highest possible warning level on your compiler. This ensures that the compiler will report on possible bugs that are normally ignored at the default warning level, on non-portable constructs or on wasteful code. LINT is a utility available under UNIX and some other operating systems that performs a very strict check of your source code.</p>

<p>(5)&emsp;Use the C-Vu technical help section. If you are stuck with a really persistent bug, get in contact with either Martin Houston or Steven Palmer. If they can't help, then they'll do their best to find someone who can, or even contact the software house who developed your compiler to see if the bug could be a product of the compiler itself. That is what a user group is for!</p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
