<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://hackepedia.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=84.170.160.72</id>
	<title>Hackepedia - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://hackepedia.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=84.170.160.72"/>
	<link rel="alternate" type="text/html" href="https://hackepedia.org/index.php?title=Special:Contributions/84.170.160.72"/>
	<updated>2026-05-08T19:03:32Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://hackepedia.org/index.php?title=C_Primer&amp;diff=4518</id>
		<title>C Primer</title>
		<link rel="alternate" type="text/html" href="https://hackepedia.org/index.php?title=C_Primer&amp;diff=4518"/>
		<updated>2010-07-11T20:44:33Z</updated>

		<summary type="html">&lt;p&gt;84.170.160.72: /* The Internet Interface */ formatting&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The [[C]] programming language was invented at [[Bell Labs]] by&lt;br /&gt;
Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
Since UNIX and C are intertwined it&#039;s good to know the basics of both.  The &amp;quot;K&amp;amp;R The (ANSI) C Programming Language&amp;quot; written by both Kernighan and Ritchie is the &amp;quot;bible&amp;quot; for C programmers.  Another reference will be  &amp;quot;The UNIX programming environment&amp;quot; written by Kernighan and&lt;br /&gt;
Rob Pike.  This book ties UNIX&#039;s development tools together such as simple&lt;br /&gt;
shell programming as well as the UNIX interface of the C programming language.&lt;br /&gt;
The classic K&amp;amp;R program that the C book starts with is:&lt;br /&gt;
&lt;br /&gt;
 int&lt;br /&gt;
 main(void)&lt;br /&gt;
 {&lt;br /&gt;
        printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You see the structure here of a program.  What you see between the { and } brackets is known as a &amp;quot;block&amp;quot; in C.  It ties a series of instructions together, whether in&lt;br /&gt;
a logical branch (often an if branch) or to define a function or procedure (same thing).  Every C program has a main()&lt;br /&gt;
[[procedure]].  This is where the program starts.  main() returns an integer&lt;br /&gt;
which is signed[1].  The return value can be caught and read by the user of &lt;br /&gt;
the program when the program exits. &lt;br /&gt;
&lt;br /&gt;
A procedure also takes one or more [[argument]]s.  In the code example above the&lt;br /&gt;
argument is [[void]], meaning it&#039;s ignored (even if there is arguments passed to&lt;br /&gt;
the procedure).  main() usually takes 2 arguments to read arguments[2] from&lt;br /&gt;
the program that executed the particular program.  There is a third argument&lt;br /&gt;
on UNIX systems that allows a users environment list to be passed into the&lt;br /&gt;
program as well.  &lt;br /&gt;
&lt;br /&gt;
Finally the instruction, printf().  As you can see it is&lt;br /&gt;
a function as well and it takes as the argument &#039;&#039;&amp;quot;Hello, World\n&amp;quot;&amp;quot;.  The \n&lt;br /&gt;
means newline (ascii hex 0a dec 10) and ensures that when the program returns&lt;br /&gt;
to a user shell that the prompt will be on the next line.  What is printed&lt;br /&gt;
in fact is &amp;quot;Hello, World&amp;quot;.  Then the program exits.  As there is no return&lt;br /&gt;
value passed with the return() or exit() function I&#039;m not sure if it will&lt;br /&gt;
be consistent.  Consistency is key in programming.&lt;br /&gt;
&lt;br /&gt;
== The UNIX Interface ==&lt;br /&gt;
&lt;br /&gt;
As indicated in the introduction, UNIX and [[C]] go together.  The OS provides an [[API]] to hook&lt;br /&gt;
into the [[kernel]] (privileged core of the OS) to make use of [[system call]]s.  &lt;br /&gt;
All input and output to and from a program is dealt with a system call, &lt;br /&gt;
calculations do not and remain in userland.  UNIX has two sides, a kernel&lt;br /&gt;
and [[userland]].  Userland is for users and administrators who request services&lt;br /&gt;
from the kernel which queues the request, and services results back as soon&lt;br /&gt;
as possible.  The kernel schedules processes (programs) in userland to run&lt;br /&gt;
on a fair share basis (at least in theory and determined by the algorithm).&lt;br /&gt;
Free UNIX clones or UNIX-like Operating Systems exists.  These are great for&lt;br /&gt;
personal study, and excellent for learning C because they are included with &lt;br /&gt;
the GNU C compiler.  In the old days one had to dual-boot a computer on &lt;br /&gt;
partitions, today one can run a [[virtual]] computer in a window and run any&lt;br /&gt;
Operating System they like. This eases switching between platforms somewhat.&lt;br /&gt;
&lt;br /&gt;
If you run Mac OS X it is based on UNIX and you can open a terminal to get &lt;br /&gt;
to the command prompt.  [[Linux]] and [[BSD]] OS&#039;s also have this capability.   &lt;br /&gt;
So when you have the C source code (ending in a .c or .cc extension) how do&lt;br /&gt;
you make it work?  In C you compile the source code into a binary code which&lt;br /&gt;
is machine language, unlike the language BASIC C is not interpreted, which&lt;br /&gt;
means the program is a script run inside a program that knows what to do with&lt;br /&gt;
the instructions.  Compiled programs do not need another program to make &lt;br /&gt;
themselves run.  Usually a compiler (such as gcc) produces assembler text&lt;br /&gt;
first round through, and passes that to an assembler to produce the binary&lt;br /&gt;
code.  This is a good feature and allows people familiar with assembler to &lt;br /&gt;
really debug the execution path (order of operations) of a program.  Here is&lt;br /&gt;
a list of useful programs:&lt;br /&gt;
&lt;br /&gt;
 [[gcc]], cc - C compiler (-o file outputs binary code, -static produces static code)&lt;br /&gt;
 [[gdb]] - debugger (allows you to step through your program for every instruction)&lt;br /&gt;
 [[ldd]] - list dynamic dependencies (if dynamically compiled, reduces size of bins)&lt;br /&gt;
 [[objdump]] - disassembler (produces assembly language from binary code)&lt;br /&gt;
 [[file]] - identifies a program (similar to ldd), useful!&lt;br /&gt;
 [[nm]] - identifies symbols in the binary code of a program, probably helpful for reverse engineering although I have never done this.&lt;br /&gt;
 [[vi]], [[ed]], [[pico]] - useful text editors to enter the C language code.&lt;br /&gt;
&lt;br /&gt;
So the small program in the introduction can be compiled like the following:&lt;br /&gt;
&lt;br /&gt;
cc -o helloworld helloworld.c&lt;br /&gt;
&lt;br /&gt;
and then the binary can be executed with ./helloworld &lt;br /&gt;
You may need to add an &amp;quot;&amp;quot;#include &amp;lt;stdio.h&amp;gt;&amp;quot;&amp;quot; to the top, which is the standard&lt;br /&gt;
C input/output library.  The .h is a header file, but we&#039;ll get to that.&lt;br /&gt;
(I hope). You can add -Wall to the command line arguements to show you all of the warnings. &lt;br /&gt;
If you want to write &amp;quot;clean&amp;quot; code, you will fix it until it has no errors. &lt;br /&gt;
&lt;br /&gt;
As soon as you run a program on UNIX and it ends there is an exit code.  Every&lt;br /&gt;
[[shell]] has a different way of querying the exit value as you face the prompt&lt;br /&gt;
again, but with the /bin/[[sh]], [[bash]] and [[ksh]] shell you can type echo $? to query the return value.&lt;br /&gt;
&lt;br /&gt;
Another great feature that UNIX offers other than opening files is pipes.  A&lt;br /&gt;
pipe (symbol | on the command prompt) allows one to direct the output of one&lt;br /&gt;
program into the input of another program and thus you create what is called&lt;br /&gt;
a pipeline.  A [[pipeline]] uses different programs that specialize on one task&lt;br /&gt;
to shape the output at the end into something useable.  Take this example&lt;br /&gt;
of the previous text; if I did:&lt;br /&gt;
&lt;br /&gt;
 $ cat c-programming | grep -A5 ^int | cat -n&lt;br /&gt;
     1  int&lt;br /&gt;
     2  main(void)&lt;br /&gt;
     3  {&lt;br /&gt;
     4          printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
     5  }&lt;br /&gt;
     6&lt;br /&gt;
&lt;br /&gt;
The output is the source code of the helloworld.c program and the -n argument&lt;br /&gt;
to cat adds a sequential line count per line.  Ok so you can put together&lt;br /&gt;
your own programs and programs &amp;quot;&amp;quot;already created&amp;quot;&amp;quot; for you to make the final &lt;br /&gt;
output. There are limits, but this is almost 40 years&lt;br /&gt;
old.&lt;br /&gt;
&lt;br /&gt;
Another important point is that if you want to make custom modifications to&lt;br /&gt;
the UNIX Operating System, you can do this and the source code is in C,&lt;br /&gt;
minor parts are written in assembly but only on really low end stuff.  The&lt;br /&gt;
C source code guarantees that you can edit any of the code you like, or hire someone to edit&lt;br /&gt;
it if you desire to do so. Unfortunately [[Apple]] discontinued [[OpenDarwin]] as far as I know,&lt;br /&gt;
but there is a certain paranoia in most corporate circles that there&lt;br /&gt;
is a loss of income if source code is revealed to scary people. It&#039;s in all our best interests to &lt;br /&gt;
ensure this mindset is corrected by the decision makers.&lt;br /&gt;
&lt;br /&gt;
Most open source operating system vendors show you the steps to turn the C&lt;br /&gt;
program code into binaries that run the final system.  All the code has to&lt;br /&gt;
be compiled which depending on your processor speed takes days to a few&lt;br /&gt;
minutes and then the system requires a reboot.  The reboot is required to&lt;br /&gt;
load the new kernel which then services everything else.&lt;br /&gt;
&lt;br /&gt;
Please see http://www.hackepedia.org for a lot of help on UNIX that I &lt;br /&gt;
contributed my time to.&lt;br /&gt;
&lt;br /&gt;
==  The Internet Interface ==&lt;br /&gt;
&lt;br /&gt;
Our Internet is closely tied to UNIX and thus C.  The original computers that&lt;br /&gt;
switched packets back and forth between Universities and Governments on the&lt;br /&gt;
old ARPAnet (predecessor of Internet) probably ran UNIX.  UNIX has a great &lt;br /&gt;
set of API&#039;s for userland to connect into the greater network.  The standard &lt;br /&gt;
of Internet API&#039;s is probably Berkeley sockets which were created on the BSD &lt;br /&gt;
variant of UNIX.  &lt;br /&gt;
&lt;br /&gt;
If network communication were chopped up into layers and you have physical&lt;br /&gt;
exchange of bits over wire or radio then this would be layer 1.  If you have&lt;br /&gt;
a standard protocol with rudamentary addresses and perhaps a checksum at the&lt;br /&gt;
back and on the Data Link you&#039;d call this layer 2.  Then if you have a more &lt;br /&gt;
complex protocol such as the Internet Protocol that reaches beyond routers&lt;br /&gt;
to form an internet you&#039;d call this a Network layer or layer 3.  Finally IP&lt;br /&gt;
carries Transport protocols such as TCP (Transmission Control Protocol) which&lt;br /&gt;
is complex and has features such as windowing, retransmissions, sequencing,&lt;br /&gt;
reception acknowledgement and so on.  And it also carries simple protocols&lt;br /&gt;
such as UDP (User Datagram Protocol) which really only defines a source port, &lt;br /&gt;
a destination port, the data length and a checksum for it all.  This is the&lt;br /&gt;
Transport layer or layer 4.  When dealing with TCP and UDP in UNIX the socket&lt;br /&gt;
API allows you limited manipulation of layer 4, but most of it is done by&lt;br /&gt;
the kernel (such as checksumming).  All you&#039;re left with is sticking in the&lt;br /&gt;
data in there and wait for the system call to return.  What the system call&lt;br /&gt;
returns determines whether you successfully sent a packet out of a computers&lt;br /&gt;
network interface or not.  You can also have RAW sockets which means you have&lt;br /&gt;
direct control over layer 3, and you have to write the header protocol,&lt;br /&gt;
checksumming, payload data and other features such as retransmissions yourself.&lt;br /&gt;
This socket mode is restricted to the superuser/root.  There is also layer 2&lt;br /&gt;
access for the real hard-core but I won&#039;t go into that just yet.&lt;br /&gt;
Ok here is a diagram from RFC 768 (UDP):&lt;br /&gt;
&lt;br /&gt;
                  0      7 8     15 16    23 24    31&lt;br /&gt;
                 +--------+--------+--------+--------+&lt;br /&gt;
                 |     Source      |   Destination   |&lt;br /&gt;
                 |      Port       |      Port       |&lt;br /&gt;
                 +--------+--------+--------+--------+&lt;br /&gt;
                 |                 |                 |&lt;br /&gt;
                 |     Length      |    Checksum     |&lt;br /&gt;
                 +--------+--------+--------+--------+&lt;br /&gt;
                 |&lt;br /&gt;
                 |          data octets ...&lt;br /&gt;
                 +---------------- ...&lt;br /&gt;
&lt;br /&gt;
                      User Datagram Header Format&lt;br /&gt;
&lt;br /&gt;
The funny numbers at the top indicate a scale, from 0 through 31.  These are&lt;br /&gt;
bits.  Each rectangle represents 16 bits in this picture and you look at it&lt;br /&gt;
from top left to right.  Something like this is easy to construct in C because&lt;br /&gt;
it coincides with the size of short unsigned integers that are part of C.&lt;br /&gt;
I&#039;m going to show you an example of how this would be constructed in C, if you&lt;br /&gt;
don&#039;t understand it, ignore it and come back to it later when you&#039;re able to.&lt;br /&gt;
&lt;br /&gt;
 /*&lt;br /&gt;
  * this would be a definition of a UDP header&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
 struct udpheader {&lt;br /&gt;
        u_int16_t sport;&lt;br /&gt;
        u_int16_t dport;&lt;br /&gt;
        u_int16_t len;&lt;br /&gt;
        u_int16_t csum;&lt;br /&gt;
 };&lt;br /&gt;
                &lt;br /&gt;
Notice that a UDP packet is limited to 65535 bytes due to the integer limit&lt;br /&gt;
that one can pack into a 16 bit integer.  So if you had a 1400 byte packet&lt;br /&gt;
you could do the following.&lt;br /&gt;
&lt;br /&gt;
 u_char packet[1400];&lt;br /&gt;
 u_char *data;&lt;br /&gt;
 struct udpheader *uh;&lt;br /&gt;
&lt;br /&gt;
 uh = (struct udpheader *)&amp;amp;packet[0];&lt;br /&gt;
 uh-&amp;gt;sport = 1024;&lt;br /&gt;
 uh-&amp;gt;dport = 53;&lt;br /&gt;
 uh-&amp;gt;len = 1400;&lt;br /&gt;
 uh-&amp;gt;csum = 0;&lt;br /&gt;
&lt;br /&gt;
 data = &amp;amp;packet[sizeof(struct udpheader)];&lt;br /&gt;
&lt;br /&gt;
There is a few caveats to this example (it&#039;s only an example).  It would work&lt;br /&gt;
on a powerpc processor, or sparc processor as written, but not on intel (i386)&lt;br /&gt;
processors.  There is a law of ordering bits of packets on the internet and&lt;br /&gt;
they require the least significant bit to cross first right through to the &lt;br /&gt;
most significant bit.  The registers on an i386 processor store a 16 bit &lt;br /&gt;
integer with the most significant bit first and least last.  This is called&lt;br /&gt;
endian-ness or byte order.  Network byte order is big endian as outlined, what&lt;br /&gt;
intel processors use is little endian byte order.  So you need a function to&lt;br /&gt;
flip the bytes in the right order.  UNIX has a few functions to do that.  This&lt;br /&gt;
is how you write the above portable.&lt;br /&gt;
&lt;br /&gt;
 uh-&amp;gt;sport = htons(1024);&lt;br /&gt;
&lt;br /&gt;
htons() - host to network (short 16 bits) swap.&lt;br /&gt;
&lt;br /&gt;
Ok.  The final word.  As you can see with C you can write out the headers of&lt;br /&gt;
packets easily, it gets a little tricky when things are compressed into &lt;br /&gt;
nibbles (half-bytes - 4 bit) or even 1 bit flags.  But C can work around this.&lt;br /&gt;
Internet, UNIX and the C programming language thus seem to be made for each&lt;br /&gt;
other.  If you like any of these you&#039;ll like the rest.  I&#039;m going to get into&lt;br /&gt;
socket programming much later perhaps.&lt;br /&gt;
&lt;br /&gt;
== #4 Integers, Loops and Branches ==&lt;br /&gt;
&lt;br /&gt;
Variables in C are important.  In fact they exist in all programming languages.&lt;br /&gt;
They are used for temporary or permanent storage throughout the programs life.&lt;br /&gt;
A processor (CPU) has a set of registers that are used to do logical operations&lt;br /&gt;
on numbers stored in them.  The storage size of these registers defines the&lt;br /&gt;
storage size of integers available in any programming language.  More on this&lt;br /&gt;
later.  Often any computer is used to do boring calculations and do these at&lt;br /&gt;
rapid speeds over and over (loops). This is why we invented computers so that&lt;br /&gt;
they can do these repetitive tasks at great speeds.  Take a look at the &lt;br /&gt;
following main() function:&lt;br /&gt;
&lt;br /&gt;
 1               int&lt;br /&gt;
 2               main(void) {&lt;br /&gt;
 3               &lt;br /&gt;
 4                       int count;&lt;br /&gt;
 5               &lt;br /&gt;
 6                       count = 10;&lt;br /&gt;
 7       &lt;br /&gt;
 8                       while (count &amp;gt; 0) {&lt;br /&gt;
 9                               printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
 10                              count = count - 1;&lt;br /&gt;
 11                      }&lt;br /&gt;
 12              }&lt;br /&gt;
&lt;br /&gt;
What this program does is it define a variable of type int (integer) named &lt;br /&gt;
count (line 4).  It then assigns the value 10 (decimal) to it (line 6).  Then&lt;br /&gt;
comes a while() loop.  A while loop will continue to loop as long as the &lt;br /&gt;
condition given as its argument remains true.  In this case (on line 8) the&lt;br /&gt;
condition holds true when the value of count is greater than zero.  On line&lt;br /&gt;
9 we print our familiar string (taken from #1).  Line 10 then decrements the&lt;br /&gt;
value of count by one.  This is the simplest way to decrement by one.  C has&lt;br /&gt;
a few shortcuts to decrement such as:&lt;br /&gt;
&lt;br /&gt;
        count--;&lt;br /&gt;
        --count;&lt;br /&gt;
        count -= 1;&lt;br /&gt;
&lt;br /&gt;
All of these ways are synonymous (the same as) to what you see on line 10.&lt;br /&gt;
Similarily if you wanted to increase the value of count by one you could type:&lt;br /&gt;
&lt;br /&gt;
        count = count + 1;&lt;br /&gt;
        count++;&lt;br /&gt;
        ++count;&lt;br /&gt;
        count += 1;&lt;br /&gt;
&lt;br /&gt;
They all mean the same.  The ++ on either side has a dual functionality which&lt;br /&gt;
I will demonstrate here:&lt;br /&gt;
&lt;br /&gt;
 1       while (count--) &lt;br /&gt;
 2               printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
Notice a few differences.  The obvious decrementor has been stuffed into the&lt;br /&gt;
while condition and the while loop doesn&#039;t have a block bracket {}.  The&lt;br /&gt;
result will print 10 Hello Worlds like the above example.  Because 10 through 1&lt;br /&gt;
are positive and thus logically true while will continue.  As soon as count&lt;br /&gt;
reaches the value of 0 while() will break.  Consider the following difference:&lt;br /&gt;
&lt;br /&gt;
 1       while (--count) &lt;br /&gt;
 2               printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
Here our string will be printed only 9 times.  The reason is the following.&lt;br /&gt;
When a incrementor or decrementor is before a variable/integer the value is&lt;br /&gt;
decremented before it is evaluated in a branch condition (in order to break&lt;br /&gt;
the loop).  If the decrementor is after the integer while will evaluate the&lt;br /&gt;
value and then that value gets decreased.  This allows certain freedoms in&lt;br /&gt;
logic of code and allows a sort of compactness in order to screw with your&lt;br /&gt;
perception and natural logic.&lt;br /&gt;
&lt;br /&gt;
Much like decrementing operations C also has a few different ways to loop.&lt;br /&gt;
&lt;br /&gt;
 do {&lt;br /&gt;
        something;&lt;br /&gt;
 } while(condition);&lt;br /&gt;
&lt;br /&gt;
 for (count = 10; count &amp;gt; 0; count--) {&lt;br /&gt;
        something;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Do/while loops are nice to haves when you have to enter a loop on a condition&lt;br /&gt;
but have to execute the code at least once that is within the loop.  This &lt;br /&gt;
compacts having to write out the same code twice.  for() loops are very &lt;br /&gt;
popular because the three arguments (delimited (seperated) by &#039;;&#039;).  The first&lt;br /&gt;
argument sets a value to a variable.  There can be more than one of these but&lt;br /&gt;
they have to be delimited by a comma (,).  The second argument is the check&lt;br /&gt;
condition in order to break the loop.  And the last argument is the decrementor&lt;br /&gt;
or incrementor of a value, there can be more than one again delimited by a &lt;br /&gt;
comma.  It&#039;s a nice way to compact a loop. &lt;br /&gt;
&lt;br /&gt;
I&#039;m going to go into endless loops but before I do I&#039;m going to introduce a&lt;br /&gt;
simple branch in order to break out of the loop.  Consider this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 1       while (1) {&lt;br /&gt;
 2               printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
 3               &lt;br /&gt;
 4               if (--count == 0) &lt;br /&gt;
 5                       break;&lt;br /&gt;
 6       }&lt;br /&gt;
&lt;br /&gt;
Ok line one defines the endless loop.  1 is always true and it doesn&#039;t get&lt;br /&gt;
increased nor decreased.  Line 4 introduces the if () branch, it is similar&lt;br /&gt;
to the IF/THEN also found in BASIC.  New is the == sign, and this is often&lt;br /&gt;
in confusion.  To test a value, C expects a character before an equal sign&lt;br /&gt;
so the following combinations can work:&lt;br /&gt;
&lt;br /&gt;
        == equals&lt;br /&gt;
        != does not equal&lt;br /&gt;
        &amp;lt;= less than or equal to&lt;br /&gt;
        &amp;gt;= greater than or equal to&lt;br /&gt;
&lt;br /&gt;
        &amp;lt; less than&lt;br /&gt;
        &amp;gt; greater than&lt;br /&gt;
&lt;br /&gt;
Imagine the following scenario (typo):&lt;br /&gt;
&lt;br /&gt;
        if (--count = 0) &lt;br /&gt;
                break;&lt;br /&gt;
&lt;br /&gt;
Then the loop would never exit/break because count gets decremented and then&lt;br /&gt;
assigned the value 0 and 0 is not TRUE it is FALSE.  Luckily todays GCC&lt;br /&gt;
compiler catches this and won&#039;t compile this.  The error message it spits&lt;br /&gt;
back is:&lt;br /&gt;
&lt;br /&gt;
test.c: In function `main&#039;:&lt;br /&gt;
test.c:9: error: invalid lvalue in assignment&lt;br /&gt;
&lt;br /&gt;
Consider we wanted to skip the part where count holds the number 5, then:&lt;br /&gt;
&lt;br /&gt;
 1       while (1) {&lt;br /&gt;
 2               if (count == 5) {&lt;br /&gt;
 3                       count--;&lt;br /&gt;
 4                       continue;&lt;br /&gt;
 5               }&lt;br /&gt;
 6       &lt;br /&gt;
 7               printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
 8               &lt;br /&gt;
 9               if (--count == 0) &lt;br /&gt;
 10                      break;&lt;br /&gt;
 11      &lt;br /&gt;
 12      }&lt;br /&gt;
&lt;br /&gt;
Notice that count has to be decremented before continuing or you&#039;d have an&lt;br /&gt;
endless loop again.&lt;br /&gt;
Remember all examples that have numbers to indicate their position need to&lt;br /&gt;
have the numbers removed.  Here is an example of the last program.&lt;br /&gt;
&lt;br /&gt;
 blah.c: 21 lines, 188 characters.&lt;br /&gt;
 neptune$ cc -o blah blah.c &lt;br /&gt;
 neptune$ ./blah | wc -l&lt;br /&gt;
       9 &lt;br /&gt;
 neptune$ &lt;br /&gt;
&lt;br /&gt;
The program &#039;wc&#039; does a word count and when passed the argument -l it will&lt;br /&gt;
count lines.  You see here that Hello, World was printed 9 times.  Thank&lt;br /&gt;
goodness for pipes or this example would be extremely boring.&lt;br /&gt;
&lt;br /&gt;
== #5 Pointers, Variables and Variables of some sorts ==&lt;br /&gt;
&lt;br /&gt;
Pointers are often seen as something hard to understand, and it is true that&lt;br /&gt;
often C programs have their bugs near pointers.  I think the problem is &lt;br /&gt;
psychological when people think there is difficulty.  I&#039;m going to start&lt;br /&gt;
fairly early with pointers so that they are covered right away.&lt;br /&gt;
&lt;br /&gt;
In C there is different types of variables.  One we covered with loops already&lt;br /&gt;
and that is the Integer (int).  There is a few others.&lt;br /&gt;
&lt;br /&gt;
 1. short                &lt;br /&gt;
 2. int          &lt;br /&gt;
 3. long&lt;br /&gt;
 4. long long            &lt;br /&gt;
 5. char         &lt;br /&gt;
 6. void&lt;br /&gt;
 7. struct                &lt;br /&gt;
 8. union&lt;br /&gt;
&lt;br /&gt;
1. short&lt;br /&gt;
&lt;br /&gt;
short is a short Integer of size 16 bits (2 bytes).  If it&#039;s signed it can&lt;br /&gt;
hold 32767 as maximum, after that it wraps around into the negative.  More&lt;br /&gt;
on this later.  Unsigned limit is 65535.&lt;br /&gt;
&lt;br /&gt;
2. int&lt;br /&gt;
&lt;br /&gt;
Integer.  We shortly covered this in the last article.  An integer is looked&lt;br /&gt;
at as a 32 bit entity (4 bytes). Signed limit is 0x7fffffff (hexadecimal) and&lt;br /&gt;
unsigned limit is 0xffffffff.  Please refer to the /usr/include/limits.h&lt;br /&gt;
header file and follow all inclusions.  There is aliases for most limits.&lt;br /&gt;
&lt;br /&gt;
3. long&lt;br /&gt;
&lt;br /&gt;
A long integer.  On 32 bit architectures this is 32 bits (4 bytes), and on &lt;br /&gt;
64 bit architectures this should be 64 bits (8 bytes).  One should put this&lt;br /&gt;
into consideration when writing portable code for different architectures.&lt;br /&gt;
&lt;br /&gt;
A new way of defining integers is to write out what they are in the code, &lt;br /&gt;
these are aliases to the defined types.  You have the following:&lt;br /&gt;
&lt;br /&gt;
 u_int8_t, int8_t - 8 bit unsigned and signed integer&lt;br /&gt;
 u_int16_t, int16_t - 16 bit unsigned and signed integer&lt;br /&gt;
 u_int32_t, int32_t - 32 bit unsigned and signed integer&lt;br /&gt;
 u_int64_t, int64_t - 64 bit unsigned and signed integer&lt;br /&gt;
&lt;br /&gt;
Now you take away the confusion but must write your own aliases (#define&#039;s)&lt;br /&gt;
for them if you want to compile these integers on old computers with old&lt;br /&gt;
compilers.  Do understand that using a 64 bit integer on a 32 bit architecture&lt;br /&gt;
is most likely going to result in having to split the integer over 2 registers,&lt;br /&gt;
this is a performance degradation and possibly not what you want when you &lt;br /&gt;
count on speed.&lt;br /&gt;
&lt;br /&gt;
4. long long&lt;br /&gt;
I believe what is meant here is the same as a int64_t (8 bytes).&lt;br /&gt;
&lt;br /&gt;
5. char&lt;br /&gt;
A char holds a byte (8 bit).  It is synonymous to 8int_t.  u_char and char&lt;br /&gt;
both take up 8 bits and can be used interchangably.&lt;br /&gt;
&lt;br /&gt;
6. void&lt;br /&gt;
This is a stub.  It is used to indicate nothing you can often see this in&lt;br /&gt;
C source code when a return value of some system call is being ignored such&lt;br /&gt;
as:  &lt;br /&gt;
&lt;br /&gt;
(void)chdir(&amp;quot;/&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
The brackets indicate that it is &amp;quot;casted&amp;quot;.  The system call chdir(&amp;quot;/&amp;quot;); on&lt;br /&gt;
unix systems should always work as UNIX cannot run without a root filesystem&lt;br /&gt;
so you don&#039;t need to check for an error condition, thus void.  void consumes&lt;br /&gt;
32 bits I believe.&lt;br /&gt;
&lt;br /&gt;
7. struct&lt;br /&gt;
struct is a special type.  It comprises an object comprised out of 1 or more&lt;br /&gt;
other variables/objects.  You can build IP packet headers with structs as &lt;br /&gt;
shown in the previous example or just have a grouping of 2 integers.  Here&lt;br /&gt;
is an example:&lt;br /&gt;
&lt;br /&gt;
 struct somestruct {&lt;br /&gt;
        int a;&lt;br /&gt;
        int b;&lt;br /&gt;
 } ST;&lt;br /&gt;
&lt;br /&gt;
Accessing integer a, b then you could use:&lt;br /&gt;
&lt;br /&gt;
  ST.a = 7;&lt;br /&gt;
  ST.b = 12;&lt;br /&gt;
&lt;br /&gt;
  if (ST.a &amp;gt; ST.b)&lt;br /&gt;
        exit(1);&lt;br /&gt;
&lt;br /&gt;
[These are just examples and don&#039;t say anything in case you&#039;re trying to read&lt;br /&gt;
into these.]&lt;br /&gt;
&lt;br /&gt;
Alternatively the above struct can be defined like so:&lt;br /&gt;
&lt;br /&gt;
 struct somestruct {&lt;br /&gt;
        int a;&lt;br /&gt;
        int b;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
struct somestruct ST;&lt;br /&gt;
&lt;br /&gt;
Both ways have the same results.&lt;br /&gt;
&lt;br /&gt;
8. union&lt;br /&gt;
&lt;br /&gt;
A union is built up like a struct but the individual members overlap on each&lt;br /&gt;
other.  This is great when you want to exchange values between different &lt;br /&gt;
sized variables/objects.  Consider this:&lt;br /&gt;
&lt;br /&gt;
 union someunion {&lt;br /&gt;
        char array[4];&lt;br /&gt;
        int value;&lt;br /&gt;
 } US;&lt;br /&gt;
&lt;br /&gt;
You can then fill the value in the union US and read the individual bytes of&lt;br /&gt;
that value from a character array of the same length.  I&#039;ll get to arrays a&lt;br /&gt;
little further down.  Pretend you want to change an IP (version 4 - at the&lt;br /&gt;
time of this writing the current) address represented as a 32 bit number and&lt;br /&gt;
write out the dotted quads (as they are called in the networking world) then&lt;br /&gt;
you&#039;d have something like.&lt;br /&gt;
&lt;br /&gt;
        US.value = somevalue;&lt;br /&gt;
        printf(&amp;quot;%u.%u.%u.%u\n&amp;quot;, US.array[0], US.array[1], US.array[2], US.array[3]);&lt;br /&gt;
&lt;br /&gt;
The example is written for a big-endian machine, in order to make it portable &lt;br /&gt;
with little endian (little byte order) machines such as intel or amd processors.&lt;br /&gt;
You need to change it given the htonl(), ntohl() functions.  Read the manual&lt;br /&gt;
pages found online on UNIX systems for these functions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Another good way for a union is to find the byte order of a machine in the&lt;br /&gt;
first place.  Pretend somevalue is 0x01020304 (hexadecimal) then on big &lt;br /&gt;
endian machines you&#039;d see 1.2.3.4 and on little endian machines you should&lt;br /&gt;
see 4.3.2.1.  The order is reversed where MSB (most significant byte) becomes &lt;br /&gt;
LSB (least significant byte).&lt;br /&gt;
&lt;br /&gt;
An example on an amd64 computer:&lt;br /&gt;
&lt;br /&gt;
 neptune$ cc -o testp test.c&lt;br /&gt;
 neptune$ ./testp&lt;br /&gt;
 4.3.2.1&lt;br /&gt;
&lt;br /&gt;
I don&#039;t have a G3 or G4 Macintosh handy at the moment but you&#039;d most likely&lt;br /&gt;
see 1.2.3.4 on that computer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;Pointers and Arrays.&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Every variable type is represented by an address in the memory of your &lt;br /&gt;
computer.  That address stores the value of that variable.  Pointers allow&lt;br /&gt;
you to store another address.  Pretend you have a 32 bit computer and it&lt;br /&gt;
is capable of manipulating address space starting at address 0 all the way&lt;br /&gt;
up to 0xffffffff (hexadecimal).  This gives you a limit of 4 gigabytes of&lt;br /&gt;
memory.  So when you want to read memory in C you can use pointers.  Take&lt;br /&gt;
this example:&lt;br /&gt;
&lt;br /&gt;
        int value = 1;&lt;br /&gt;
        int anothervalue = 2;&lt;br /&gt;
        int *pv = NULL;&lt;br /&gt;
&lt;br /&gt;
Notice the asterisk (star) before pv.  This is a pointer to an integer and it&lt;br /&gt;
is declared to point to NULL (a macro representing 0).&lt;br /&gt;
&lt;br /&gt;
        pv = &amp;amp;value;&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, *pv);&lt;br /&gt;
        printf(&amp;quot;%u\n&amp;quot;, pv);&lt;br /&gt;
        pv = &amp;amp;anothervalue;&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, *pv);&lt;br /&gt;
        printf(&amp;quot;%u\n&amp;quot;, pv);&lt;br /&gt;
&lt;br /&gt;
Consider this.  when you assign the address of &amp;quot;value&amp;quot; to pv you can then &lt;br /&gt;
print the value of &amp;quot;value&amp;quot; by adding an asterisk in front of pv.  To print&lt;br /&gt;
the address that &amp;quot;value&amp;quot; resides in memory you&#039;d just print pv.  In order&lt;br /&gt;
to print the address of any value you prepend it with an ampersand (&amp;amp;). It&#039;s&lt;br /&gt;
straight forward.  Watch how this program executes on an amd64 64 bit system.&lt;br /&gt;
Here&#039;s the program first, notice I changed the variables from int to long in&lt;br /&gt;
order to fit all 64 bits of address space.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 1       #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 2       &lt;br /&gt;
 3       int&lt;br /&gt;
 4       main(void)&lt;br /&gt;
 5       {&lt;br /&gt;
 6               long value = 1;&lt;br /&gt;
 7               long anothervalue = 2;&lt;br /&gt;
 8               long *pv = NULL;&lt;br /&gt;
 9       &lt;br /&gt;
 10              pv = &amp;amp;value;&lt;br /&gt;
 11              printf(&amp;quot;%ld\n&amp;quot;, *pv);&lt;br /&gt;
 12              printf(&amp;quot;%lu\n&amp;quot;, pv);&lt;br /&gt;
 13              pv = &amp;amp;anothervalue;&lt;br /&gt;
 14              printf(&amp;quot;%ld\n&amp;quot;, *pv);&lt;br /&gt;
 15              printf(&amp;quot;%lu\n&amp;quot;, pv);&lt;br /&gt;
 16      }&lt;br /&gt;
&lt;br /&gt;
 neptune$ cc -o testp test.c &lt;br /&gt;
 neptune$ ./testp&lt;br /&gt;
 1&lt;br /&gt;
 140187732443816&lt;br /&gt;
 2&lt;br /&gt;
 140187732443808&lt;br /&gt;
&lt;br /&gt;
Notice the output.  Those addresses are really high numbers telling you a &lt;br /&gt;
few things.  Since addressed memory starts at 0 and grows to a maximum of&lt;br /&gt;
0xffffffffffffffffff (hexadecimal) on 64 bit computers there is a lot of &lt;br /&gt;
expansion room for RAM.  The computer I use has 1 gigabyte of memory.  But&lt;br /&gt;
if you look at the address of value and another value it goes way beyond&lt;br /&gt;
1 billion.  There must be memory holes between 0 and that number.  And this &lt;br /&gt;
is true because of memory address translation (MAT) which is used in UNIX.  &lt;br /&gt;
The physical memory addresses are translated to virtual memory in order to &lt;br /&gt;
protect other memory of other users in the system.  This is all handled by &lt;br /&gt;
the kernel (OS) and is invisible to the user and often irrelevant to the C &lt;br /&gt;
programmer.  Another interesting thing you&#039;ll notice is that the two &lt;br /&gt;
addresses are 8 bytes of address space apart.  Exactly the storage size of&lt;br /&gt;
a long integer (64 bits).  On a 32 bit system (i386) this would be 4 bytes.&lt;br /&gt;
&lt;br /&gt;
So pointers point to an address in memory, and because they have a type they&lt;br /&gt;
can also manipulate bytes starting at that address (offset).  This is a &lt;br /&gt;
useful feature.&lt;br /&gt;
&lt;br /&gt;
On to arrays.  You&#039;ve already seen a character array, and I&#039;ll continue on&lt;br /&gt;
this thread a little bit.  Consider this program:&lt;br /&gt;
&lt;br /&gt;
 1       int&lt;br /&gt;
 2       main(void)&lt;br /&gt;
 3       {&lt;br /&gt;
 4               char array[16];         /* array[0] through array[15] */&lt;br /&gt;
 5               int i;&lt;br /&gt;
 6       &lt;br /&gt;
 7               for (i = 0; i &amp;lt; 16; i++) {&lt;br /&gt;
 8                       array[i] = &#039;A&#039;;&lt;br /&gt;
 9               }&lt;br /&gt;
 10      &lt;br /&gt;
 11              array[15] = &#039;\0&#039;;&lt;br /&gt;
 12      &lt;br /&gt;
 13              printf(&amp;quot;%s\n&amp;quot;, array);&lt;br /&gt;
 14      }&lt;br /&gt;
 15              &lt;br /&gt;
&lt;br /&gt;
Notice the for() loop rushing from 0 through 15, at value 16 it&#039;s not less than&lt;br /&gt;
16 anymore and thus the loop breaks.  An array in C always starts at 0 upwards.&lt;br /&gt;
This is confusing at first but you get used to it (you also start at address&lt;br /&gt;
0 in the computers memory and not 1).  On line 11 the 16th character is &lt;br /&gt;
replaced with a NULL terminator which is equivalent to &#039;\0&#039;.  Finally on line&lt;br /&gt;
13 the array is printed, here is the output:&lt;br /&gt;
&lt;br /&gt;
 test.c: 17 lines, 195 characters.&lt;br /&gt;
 neptune$ cc -o testp test.c&lt;br /&gt;
 neptune$ ./testp &lt;br /&gt;
 AAAAAAAAAAAAAAA&lt;br /&gt;
 neptune$ ./testp | wc -c&lt;br /&gt;
      16&lt;br /&gt;
&lt;br /&gt;
Notice wc -c returns 16 because it counts the newline &#039;\n&#039; as well.  In C&lt;br /&gt;
every string has to be terminated with NULL, or it cannot be printed with&lt;br /&gt;
the %s argument to printf().  Consider this small modification with pointers:&lt;br /&gt;
&lt;br /&gt;
 1       #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 2       &lt;br /&gt;
 3       int&lt;br /&gt;
 4       main(void)&lt;br /&gt;
 5       {&lt;br /&gt;
 6               char array[16];         /* array[0] through array[15] */&lt;br /&gt;
 7               char *p;&lt;br /&gt;
 8               int i;&lt;br /&gt;
 9       &lt;br /&gt;
 10              for (i = 0; i &amp;lt; 16; i++) {&lt;br /&gt;
 11                      array[i] = &#039;A&#039;;&lt;br /&gt;
 12              }&lt;br /&gt;
 13      &lt;br /&gt;
 14              array[15] = &#039;\0&#039;;&lt;br /&gt;
 15              &lt;br /&gt;
 16              p = &amp;amp;array[0];&lt;br /&gt;
 17      &lt;br /&gt;
 18              while (*p) {&lt;br /&gt;
 19                      printf(&amp;quot;%c&amp;quot;, *p++);&lt;br /&gt;
 20              }&lt;br /&gt;
 21      &lt;br /&gt;
 22              printf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
 23      }&lt;br /&gt;
 24              &lt;br /&gt;
&lt;br /&gt;
 test.c: 24 lines, 254 characters.&lt;br /&gt;
 neptune$ cc -o testp test.c&lt;br /&gt;
 neptune$ ./testp &lt;br /&gt;
 AAAAAAAAAAAAAAA&lt;br /&gt;
&lt;br /&gt;
Same output as before but this time what was printed was done so one character&lt;br /&gt;
at a time.  The p pointer is assigned to point to the beginning of array.  We&lt;br /&gt;
know it&#039;s a string (because of the termination) so we can traverse through the&lt;br /&gt;
array in a loop printing the value that p points to (asterisk *) and then&lt;br /&gt;
incrementing the value of the pointer address by one.  Eventually *p on&lt;br /&gt;
line 18 will return the NULL and to while() this is FALSE and the loop will&lt;br /&gt;
break.  Then we print a newline in order to make it pretty for the next&lt;br /&gt;
prompt.  So why doesn&#039;t the value of *p increase with ++?  You&#039;d put brackets&lt;br /&gt;
around it like so:&lt;br /&gt;
&lt;br /&gt;
 printf(&amp;quot;%c&amp;quot;, (*p)++);&lt;br /&gt;
 p++;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
But that won&#039;t do much because the increment is after the value has been passed&lt;br /&gt;
to printf().  This would be better:&lt;br /&gt;
&lt;br /&gt;
 printf(&amp;quot;%c&amp;quot;, ++(*p));&lt;br /&gt;
 p++;&lt;br /&gt;
&lt;br /&gt;
 test.c: 25 lines, 263 characters.&lt;br /&gt;
 neptune$ cc -o testp test.c&lt;br /&gt;
 neptune$ ./testp&lt;br /&gt;
 BBBBBBBBBBBBBBB&lt;br /&gt;
&lt;br /&gt;
That&#039;s how it would look like.&lt;br /&gt;
&lt;br /&gt;
You can replace the char type on any of these with short or int types it&lt;br /&gt;
doesn&#039;t matter the concept is the same.  Obviously you won&#039;t be able to&lt;br /&gt;
print these types but you can work on loops that count the size of the&lt;br /&gt;
array.  The example with the while() loop for the pointers only works on&lt;br /&gt;
NULL terminated strings (character arrays).&lt;/div&gt;</summary>
		<author><name>84.170.160.72</name></author>
	</entry>
	<entry>
		<id>https://hackepedia.org/index.php?title=C_Primer&amp;diff=4517</id>
		<title>C Primer</title>
		<link rel="alternate" type="text/html" href="https://hackepedia.org/index.php?title=C_Primer&amp;diff=4517"/>
		<updated>2010-07-11T20:42:24Z</updated>

		<summary type="html">&lt;p&gt;84.170.160.72: /* The Internet Interface */  restored orginal section #3&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The [[C]] programming language was invented at [[Bell Labs]] by&lt;br /&gt;
Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
Since UNIX and C are intertwined it&#039;s good to know the basics of both.  The &amp;quot;K&amp;amp;R The (ANSI) C Programming Language&amp;quot; written by both Kernighan and Ritchie is the &amp;quot;bible&amp;quot; for C programmers.  Another reference will be  &amp;quot;The UNIX programming environment&amp;quot; written by Kernighan and&lt;br /&gt;
Rob Pike.  This book ties UNIX&#039;s development tools together such as simple&lt;br /&gt;
shell programming as well as the UNIX interface of the C programming language.&lt;br /&gt;
The classic K&amp;amp;R program that the C book starts with is:&lt;br /&gt;
&lt;br /&gt;
 int&lt;br /&gt;
 main(void)&lt;br /&gt;
 {&lt;br /&gt;
        printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You see the structure here of a program.  What you see between the { and } brackets is known as a &amp;quot;block&amp;quot; in C.  It ties a series of instructions together, whether in&lt;br /&gt;
a logical branch (often an if branch) or to define a function or procedure (same thing).  Every C program has a main()&lt;br /&gt;
[[procedure]].  This is where the program starts.  main() returns an integer&lt;br /&gt;
which is signed[1].  The return value can be caught and read by the user of &lt;br /&gt;
the program when the program exits. &lt;br /&gt;
&lt;br /&gt;
A procedure also takes one or more [[argument]]s.  In the code example above the&lt;br /&gt;
argument is [[void]], meaning it&#039;s ignored (even if there is arguments passed to&lt;br /&gt;
the procedure).  main() usually takes 2 arguments to read arguments[2] from&lt;br /&gt;
the program that executed the particular program.  There is a third argument&lt;br /&gt;
on UNIX systems that allows a users environment list to be passed into the&lt;br /&gt;
program as well.  &lt;br /&gt;
&lt;br /&gt;
Finally the instruction, printf().  As you can see it is&lt;br /&gt;
a function as well and it takes as the argument &#039;&#039;&amp;quot;Hello, World\n&amp;quot;&amp;quot;.  The \n&lt;br /&gt;
means newline (ascii hex 0a dec 10) and ensures that when the program returns&lt;br /&gt;
to a user shell that the prompt will be on the next line.  What is printed&lt;br /&gt;
in fact is &amp;quot;Hello, World&amp;quot;.  Then the program exits.  As there is no return&lt;br /&gt;
value passed with the return() or exit() function I&#039;m not sure if it will&lt;br /&gt;
be consistent.  Consistency is key in programming.&lt;br /&gt;
&lt;br /&gt;
== The UNIX Interface ==&lt;br /&gt;
&lt;br /&gt;
As indicated in the introduction, UNIX and [[C]] go together.  The OS provides an [[API]] to hook&lt;br /&gt;
into the [[kernel]] (privileged core of the OS) to make use of [[system call]]s.  &lt;br /&gt;
All input and output to and from a program is dealt with a system call, &lt;br /&gt;
calculations do not and remain in userland.  UNIX has two sides, a kernel&lt;br /&gt;
and [[userland]].  Userland is for users and administrators who request services&lt;br /&gt;
from the kernel which queues the request, and services results back as soon&lt;br /&gt;
as possible.  The kernel schedules processes (programs) in userland to run&lt;br /&gt;
on a fair share basis (at least in theory and determined by the algorithm).&lt;br /&gt;
Free UNIX clones or UNIX-like Operating Systems exists.  These are great for&lt;br /&gt;
personal study, and excellent for learning C because they are included with &lt;br /&gt;
the GNU C compiler.  In the old days one had to dual-boot a computer on &lt;br /&gt;
partitions, today one can run a [[virtual]] computer in a window and run any&lt;br /&gt;
Operating System they like. This eases switching between platforms somewhat.&lt;br /&gt;
&lt;br /&gt;
If you run Mac OS X it is based on UNIX and you can open a terminal to get &lt;br /&gt;
to the command prompt.  [[Linux]] and [[BSD]] OS&#039;s also have this capability.   &lt;br /&gt;
So when you have the C source code (ending in a .c or .cc extension) how do&lt;br /&gt;
you make it work?  In C you compile the source code into a binary code which&lt;br /&gt;
is machine language, unlike the language BASIC C is not interpreted, which&lt;br /&gt;
means the program is a script run inside a program that knows what to do with&lt;br /&gt;
the instructions.  Compiled programs do not need another program to make &lt;br /&gt;
themselves run.  Usually a compiler (such as gcc) produces assembler text&lt;br /&gt;
first round through, and passes that to an assembler to produce the binary&lt;br /&gt;
code.  This is a good feature and allows people familiar with assembler to &lt;br /&gt;
really debug the execution path (order of operations) of a program.  Here is&lt;br /&gt;
a list of useful programs:&lt;br /&gt;
&lt;br /&gt;
 [[gcc]], cc - C compiler (-o file outputs binary code, -static produces static code)&lt;br /&gt;
 [[gdb]] - debugger (allows you to step through your program for every instruction)&lt;br /&gt;
 [[ldd]] - list dynamic dependencies (if dynamically compiled, reduces size of bins)&lt;br /&gt;
 [[objdump]] - disassembler (produces assembly language from binary code)&lt;br /&gt;
 [[file]] - identifies a program (similar to ldd), useful!&lt;br /&gt;
 [[nm]] - identifies symbols in the binary code of a program, probably helpful for reverse engineering although I have never done this.&lt;br /&gt;
 [[vi]], [[ed]], [[pico]] - useful text editors to enter the C language code.&lt;br /&gt;
&lt;br /&gt;
So the small program in the introduction can be compiled like the following:&lt;br /&gt;
&lt;br /&gt;
cc -o helloworld helloworld.c&lt;br /&gt;
&lt;br /&gt;
and then the binary can be executed with ./helloworld &lt;br /&gt;
You may need to add an &amp;quot;&amp;quot;#include &amp;lt;stdio.h&amp;gt;&amp;quot;&amp;quot; to the top, which is the standard&lt;br /&gt;
C input/output library.  The .h is a header file, but we&#039;ll get to that.&lt;br /&gt;
(I hope). You can add -Wall to the command line arguements to show you all of the warnings. &lt;br /&gt;
If you want to write &amp;quot;clean&amp;quot; code, you will fix it until it has no errors. &lt;br /&gt;
&lt;br /&gt;
As soon as you run a program on UNIX and it ends there is an exit code.  Every&lt;br /&gt;
[[shell]] has a different way of querying the exit value as you face the prompt&lt;br /&gt;
again, but with the /bin/[[sh]], [[bash]] and [[ksh]] shell you can type echo $? to query the return value.&lt;br /&gt;
&lt;br /&gt;
Another great feature that UNIX offers other than opening files is pipes.  A&lt;br /&gt;
pipe (symbol | on the command prompt) allows one to direct the output of one&lt;br /&gt;
program into the input of another program and thus you create what is called&lt;br /&gt;
a pipeline.  A [[pipeline]] uses different programs that specialize on one task&lt;br /&gt;
to shape the output at the end into something useable.  Take this example&lt;br /&gt;
of the previous text; if I did:&lt;br /&gt;
&lt;br /&gt;
 $ cat c-programming | grep -A5 ^int | cat -n&lt;br /&gt;
     1  int&lt;br /&gt;
     2  main(void)&lt;br /&gt;
     3  {&lt;br /&gt;
     4          printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
     5  }&lt;br /&gt;
     6&lt;br /&gt;
&lt;br /&gt;
The output is the source code of the helloworld.c program and the -n argument&lt;br /&gt;
to cat adds a sequential line count per line.  Ok so you can put together&lt;br /&gt;
your own programs and programs &amp;quot;&amp;quot;already created&amp;quot;&amp;quot; for you to make the final &lt;br /&gt;
output. There are limits, but this is almost 40 years&lt;br /&gt;
old.&lt;br /&gt;
&lt;br /&gt;
Another important point is that if you want to make custom modifications to&lt;br /&gt;
the UNIX Operating System, you can do this and the source code is in C,&lt;br /&gt;
minor parts are written in assembly but only on really low end stuff.  The&lt;br /&gt;
C source code guarantees that you can edit any of the code you like, or hire someone to edit&lt;br /&gt;
it if you desire to do so. Unfortunately [[Apple]] discontinued [[OpenDarwin]] as far as I know,&lt;br /&gt;
but there is a certain paranoia in most corporate circles that there&lt;br /&gt;
is a loss of income if source code is revealed to scary people. It&#039;s in all our best interests to &lt;br /&gt;
ensure this mindset is corrected by the decision makers.&lt;br /&gt;
&lt;br /&gt;
Most open source operating system vendors show you the steps to turn the C&lt;br /&gt;
program code into binaries that run the final system.  All the code has to&lt;br /&gt;
be compiled which depending on your processor speed takes days to a few&lt;br /&gt;
minutes and then the system requires a reboot.  The reboot is required to&lt;br /&gt;
load the new kernel which then services everything else.&lt;br /&gt;
&lt;br /&gt;
Please see http://www.hackepedia.org for a lot of help on UNIX that I &lt;br /&gt;
contributed my time to.&lt;br /&gt;
&lt;br /&gt;
==  The Internet Interface ==&lt;br /&gt;
&lt;br /&gt;
Our Internet is closely tied to UNIX and thus C.  The original computers that&lt;br /&gt;
switched packets back and forth between Universities and Governments on the&lt;br /&gt;
old ARPAnet (predecessor of Internet) probably ran UNIX.  UNIX has a great &lt;br /&gt;
set of API&#039;s for userland to connect into the greater network.  The standard &lt;br /&gt;
of Internet API&#039;s is probably Berkeley sockets which were created on the BSD &lt;br /&gt;
variant of UNIX.  &lt;br /&gt;
&lt;br /&gt;
If network communication were chopped up into layers and you have physical&lt;br /&gt;
exchange of bits over wire or radio then this would be layer 1.  If you have&lt;br /&gt;
a standard protocol with rudamentary addresses and perhaps a checksum at the&lt;br /&gt;
back and on the Data Link you&#039;d call this layer 2.  Then if you have a more &lt;br /&gt;
complex protocol such as the Internet Protocol that reaches beyond routers&lt;br /&gt;
to form an internet you&#039;d call this a Network layer or layer 3.  Finally IP&lt;br /&gt;
carries Transport protocols such as TCP (Transmission Control Protocol) which&lt;br /&gt;
is complex and has features such as windowing, retransmissions, sequencing,&lt;br /&gt;
reception acknowledgement and so on.  And it also carries simple protocols&lt;br /&gt;
such as UDP (User Datagram Protocol) which really only defines a source port, &lt;br /&gt;
a destination port, the data length and a checksum for it all.  This is the&lt;br /&gt;
Transport layer or layer 4.  When dealing with TCP and UDP in UNIX the socket&lt;br /&gt;
API allows you limited manipulation of layer 4, but most of it is done by&lt;br /&gt;
the kernel (such as checksumming).  All you&#039;re left with is sticking in the&lt;br /&gt;
data in there and wait for the system call to return.  What the system call&lt;br /&gt;
returns determines whether you successfully sent a packet out of a computers&lt;br /&gt;
network interface or not.  You can also have RAW sockets which means you have&lt;br /&gt;
direct control over layer 3, and you have to write the header protocol,&lt;br /&gt;
checksumming, payload data and other features such as retransmissions yourself.&lt;br /&gt;
This socket mode is restricted to the superuser/root.  There is also layer 2&lt;br /&gt;
access for the real hard-core but I won&#039;t go into that just yet.&lt;br /&gt;
Ok here is a diagram from RFC 768 (UDP):&lt;br /&gt;
&lt;br /&gt;
                  0      7 8     15 16    23 24    31&lt;br /&gt;
                 +--------+--------+--------+--------+&lt;br /&gt;
                 |     Source      |   Destination   |&lt;br /&gt;
                 |      Port       |      Port       |&lt;br /&gt;
                 +--------+--------+--------+--------+&lt;br /&gt;
                 |                 |                 |&lt;br /&gt;
                 |     Length      |    Checksum     |&lt;br /&gt;
                 +--------+--------+--------+--------+&lt;br /&gt;
                 |&lt;br /&gt;
                 |          data octets ...&lt;br /&gt;
                 +---------------- ...&lt;br /&gt;
&lt;br /&gt;
                      User Datagram Header Format&lt;br /&gt;
&lt;br /&gt;
The funny numbers at the top indicate a scale, from 0 through 31.  These are&lt;br /&gt;
bits.  Each rectangle represents 16 bits in this picture and you look at it&lt;br /&gt;
from top left to right.  Something like this is easy to construct in C because&lt;br /&gt;
it coincides with the size of short unsigned integers that are part of C.&lt;br /&gt;
I&#039;m going to show you an example of how this would be constructed in C, if you&lt;br /&gt;
don&#039;t understand it, ignore it and come back to it later when you&#039;re able to.&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * this would be a definition of a UDP header&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
struct udpheader {&lt;br /&gt;
        u_int16_t sport;&lt;br /&gt;
        u_int16_t dport;&lt;br /&gt;
        u_int16_t len;&lt;br /&gt;
        u_int16_t csum;&lt;br /&gt;
};&lt;br /&gt;
                &lt;br /&gt;
Notice that a UDP packet is limited to 65535 bytes due to the integer limit&lt;br /&gt;
that one can pack into a 16 bit integer.  So if you had a 1400 byte packet&lt;br /&gt;
you could do the following.&lt;br /&gt;
&lt;br /&gt;
u_char packet[1400];&lt;br /&gt;
u_char *data;&lt;br /&gt;
struct udpheader *uh;&lt;br /&gt;
&lt;br /&gt;
uh = (struct udpheader *)&amp;amp;packet[0];&lt;br /&gt;
uh-&amp;gt;sport = 1024;&lt;br /&gt;
uh-&amp;gt;dport = 53;&lt;br /&gt;
uh-&amp;gt;len = 1400;&lt;br /&gt;
uh-&amp;gt;csum = 0;&lt;br /&gt;
&lt;br /&gt;
data = &amp;amp;packet[sizeof(struct udpheader)];&lt;br /&gt;
&lt;br /&gt;
There is a few caveats to this example (it&#039;s only an example).  It would work&lt;br /&gt;
on a powerpc processor, or sparc processor as written, but not on intel (i386)&lt;br /&gt;
processors.  There is a law of ordering bits of packets on the internet and&lt;br /&gt;
they require the least significant bit to cross first right through to the &lt;br /&gt;
most significant bit.  The registers on an i386 processor store a 16 bit &lt;br /&gt;
integer with the most significant bit first and least last.  This is called&lt;br /&gt;
endian-ness or byte order.  Network byte order is big endian as outlined, what&lt;br /&gt;
intel processors use is little endian byte order.  So you need a function to&lt;br /&gt;
flip the bytes in the right order.  UNIX has a few functions to do that.  This&lt;br /&gt;
is how you write the above portable.&lt;br /&gt;
&lt;br /&gt;
uh-&amp;gt;sport = htons(1024);&lt;br /&gt;
&lt;br /&gt;
htons() - host to network (short 16 bits) swap.&lt;br /&gt;
&lt;br /&gt;
Ok.  The final word.  As you can see with C you can write out the headers of&lt;br /&gt;
packets easily, it gets a little tricky when things are compressed into &lt;br /&gt;
nibbles (half-bytes - 4 bit) or even 1 bit flags.  But C can work around this.&lt;br /&gt;
Internet, UNIX and the C programming language thus seem to be made for each&lt;br /&gt;
other.  If you like any of these you&#039;ll like the rest.  I&#039;m going to get into&lt;br /&gt;
socket programming much later perhaps.&lt;br /&gt;
&lt;br /&gt;
== #4 Integers, Loops and Branches ==&lt;br /&gt;
&lt;br /&gt;
Variables in C are important.  In fact they exist in all programming languages.&lt;br /&gt;
They are used for temporary or permanent storage throughout the programs life.&lt;br /&gt;
A processor (CPU) has a set of registers that are used to do logical operations&lt;br /&gt;
on numbers stored in them.  The storage size of these registers defines the&lt;br /&gt;
storage size of integers available in any programming language.  More on this&lt;br /&gt;
later.  Often any computer is used to do boring calculations and do these at&lt;br /&gt;
rapid speeds over and over (loops). This is why we invented computers so that&lt;br /&gt;
they can do these repetitive tasks at great speeds.  Take a look at the &lt;br /&gt;
following main() function:&lt;br /&gt;
&lt;br /&gt;
 1               int&lt;br /&gt;
 2               main(void) {&lt;br /&gt;
 3               &lt;br /&gt;
 4                       int count;&lt;br /&gt;
 5               &lt;br /&gt;
 6                       count = 10;&lt;br /&gt;
 7       &lt;br /&gt;
 8                       while (count &amp;gt; 0) {&lt;br /&gt;
 9                               printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
 10                              count = count - 1;&lt;br /&gt;
 11                      }&lt;br /&gt;
 12              }&lt;br /&gt;
&lt;br /&gt;
What this program does is it define a variable of type int (integer) named &lt;br /&gt;
count (line 4).  It then assigns the value 10 (decimal) to it (line 6).  Then&lt;br /&gt;
comes a while() loop.  A while loop will continue to loop as long as the &lt;br /&gt;
condition given as its argument remains true.  In this case (on line 8) the&lt;br /&gt;
condition holds true when the value of count is greater than zero.  On line&lt;br /&gt;
9 we print our familiar string (taken from #1).  Line 10 then decrements the&lt;br /&gt;
value of count by one.  This is the simplest way to decrement by one.  C has&lt;br /&gt;
a few shortcuts to decrement such as:&lt;br /&gt;
&lt;br /&gt;
        count--;&lt;br /&gt;
        --count;&lt;br /&gt;
        count -= 1;&lt;br /&gt;
&lt;br /&gt;
All of these ways are synonymous (the same as) to what you see on line 10.&lt;br /&gt;
Similarily if you wanted to increase the value of count by one you could type:&lt;br /&gt;
&lt;br /&gt;
        count = count + 1;&lt;br /&gt;
        count++;&lt;br /&gt;
        ++count;&lt;br /&gt;
        count += 1;&lt;br /&gt;
&lt;br /&gt;
They all mean the same.  The ++ on either side has a dual functionality which&lt;br /&gt;
I will demonstrate here:&lt;br /&gt;
&lt;br /&gt;
 1       while (count--) &lt;br /&gt;
 2               printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
Notice a few differences.  The obvious decrementor has been stuffed into the&lt;br /&gt;
while condition and the while loop doesn&#039;t have a block bracket {}.  The&lt;br /&gt;
result will print 10 Hello Worlds like the above example.  Because 10 through 1&lt;br /&gt;
are positive and thus logically true while will continue.  As soon as count&lt;br /&gt;
reaches the value of 0 while() will break.  Consider the following difference:&lt;br /&gt;
&lt;br /&gt;
 1       while (--count) &lt;br /&gt;
 2               printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
Here our string will be printed only 9 times.  The reason is the following.&lt;br /&gt;
When a incrementor or decrementor is before a variable/integer the value is&lt;br /&gt;
decremented before it is evaluated in a branch condition (in order to break&lt;br /&gt;
the loop).  If the decrementor is after the integer while will evaluate the&lt;br /&gt;
value and then that value gets decreased.  This allows certain freedoms in&lt;br /&gt;
logic of code and allows a sort of compactness in order to screw with your&lt;br /&gt;
perception and natural logic.&lt;br /&gt;
&lt;br /&gt;
Much like decrementing operations C also has a few different ways to loop.&lt;br /&gt;
&lt;br /&gt;
 do {&lt;br /&gt;
        something;&lt;br /&gt;
 } while(condition);&lt;br /&gt;
&lt;br /&gt;
 for (count = 10; count &amp;gt; 0; count--) {&lt;br /&gt;
        something;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Do/while loops are nice to haves when you have to enter a loop on a condition&lt;br /&gt;
but have to execute the code at least once that is within the loop.  This &lt;br /&gt;
compacts having to write out the same code twice.  for() loops are very &lt;br /&gt;
popular because the three arguments (delimited (seperated) by &#039;;&#039;).  The first&lt;br /&gt;
argument sets a value to a variable.  There can be more than one of these but&lt;br /&gt;
they have to be delimited by a comma (,).  The second argument is the check&lt;br /&gt;
condition in order to break the loop.  And the last argument is the decrementor&lt;br /&gt;
or incrementor of a value, there can be more than one again delimited by a &lt;br /&gt;
comma.  It&#039;s a nice way to compact a loop. &lt;br /&gt;
&lt;br /&gt;
I&#039;m going to go into endless loops but before I do I&#039;m going to introduce a&lt;br /&gt;
simple branch in order to break out of the loop.  Consider this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 1       while (1) {&lt;br /&gt;
 2               printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
 3               &lt;br /&gt;
 4               if (--count == 0) &lt;br /&gt;
 5                       break;&lt;br /&gt;
 6       }&lt;br /&gt;
&lt;br /&gt;
Ok line one defines the endless loop.  1 is always true and it doesn&#039;t get&lt;br /&gt;
increased nor decreased.  Line 4 introduces the if () branch, it is similar&lt;br /&gt;
to the IF/THEN also found in BASIC.  New is the == sign, and this is often&lt;br /&gt;
in confusion.  To test a value, C expects a character before an equal sign&lt;br /&gt;
so the following combinations can work:&lt;br /&gt;
&lt;br /&gt;
        == equals&lt;br /&gt;
        != does not equal&lt;br /&gt;
        &amp;lt;= less than or equal to&lt;br /&gt;
        &amp;gt;= greater than or equal to&lt;br /&gt;
&lt;br /&gt;
        &amp;lt; less than&lt;br /&gt;
        &amp;gt; greater than&lt;br /&gt;
&lt;br /&gt;
Imagine the following scenario (typo):&lt;br /&gt;
&lt;br /&gt;
        if (--count = 0) &lt;br /&gt;
                break;&lt;br /&gt;
&lt;br /&gt;
Then the loop would never exit/break because count gets decremented and then&lt;br /&gt;
assigned the value 0 and 0 is not TRUE it is FALSE.  Luckily todays GCC&lt;br /&gt;
compiler catches this and won&#039;t compile this.  The error message it spits&lt;br /&gt;
back is:&lt;br /&gt;
&lt;br /&gt;
test.c: In function `main&#039;:&lt;br /&gt;
test.c:9: error: invalid lvalue in assignment&lt;br /&gt;
&lt;br /&gt;
Consider we wanted to skip the part where count holds the number 5, then:&lt;br /&gt;
&lt;br /&gt;
 1       while (1) {&lt;br /&gt;
 2               if (count == 5) {&lt;br /&gt;
 3                       count--;&lt;br /&gt;
 4                       continue;&lt;br /&gt;
 5               }&lt;br /&gt;
 6       &lt;br /&gt;
 7               printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
 8               &lt;br /&gt;
 9               if (--count == 0) &lt;br /&gt;
 10                      break;&lt;br /&gt;
 11      &lt;br /&gt;
 12      }&lt;br /&gt;
&lt;br /&gt;
Notice that count has to be decremented before continuing or you&#039;d have an&lt;br /&gt;
endless loop again.&lt;br /&gt;
Remember all examples that have numbers to indicate their position need to&lt;br /&gt;
have the numbers removed.  Here is an example of the last program.&lt;br /&gt;
&lt;br /&gt;
 blah.c: 21 lines, 188 characters.&lt;br /&gt;
 neptune$ cc -o blah blah.c &lt;br /&gt;
 neptune$ ./blah | wc -l&lt;br /&gt;
       9 &lt;br /&gt;
 neptune$ &lt;br /&gt;
&lt;br /&gt;
The program &#039;wc&#039; does a word count and when passed the argument -l it will&lt;br /&gt;
count lines.  You see here that Hello, World was printed 9 times.  Thank&lt;br /&gt;
goodness for pipes or this example would be extremely boring.&lt;br /&gt;
&lt;br /&gt;
== #5 Pointers, Variables and Variables of some sorts ==&lt;br /&gt;
&lt;br /&gt;
Pointers are often seen as something hard to understand, and it is true that&lt;br /&gt;
often C programs have their bugs near pointers.  I think the problem is &lt;br /&gt;
psychological when people think there is difficulty.  I&#039;m going to start&lt;br /&gt;
fairly early with pointers so that they are covered right away.&lt;br /&gt;
&lt;br /&gt;
In C there is different types of variables.  One we covered with loops already&lt;br /&gt;
and that is the Integer (int).  There is a few others.&lt;br /&gt;
&lt;br /&gt;
 1. short                &lt;br /&gt;
 2. int          &lt;br /&gt;
 3. long&lt;br /&gt;
 4. long long            &lt;br /&gt;
 5. char         &lt;br /&gt;
 6. void&lt;br /&gt;
 7. struct                &lt;br /&gt;
 8. union&lt;br /&gt;
&lt;br /&gt;
1. short&lt;br /&gt;
&lt;br /&gt;
short is a short Integer of size 16 bits (2 bytes).  If it&#039;s signed it can&lt;br /&gt;
hold 32767 as maximum, after that it wraps around into the negative.  More&lt;br /&gt;
on this later.  Unsigned limit is 65535.&lt;br /&gt;
&lt;br /&gt;
2. int&lt;br /&gt;
&lt;br /&gt;
Integer.  We shortly covered this in the last article.  An integer is looked&lt;br /&gt;
at as a 32 bit entity (4 bytes). Signed limit is 0x7fffffff (hexadecimal) and&lt;br /&gt;
unsigned limit is 0xffffffff.  Please refer to the /usr/include/limits.h&lt;br /&gt;
header file and follow all inclusions.  There is aliases for most limits.&lt;br /&gt;
&lt;br /&gt;
3. long&lt;br /&gt;
&lt;br /&gt;
A long integer.  On 32 bit architectures this is 32 bits (4 bytes), and on &lt;br /&gt;
64 bit architectures this should be 64 bits (8 bytes).  One should put this&lt;br /&gt;
into consideration when writing portable code for different architectures.&lt;br /&gt;
&lt;br /&gt;
A new way of defining integers is to write out what they are in the code, &lt;br /&gt;
these are aliases to the defined types.  You have the following:&lt;br /&gt;
&lt;br /&gt;
 u_int8_t, int8_t - 8 bit unsigned and signed integer&lt;br /&gt;
 u_int16_t, int16_t - 16 bit unsigned and signed integer&lt;br /&gt;
 u_int32_t, int32_t - 32 bit unsigned and signed integer&lt;br /&gt;
 u_int64_t, int64_t - 64 bit unsigned and signed integer&lt;br /&gt;
&lt;br /&gt;
Now you take away the confusion but must write your own aliases (#define&#039;s)&lt;br /&gt;
for them if you want to compile these integers on old computers with old&lt;br /&gt;
compilers.  Do understand that using a 64 bit integer on a 32 bit architecture&lt;br /&gt;
is most likely going to result in having to split the integer over 2 registers,&lt;br /&gt;
this is a performance degradation and possibly not what you want when you &lt;br /&gt;
count on speed.&lt;br /&gt;
&lt;br /&gt;
4. long long&lt;br /&gt;
I believe what is meant here is the same as a int64_t (8 bytes).&lt;br /&gt;
&lt;br /&gt;
5. char&lt;br /&gt;
A char holds a byte (8 bit).  It is synonymous to 8int_t.  u_char and char&lt;br /&gt;
both take up 8 bits and can be used interchangably.&lt;br /&gt;
&lt;br /&gt;
6. void&lt;br /&gt;
This is a stub.  It is used to indicate nothing you can often see this in&lt;br /&gt;
C source code when a return value of some system call is being ignored such&lt;br /&gt;
as:  &lt;br /&gt;
&lt;br /&gt;
(void)chdir(&amp;quot;/&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
The brackets indicate that it is &amp;quot;casted&amp;quot;.  The system call chdir(&amp;quot;/&amp;quot;); on&lt;br /&gt;
unix systems should always work as UNIX cannot run without a root filesystem&lt;br /&gt;
so you don&#039;t need to check for an error condition, thus void.  void consumes&lt;br /&gt;
32 bits I believe.&lt;br /&gt;
&lt;br /&gt;
7. struct&lt;br /&gt;
struct is a special type.  It comprises an object comprised out of 1 or more&lt;br /&gt;
other variables/objects.  You can build IP packet headers with structs as &lt;br /&gt;
shown in the previous example or just have a grouping of 2 integers.  Here&lt;br /&gt;
is an example:&lt;br /&gt;
&lt;br /&gt;
 struct somestruct {&lt;br /&gt;
        int a;&lt;br /&gt;
        int b;&lt;br /&gt;
 } ST;&lt;br /&gt;
&lt;br /&gt;
Accessing integer a, b then you could use:&lt;br /&gt;
&lt;br /&gt;
  ST.a = 7;&lt;br /&gt;
  ST.b = 12;&lt;br /&gt;
&lt;br /&gt;
  if (ST.a &amp;gt; ST.b)&lt;br /&gt;
        exit(1);&lt;br /&gt;
&lt;br /&gt;
[These are just examples and don&#039;t say anything in case you&#039;re trying to read&lt;br /&gt;
into these.]&lt;br /&gt;
&lt;br /&gt;
Alternatively the above struct can be defined like so:&lt;br /&gt;
&lt;br /&gt;
 struct somestruct {&lt;br /&gt;
        int a;&lt;br /&gt;
        int b;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
struct somestruct ST;&lt;br /&gt;
&lt;br /&gt;
Both ways have the same results.&lt;br /&gt;
&lt;br /&gt;
8. union&lt;br /&gt;
&lt;br /&gt;
A union is built up like a struct but the individual members overlap on each&lt;br /&gt;
other.  This is great when you want to exchange values between different &lt;br /&gt;
sized variables/objects.  Consider this:&lt;br /&gt;
&lt;br /&gt;
 union someunion {&lt;br /&gt;
        char array[4];&lt;br /&gt;
        int value;&lt;br /&gt;
 } US;&lt;br /&gt;
&lt;br /&gt;
You can then fill the value in the union US and read the individual bytes of&lt;br /&gt;
that value from a character array of the same length.  I&#039;ll get to arrays a&lt;br /&gt;
little further down.  Pretend you want to change an IP (version 4 - at the&lt;br /&gt;
time of this writing the current) address represented as a 32 bit number and&lt;br /&gt;
write out the dotted quads (as they are called in the networking world) then&lt;br /&gt;
you&#039;d have something like.&lt;br /&gt;
&lt;br /&gt;
        US.value = somevalue;&lt;br /&gt;
        printf(&amp;quot;%u.%u.%u.%u\n&amp;quot;, US.array[0], US.array[1], US.array[2], US.array[3]);&lt;br /&gt;
&lt;br /&gt;
The example is written for a big-endian machine, in order to make it portable &lt;br /&gt;
with little endian (little byte order) machines such as intel or amd processors.&lt;br /&gt;
You need to change it given the htonl(), ntohl() functions.  Read the manual&lt;br /&gt;
pages found online on UNIX systems for these functions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Another good way for a union is to find the byte order of a machine in the&lt;br /&gt;
first place.  Pretend somevalue is 0x01020304 (hexadecimal) then on big &lt;br /&gt;
endian machines you&#039;d see 1.2.3.4 and on little endian machines you should&lt;br /&gt;
see 4.3.2.1.  The order is reversed where MSB (most significant byte) becomes &lt;br /&gt;
LSB (least significant byte).&lt;br /&gt;
&lt;br /&gt;
An example on an amd64 computer:&lt;br /&gt;
&lt;br /&gt;
 neptune$ cc -o testp test.c&lt;br /&gt;
 neptune$ ./testp&lt;br /&gt;
 4.3.2.1&lt;br /&gt;
&lt;br /&gt;
I don&#039;t have a G3 or G4 Macintosh handy at the moment but you&#039;d most likely&lt;br /&gt;
see 1.2.3.4 on that computer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;Pointers and Arrays.&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Every variable type is represented by an address in the memory of your &lt;br /&gt;
computer.  That address stores the value of that variable.  Pointers allow&lt;br /&gt;
you to store another address.  Pretend you have a 32 bit computer and it&lt;br /&gt;
is capable of manipulating address space starting at address 0 all the way&lt;br /&gt;
up to 0xffffffff (hexadecimal).  This gives you a limit of 4 gigabytes of&lt;br /&gt;
memory.  So when you want to read memory in C you can use pointers.  Take&lt;br /&gt;
this example:&lt;br /&gt;
&lt;br /&gt;
        int value = 1;&lt;br /&gt;
        int anothervalue = 2;&lt;br /&gt;
        int *pv = NULL;&lt;br /&gt;
&lt;br /&gt;
Notice the asterisk (star) before pv.  This is a pointer to an integer and it&lt;br /&gt;
is declared to point to NULL (a macro representing 0).&lt;br /&gt;
&lt;br /&gt;
        pv = &amp;amp;value;&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, *pv);&lt;br /&gt;
        printf(&amp;quot;%u\n&amp;quot;, pv);&lt;br /&gt;
        pv = &amp;amp;anothervalue;&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, *pv);&lt;br /&gt;
        printf(&amp;quot;%u\n&amp;quot;, pv);&lt;br /&gt;
&lt;br /&gt;
Consider this.  when you assign the address of &amp;quot;value&amp;quot; to pv you can then &lt;br /&gt;
print the value of &amp;quot;value&amp;quot; by adding an asterisk in front of pv.  To print&lt;br /&gt;
the address that &amp;quot;value&amp;quot; resides in memory you&#039;d just print pv.  In order&lt;br /&gt;
to print the address of any value you prepend it with an ampersand (&amp;amp;). It&#039;s&lt;br /&gt;
straight forward.  Watch how this program executes on an amd64 64 bit system.&lt;br /&gt;
Here&#039;s the program first, notice I changed the variables from int to long in&lt;br /&gt;
order to fit all 64 bits of address space.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 1       #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 2       &lt;br /&gt;
 3       int&lt;br /&gt;
 4       main(void)&lt;br /&gt;
 5       {&lt;br /&gt;
 6               long value = 1;&lt;br /&gt;
 7               long anothervalue = 2;&lt;br /&gt;
 8               long *pv = NULL;&lt;br /&gt;
 9       &lt;br /&gt;
 10              pv = &amp;amp;value;&lt;br /&gt;
 11              printf(&amp;quot;%ld\n&amp;quot;, *pv);&lt;br /&gt;
 12              printf(&amp;quot;%lu\n&amp;quot;, pv);&lt;br /&gt;
 13              pv = &amp;amp;anothervalue;&lt;br /&gt;
 14              printf(&amp;quot;%ld\n&amp;quot;, *pv);&lt;br /&gt;
 15              printf(&amp;quot;%lu\n&amp;quot;, pv);&lt;br /&gt;
 16      }&lt;br /&gt;
&lt;br /&gt;
 neptune$ cc -o testp test.c &lt;br /&gt;
 neptune$ ./testp&lt;br /&gt;
 1&lt;br /&gt;
 140187732443816&lt;br /&gt;
 2&lt;br /&gt;
 140187732443808&lt;br /&gt;
&lt;br /&gt;
Notice the output.  Those addresses are really high numbers telling you a &lt;br /&gt;
few things.  Since addressed memory starts at 0 and grows to a maximum of&lt;br /&gt;
0xffffffffffffffffff (hexadecimal) on 64 bit computers there is a lot of &lt;br /&gt;
expansion room for RAM.  The computer I use has 1 gigabyte of memory.  But&lt;br /&gt;
if you look at the address of value and another value it goes way beyond&lt;br /&gt;
1 billion.  There must be memory holes between 0 and that number.  And this &lt;br /&gt;
is true because of memory address translation (MAT) which is used in UNIX.  &lt;br /&gt;
The physical memory addresses are translated to virtual memory in order to &lt;br /&gt;
protect other memory of other users in the system.  This is all handled by &lt;br /&gt;
the kernel (OS) and is invisible to the user and often irrelevant to the C &lt;br /&gt;
programmer.  Another interesting thing you&#039;ll notice is that the two &lt;br /&gt;
addresses are 8 bytes of address space apart.  Exactly the storage size of&lt;br /&gt;
a long integer (64 bits).  On a 32 bit system (i386) this would be 4 bytes.&lt;br /&gt;
&lt;br /&gt;
So pointers point to an address in memory, and because they have a type they&lt;br /&gt;
can also manipulate bytes starting at that address (offset).  This is a &lt;br /&gt;
useful feature.&lt;br /&gt;
&lt;br /&gt;
On to arrays.  You&#039;ve already seen a character array, and I&#039;ll continue on&lt;br /&gt;
this thread a little bit.  Consider this program:&lt;br /&gt;
&lt;br /&gt;
 1       int&lt;br /&gt;
 2       main(void)&lt;br /&gt;
 3       {&lt;br /&gt;
 4               char array[16];         /* array[0] through array[15] */&lt;br /&gt;
 5               int i;&lt;br /&gt;
 6       &lt;br /&gt;
 7               for (i = 0; i &amp;lt; 16; i++) {&lt;br /&gt;
 8                       array[i] = &#039;A&#039;;&lt;br /&gt;
 9               }&lt;br /&gt;
 10      &lt;br /&gt;
 11              array[15] = &#039;\0&#039;;&lt;br /&gt;
 12      &lt;br /&gt;
 13              printf(&amp;quot;%s\n&amp;quot;, array);&lt;br /&gt;
 14      }&lt;br /&gt;
 15              &lt;br /&gt;
&lt;br /&gt;
Notice the for() loop rushing from 0 through 15, at value 16 it&#039;s not less than&lt;br /&gt;
16 anymore and thus the loop breaks.  An array in C always starts at 0 upwards.&lt;br /&gt;
This is confusing at first but you get used to it (you also start at address&lt;br /&gt;
0 in the computers memory and not 1).  On line 11 the 16th character is &lt;br /&gt;
replaced with a NULL terminator which is equivalent to &#039;\0&#039;.  Finally on line&lt;br /&gt;
13 the array is printed, here is the output:&lt;br /&gt;
&lt;br /&gt;
 test.c: 17 lines, 195 characters.&lt;br /&gt;
 neptune$ cc -o testp test.c&lt;br /&gt;
 neptune$ ./testp &lt;br /&gt;
 AAAAAAAAAAAAAAA&lt;br /&gt;
 neptune$ ./testp | wc -c&lt;br /&gt;
      16&lt;br /&gt;
&lt;br /&gt;
Notice wc -c returns 16 because it counts the newline &#039;\n&#039; as well.  In C&lt;br /&gt;
every string has to be terminated with NULL, or it cannot be printed with&lt;br /&gt;
the %s argument to printf().  Consider this small modification with pointers:&lt;br /&gt;
&lt;br /&gt;
 1       #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 2       &lt;br /&gt;
 3       int&lt;br /&gt;
 4       main(void)&lt;br /&gt;
 5       {&lt;br /&gt;
 6               char array[16];         /* array[0] through array[15] */&lt;br /&gt;
 7               char *p;&lt;br /&gt;
 8               int i;&lt;br /&gt;
 9       &lt;br /&gt;
 10              for (i = 0; i &amp;lt; 16; i++) {&lt;br /&gt;
 11                      array[i] = &#039;A&#039;;&lt;br /&gt;
 12              }&lt;br /&gt;
 13      &lt;br /&gt;
 14              array[15] = &#039;\0&#039;;&lt;br /&gt;
 15              &lt;br /&gt;
 16              p = &amp;amp;array[0];&lt;br /&gt;
 17      &lt;br /&gt;
 18              while (*p) {&lt;br /&gt;
 19                      printf(&amp;quot;%c&amp;quot;, *p++);&lt;br /&gt;
 20              }&lt;br /&gt;
 21      &lt;br /&gt;
 22              printf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
 23      }&lt;br /&gt;
 24              &lt;br /&gt;
&lt;br /&gt;
 test.c: 24 lines, 254 characters.&lt;br /&gt;
 neptune$ cc -o testp test.c&lt;br /&gt;
 neptune$ ./testp &lt;br /&gt;
 AAAAAAAAAAAAAAA&lt;br /&gt;
&lt;br /&gt;
Same output as before but this time what was printed was done so one character&lt;br /&gt;
at a time.  The p pointer is assigned to point to the beginning of array.  We&lt;br /&gt;
know it&#039;s a string (because of the termination) so we can traverse through the&lt;br /&gt;
array in a loop printing the value that p points to (asterisk *) and then&lt;br /&gt;
incrementing the value of the pointer address by one.  Eventually *p on&lt;br /&gt;
line 18 will return the NULL and to while() this is FALSE and the loop will&lt;br /&gt;
break.  Then we print a newline in order to make it pretty for the next&lt;br /&gt;
prompt.  So why doesn&#039;t the value of *p increase with ++?  You&#039;d put brackets&lt;br /&gt;
around it like so:&lt;br /&gt;
&lt;br /&gt;
 printf(&amp;quot;%c&amp;quot;, (*p)++);&lt;br /&gt;
 p++;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
But that won&#039;t do much because the increment is after the value has been passed&lt;br /&gt;
to printf().  This would be better:&lt;br /&gt;
&lt;br /&gt;
 printf(&amp;quot;%c&amp;quot;, ++(*p));&lt;br /&gt;
 p++;&lt;br /&gt;
&lt;br /&gt;
 test.c: 25 lines, 263 characters.&lt;br /&gt;
 neptune$ cc -o testp test.c&lt;br /&gt;
 neptune$ ./testp&lt;br /&gt;
 BBBBBBBBBBBBBBB&lt;br /&gt;
&lt;br /&gt;
That&#039;s how it would look like.&lt;br /&gt;
&lt;br /&gt;
You can replace the char type on any of these with short or int types it&lt;br /&gt;
doesn&#039;t matter the concept is the same.  Obviously you won&#039;t be able to&lt;br /&gt;
print these types but you can work on loops that count the size of the&lt;br /&gt;
array.  The example with the while() loop for the pointers only works on&lt;br /&gt;
NULL terminated strings (character arrays).&lt;/div&gt;</summary>
		<author><name>84.170.160.72</name></author>
	</entry>
	<entry>
		<id>https://hackepedia.org/index.php?title=C_Primer&amp;diff=4516</id>
		<title>C Primer</title>
		<link rel="alternate" type="text/html" href="https://hackepedia.org/index.php?title=C_Primer&amp;diff=4516"/>
		<updated>2010-07-11T20:31:56Z</updated>

		<summary type="html">&lt;p&gt;84.170.160.72: /* #3 The Internet Interface */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The [[C]] programming language was invented at [[Bell Labs]] by&lt;br /&gt;
Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
Since UNIX and C are intertwined it&#039;s good to know the basics of both.  The &amp;quot;K&amp;amp;R The (ANSI) C Programming Language&amp;quot; written by both Kernighan and Ritchie is the &amp;quot;bible&amp;quot; for C programmers.  Another reference will be  &amp;quot;The UNIX programming environment&amp;quot; written by Kernighan and&lt;br /&gt;
Rob Pike.  This book ties UNIX&#039;s development tools together such as simple&lt;br /&gt;
shell programming as well as the UNIX interface of the C programming language.&lt;br /&gt;
The classic K&amp;amp;R program that the C book starts with is:&lt;br /&gt;
&lt;br /&gt;
 int&lt;br /&gt;
 main(void)&lt;br /&gt;
 {&lt;br /&gt;
        printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You see the structure here of a program.  What you see between the { and } brackets is known as a &amp;quot;block&amp;quot; in C.  It ties a series of instructions together, whether in&lt;br /&gt;
a logical branch (often an if branch) or to define a function or procedure (same thing).  Every C program has a main()&lt;br /&gt;
[[procedure]].  This is where the program starts.  main() returns an integer&lt;br /&gt;
which is signed[1].  The return value can be caught and read by the user of &lt;br /&gt;
the program when the program exits. &lt;br /&gt;
&lt;br /&gt;
A procedure also takes one or more [[argument]]s.  In the code example above the&lt;br /&gt;
argument is [[void]], meaning it&#039;s ignored (even if there is arguments passed to&lt;br /&gt;
the procedure).  main() usually takes 2 arguments to read arguments[2] from&lt;br /&gt;
the program that executed the particular program.  There is a third argument&lt;br /&gt;
on UNIX systems that allows a users environment list to be passed into the&lt;br /&gt;
program as well.  &lt;br /&gt;
&lt;br /&gt;
Finally the instruction, printf().  As you can see it is&lt;br /&gt;
a function as well and it takes as the argument &#039;&#039;&amp;quot;Hello, World\n&amp;quot;&amp;quot;.  The \n&lt;br /&gt;
means newline (ascii hex 0a dec 10) and ensures that when the program returns&lt;br /&gt;
to a user shell that the prompt will be on the next line.  What is printed&lt;br /&gt;
in fact is &amp;quot;Hello, World&amp;quot;.  Then the program exits.  As there is no return&lt;br /&gt;
value passed with the return() or exit() function I&#039;m not sure if it will&lt;br /&gt;
be consistent.  Consistency is key in programming.&lt;br /&gt;
&lt;br /&gt;
== The UNIX Interface ==&lt;br /&gt;
&lt;br /&gt;
As indicated in the introduction, UNIX and [[C]] go together.  The OS provides an [[API]] to hook&lt;br /&gt;
into the [[kernel]] (privileged core of the OS) to make use of [[system call]]s.  &lt;br /&gt;
All input and output to and from a program is dealt with a system call, &lt;br /&gt;
calculations do not and remain in userland.  UNIX has two sides, a kernel&lt;br /&gt;
and [[userland]].  Userland is for users and administrators who request services&lt;br /&gt;
from the kernel which queues the request, and services results back as soon&lt;br /&gt;
as possible.  The kernel schedules processes (programs) in userland to run&lt;br /&gt;
on a fair share basis (at least in theory and determined by the algorithm).&lt;br /&gt;
Free UNIX clones or UNIX-like Operating Systems exists.  These are great for&lt;br /&gt;
personal study, and excellent for learning C because they are included with &lt;br /&gt;
the GNU C compiler.  In the old days one had to dual-boot a computer on &lt;br /&gt;
partitions, today one can run a [[virtual]] computer in a window and run any&lt;br /&gt;
Operating System they like. This eases switching between platforms somewhat.&lt;br /&gt;
&lt;br /&gt;
If you run Mac OS X it is based on UNIX and you can open a terminal to get &lt;br /&gt;
to the command prompt.  [[Linux]] and [[BSD]] OS&#039;s also have this capability.   &lt;br /&gt;
So when you have the C source code (ending in a .c or .cc extension) how do&lt;br /&gt;
you make it work?  In C you compile the source code into a binary code which&lt;br /&gt;
is machine language, unlike the language BASIC C is not interpreted, which&lt;br /&gt;
means the program is a script run inside a program that knows what to do with&lt;br /&gt;
the instructions.  Compiled programs do not need another program to make &lt;br /&gt;
themselves run.  Usually a compiler (such as gcc) produces assembler text&lt;br /&gt;
first round through, and passes that to an assembler to produce the binary&lt;br /&gt;
code.  This is a good feature and allows people familiar with assembler to &lt;br /&gt;
really debug the execution path (order of operations) of a program.  Here is&lt;br /&gt;
a list of useful programs:&lt;br /&gt;
&lt;br /&gt;
 [[gcc]], cc - C compiler (-o file outputs binary code, -static produces static code)&lt;br /&gt;
 [[gdb]] - debugger (allows you to step through your program for every instruction)&lt;br /&gt;
 [[ldd]] - list dynamic dependencies (if dynamically compiled, reduces size of bins)&lt;br /&gt;
 [[objdump]] - disassembler (produces assembly language from binary code)&lt;br /&gt;
 [[file]] - identifies a program (similar to ldd), useful!&lt;br /&gt;
 [[nm]] - identifies symbols in the binary code of a program, probably helpful for reverse engineering although I have never done this.&lt;br /&gt;
 [[vi]], [[ed]], [[pico]] - useful text editors to enter the C language code.&lt;br /&gt;
&lt;br /&gt;
So the small program in the introduction can be compiled like the following:&lt;br /&gt;
&lt;br /&gt;
cc -o helloworld helloworld.c&lt;br /&gt;
&lt;br /&gt;
and then the binary can be executed with ./helloworld &lt;br /&gt;
You may need to add an &amp;quot;&amp;quot;#include &amp;lt;stdio.h&amp;gt;&amp;quot;&amp;quot; to the top, which is the standard&lt;br /&gt;
C input/output library.  The .h is a header file, but we&#039;ll get to that.&lt;br /&gt;
(I hope). You can add -Wall to the command line arguements to show you all of the warnings. &lt;br /&gt;
If you want to write &amp;quot;clean&amp;quot; code, you will fix it until it has no errors. &lt;br /&gt;
&lt;br /&gt;
As soon as you run a program on UNIX and it ends there is an exit code.  Every&lt;br /&gt;
[[shell]] has a different way of querying the exit value as you face the prompt&lt;br /&gt;
again, but with the /bin/[[sh]], [[bash]] and [[ksh]] shell you can type echo $? to query the return value.&lt;br /&gt;
&lt;br /&gt;
Another great feature that UNIX offers other than opening files is pipes.  A&lt;br /&gt;
pipe (symbol | on the command prompt) allows one to direct the output of one&lt;br /&gt;
program into the input of another program and thus you create what is called&lt;br /&gt;
a pipeline.  A [[pipeline]] uses different programs that specialize on one task&lt;br /&gt;
to shape the output at the end into something useable.  Take this example&lt;br /&gt;
of the previous text; if I did:&lt;br /&gt;
&lt;br /&gt;
 $ cat c-programming | grep -A5 ^int | cat -n&lt;br /&gt;
     1  int&lt;br /&gt;
     2  main(void)&lt;br /&gt;
     3  {&lt;br /&gt;
     4          printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
     5  }&lt;br /&gt;
     6&lt;br /&gt;
&lt;br /&gt;
The output is the source code of the helloworld.c program and the -n argument&lt;br /&gt;
to cat adds a sequential line count per line.  Ok so you can put together&lt;br /&gt;
your own programs and programs &amp;quot;&amp;quot;already created&amp;quot;&amp;quot; for you to make the final &lt;br /&gt;
output. There are limits, but this is almost 40 years&lt;br /&gt;
old.&lt;br /&gt;
&lt;br /&gt;
Another important point is that if you want to make custom modifications to&lt;br /&gt;
the UNIX Operating System, you can do this and the source code is in C,&lt;br /&gt;
minor parts are written in assembly but only on really low end stuff.  The&lt;br /&gt;
C source code guarantees that you can edit any of the code you like, or hire someone to edit&lt;br /&gt;
it if you desire to do so. Unfortunately [[Apple]] discontinued [[OpenDarwin]] as far as I know,&lt;br /&gt;
but there is a certain paranoia in most corporate circles that there&lt;br /&gt;
is a loss of income if source code is revealed to scary people. It&#039;s in all our best interests to &lt;br /&gt;
ensure this mindset is corrected by the decision makers.&lt;br /&gt;
&lt;br /&gt;
Most open source operating system vendors show you the steps to turn the C&lt;br /&gt;
program code into binaries that run the final system.  All the code has to&lt;br /&gt;
be compiled which depending on your processor speed takes days to a few&lt;br /&gt;
minutes and then the system requires a reboot.  The reboot is required to&lt;br /&gt;
load the new kernel which then services everything else.&lt;br /&gt;
&lt;br /&gt;
Please see http://www.hackepedia.org for a lot of help on UNIX that I &lt;br /&gt;
contributed my time to.&lt;br /&gt;
&lt;br /&gt;
==  The Internet Interface ==&lt;br /&gt;
&lt;br /&gt;
This section got lost.  I&#039;ll try to write something here in the future.&lt;br /&gt;
&lt;br /&gt;
Since UNIX was re-written in C and later an internet stack was added to UNIX it was natural to also write it in C.&lt;br /&gt;
Berkeley sockets are the most popular way of dealing with the Internet in a C program which uses system calls to speak to the kernel which in turn speaks with the network.&lt;br /&gt;
&lt;br /&gt;
== #4 Integers, Loops and Branches ==&lt;br /&gt;
&lt;br /&gt;
Variables in C are important.  In fact they exist in all programming languages.&lt;br /&gt;
They are used for temporary or permanent storage throughout the programs life.&lt;br /&gt;
A processor (CPU) has a set of registers that are used to do logical operations&lt;br /&gt;
on numbers stored in them.  The storage size of these registers defines the&lt;br /&gt;
storage size of integers available in any programming language.  More on this&lt;br /&gt;
later.  Often any computer is used to do boring calculations and do these at&lt;br /&gt;
rapid speeds over and over (loops). This is why we invented computers so that&lt;br /&gt;
they can do these repetitive tasks at great speeds.  Take a look at the &lt;br /&gt;
following main() function:&lt;br /&gt;
&lt;br /&gt;
 1               int&lt;br /&gt;
 2               main(void) {&lt;br /&gt;
 3               &lt;br /&gt;
 4                       int count;&lt;br /&gt;
 5               &lt;br /&gt;
 6                       count = 10;&lt;br /&gt;
 7       &lt;br /&gt;
 8                       while (count &amp;gt; 0) {&lt;br /&gt;
 9                               printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
 10                              count = count - 1;&lt;br /&gt;
 11                      }&lt;br /&gt;
 12              }&lt;br /&gt;
&lt;br /&gt;
What this program does is it define a variable of type int (integer) named &lt;br /&gt;
count (line 4).  It then assigns the value 10 (decimal) to it (line 6).  Then&lt;br /&gt;
comes a while() loop.  A while loop will continue to loop as long as the &lt;br /&gt;
condition given as its argument remains true.  In this case (on line 8) the&lt;br /&gt;
condition holds true when the value of count is greater than zero.  On line&lt;br /&gt;
9 we print our familiar string (taken from #1).  Line 10 then decrements the&lt;br /&gt;
value of count by one.  This is the simplest way to decrement by one.  C has&lt;br /&gt;
a few shortcuts to decrement such as:&lt;br /&gt;
&lt;br /&gt;
        count--;&lt;br /&gt;
        --count;&lt;br /&gt;
        count -= 1;&lt;br /&gt;
&lt;br /&gt;
All of these ways are synonymous (the same as) to what you see on line 10.&lt;br /&gt;
Similarily if you wanted to increase the value of count by one you could type:&lt;br /&gt;
&lt;br /&gt;
        count = count + 1;&lt;br /&gt;
        count++;&lt;br /&gt;
        ++count;&lt;br /&gt;
        count += 1;&lt;br /&gt;
&lt;br /&gt;
They all mean the same.  The ++ on either side has a dual functionality which&lt;br /&gt;
I will demonstrate here:&lt;br /&gt;
&lt;br /&gt;
 1       while (count--) &lt;br /&gt;
 2               printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
Notice a few differences.  The obvious decrementor has been stuffed into the&lt;br /&gt;
while condition and the while loop doesn&#039;t have a block bracket {}.  The&lt;br /&gt;
result will print 10 Hello Worlds like the above example.  Because 10 through 1&lt;br /&gt;
are positive and thus logically true while will continue.  As soon as count&lt;br /&gt;
reaches the value of 0 while() will break.  Consider the following difference:&lt;br /&gt;
&lt;br /&gt;
 1       while (--count) &lt;br /&gt;
 2               printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
Here our string will be printed only 9 times.  The reason is the following.&lt;br /&gt;
When a incrementor or decrementor is before a variable/integer the value is&lt;br /&gt;
decremented before it is evaluated in a branch condition (in order to break&lt;br /&gt;
the loop).  If the decrementor is after the integer while will evaluate the&lt;br /&gt;
value and then that value gets decreased.  This allows certain freedoms in&lt;br /&gt;
logic of code and allows a sort of compactness in order to screw with your&lt;br /&gt;
perception and natural logic.&lt;br /&gt;
&lt;br /&gt;
Much like decrementing operations C also has a few different ways to loop.&lt;br /&gt;
&lt;br /&gt;
 do {&lt;br /&gt;
        something;&lt;br /&gt;
 } while(condition);&lt;br /&gt;
&lt;br /&gt;
 for (count = 10; count &amp;gt; 0; count--) {&lt;br /&gt;
        something;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Do/while loops are nice to haves when you have to enter a loop on a condition&lt;br /&gt;
but have to execute the code at least once that is within the loop.  This &lt;br /&gt;
compacts having to write out the same code twice.  for() loops are very &lt;br /&gt;
popular because the three arguments (delimited (seperated) by &#039;;&#039;).  The first&lt;br /&gt;
argument sets a value to a variable.  There can be more than one of these but&lt;br /&gt;
they have to be delimited by a comma (,).  The second argument is the check&lt;br /&gt;
condition in order to break the loop.  And the last argument is the decrementor&lt;br /&gt;
or incrementor of a value, there can be more than one again delimited by a &lt;br /&gt;
comma.  It&#039;s a nice way to compact a loop. &lt;br /&gt;
&lt;br /&gt;
I&#039;m going to go into endless loops but before I do I&#039;m going to introduce a&lt;br /&gt;
simple branch in order to break out of the loop.  Consider this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 1       while (1) {&lt;br /&gt;
 2               printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
 3               &lt;br /&gt;
 4               if (--count == 0) &lt;br /&gt;
 5                       break;&lt;br /&gt;
 6       }&lt;br /&gt;
&lt;br /&gt;
Ok line one defines the endless loop.  1 is always true and it doesn&#039;t get&lt;br /&gt;
increased nor decreased.  Line 4 introduces the if () branch, it is similar&lt;br /&gt;
to the IF/THEN also found in BASIC.  New is the == sign, and this is often&lt;br /&gt;
in confusion.  To test a value, C expects a character before an equal sign&lt;br /&gt;
so the following combinations can work:&lt;br /&gt;
&lt;br /&gt;
        == equals&lt;br /&gt;
        != does not equal&lt;br /&gt;
        &amp;lt;= less than or equal to&lt;br /&gt;
        &amp;gt;= greater than or equal to&lt;br /&gt;
&lt;br /&gt;
        &amp;lt; less than&lt;br /&gt;
        &amp;gt; greater than&lt;br /&gt;
&lt;br /&gt;
Imagine the following scenario (typo):&lt;br /&gt;
&lt;br /&gt;
        if (--count = 0) &lt;br /&gt;
                break;&lt;br /&gt;
&lt;br /&gt;
Then the loop would never exit/break because count gets decremented and then&lt;br /&gt;
assigned the value 0 and 0 is not TRUE it is FALSE.  Luckily todays GCC&lt;br /&gt;
compiler catches this and won&#039;t compile this.  The error message it spits&lt;br /&gt;
back is:&lt;br /&gt;
&lt;br /&gt;
test.c: In function `main&#039;:&lt;br /&gt;
test.c:9: error: invalid lvalue in assignment&lt;br /&gt;
&lt;br /&gt;
Consider we wanted to skip the part where count holds the number 5, then:&lt;br /&gt;
&lt;br /&gt;
 1       while (1) {&lt;br /&gt;
 2               if (count == 5) {&lt;br /&gt;
 3                       count--;&lt;br /&gt;
 4                       continue;&lt;br /&gt;
 5               }&lt;br /&gt;
 6       &lt;br /&gt;
 7               printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
 8               &lt;br /&gt;
 9               if (--count == 0) &lt;br /&gt;
 10                      break;&lt;br /&gt;
 11      &lt;br /&gt;
 12      }&lt;br /&gt;
&lt;br /&gt;
Notice that count has to be decremented before continuing or you&#039;d have an&lt;br /&gt;
endless loop again.&lt;br /&gt;
Remember all examples that have numbers to indicate their position need to&lt;br /&gt;
have the numbers removed.  Here is an example of the last program.&lt;br /&gt;
&lt;br /&gt;
 blah.c: 21 lines, 188 characters.&lt;br /&gt;
 neptune$ cc -o blah blah.c &lt;br /&gt;
 neptune$ ./blah | wc -l&lt;br /&gt;
       9 &lt;br /&gt;
 neptune$ &lt;br /&gt;
&lt;br /&gt;
The program &#039;wc&#039; does a word count and when passed the argument -l it will&lt;br /&gt;
count lines.  You see here that Hello, World was printed 9 times.  Thank&lt;br /&gt;
goodness for pipes or this example would be extremely boring.&lt;br /&gt;
&lt;br /&gt;
== #5 Pointers, Variables and Variables of some sorts ==&lt;br /&gt;
&lt;br /&gt;
Pointers are often seen as something hard to understand, and it is true that&lt;br /&gt;
often C programs have their bugs near pointers.  I think the problem is &lt;br /&gt;
psychological when people think there is difficulty.  I&#039;m going to start&lt;br /&gt;
fairly early with pointers so that they are covered right away.&lt;br /&gt;
&lt;br /&gt;
In C there is different types of variables.  One we covered with loops already&lt;br /&gt;
and that is the Integer (int).  There is a few others.&lt;br /&gt;
&lt;br /&gt;
 1. short                &lt;br /&gt;
 2. int          &lt;br /&gt;
 3. long&lt;br /&gt;
 4. long long            &lt;br /&gt;
 5. char         &lt;br /&gt;
 6. void&lt;br /&gt;
 7. struct                &lt;br /&gt;
 8. union&lt;br /&gt;
&lt;br /&gt;
1. short&lt;br /&gt;
&lt;br /&gt;
short is a short Integer of size 16 bits (2 bytes).  If it&#039;s signed it can&lt;br /&gt;
hold 32767 as maximum, after that it wraps around into the negative.  More&lt;br /&gt;
on this later.  Unsigned limit is 65535.&lt;br /&gt;
&lt;br /&gt;
2. int&lt;br /&gt;
&lt;br /&gt;
Integer.  We shortly covered this in the last article.  An integer is looked&lt;br /&gt;
at as a 32 bit entity (4 bytes). Signed limit is 0x7fffffff (hexadecimal) and&lt;br /&gt;
unsigned limit is 0xffffffff.  Please refer to the /usr/include/limits.h&lt;br /&gt;
header file and follow all inclusions.  There is aliases for most limits.&lt;br /&gt;
&lt;br /&gt;
3. long&lt;br /&gt;
&lt;br /&gt;
A long integer.  On 32 bit architectures this is 32 bits (4 bytes), and on &lt;br /&gt;
64 bit architectures this should be 64 bits (8 bytes).  One should put this&lt;br /&gt;
into consideration when writing portable code for different architectures.&lt;br /&gt;
&lt;br /&gt;
A new way of defining integers is to write out what they are in the code, &lt;br /&gt;
these are aliases to the defined types.  You have the following:&lt;br /&gt;
&lt;br /&gt;
 u_int8_t, int8_t - 8 bit unsigned and signed integer&lt;br /&gt;
 u_int16_t, int16_t - 16 bit unsigned and signed integer&lt;br /&gt;
 u_int32_t, int32_t - 32 bit unsigned and signed integer&lt;br /&gt;
 u_int64_t, int64_t - 64 bit unsigned and signed integer&lt;br /&gt;
&lt;br /&gt;
Now you take away the confusion but must write your own aliases (#define&#039;s)&lt;br /&gt;
for them if you want to compile these integers on old computers with old&lt;br /&gt;
compilers.  Do understand that using a 64 bit integer on a 32 bit architecture&lt;br /&gt;
is most likely going to result in having to split the integer over 2 registers,&lt;br /&gt;
this is a performance degradation and possibly not what you want when you &lt;br /&gt;
count on speed.&lt;br /&gt;
&lt;br /&gt;
4. long long&lt;br /&gt;
I believe what is meant here is the same as a int64_t (8 bytes).&lt;br /&gt;
&lt;br /&gt;
5. char&lt;br /&gt;
A char holds a byte (8 bit).  It is synonymous to 8int_t.  u_char and char&lt;br /&gt;
both take up 8 bits and can be used interchangably.&lt;br /&gt;
&lt;br /&gt;
6. void&lt;br /&gt;
This is a stub.  It is used to indicate nothing you can often see this in&lt;br /&gt;
C source code when a return value of some system call is being ignored such&lt;br /&gt;
as:  &lt;br /&gt;
&lt;br /&gt;
(void)chdir(&amp;quot;/&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
The brackets indicate that it is &amp;quot;casted&amp;quot;.  The system call chdir(&amp;quot;/&amp;quot;); on&lt;br /&gt;
unix systems should always work as UNIX cannot run without a root filesystem&lt;br /&gt;
so you don&#039;t need to check for an error condition, thus void.  void consumes&lt;br /&gt;
32 bits I believe.&lt;br /&gt;
&lt;br /&gt;
7. struct&lt;br /&gt;
struct is a special type.  It comprises an object comprised out of 1 or more&lt;br /&gt;
other variables/objects.  You can build IP packet headers with structs as &lt;br /&gt;
shown in the previous example or just have a grouping of 2 integers.  Here&lt;br /&gt;
is an example:&lt;br /&gt;
&lt;br /&gt;
 struct somestruct {&lt;br /&gt;
        int a;&lt;br /&gt;
        int b;&lt;br /&gt;
 } ST;&lt;br /&gt;
&lt;br /&gt;
Accessing integer a, b then you could use:&lt;br /&gt;
&lt;br /&gt;
  ST.a = 7;&lt;br /&gt;
  ST.b = 12;&lt;br /&gt;
&lt;br /&gt;
  if (ST.a &amp;gt; ST.b)&lt;br /&gt;
        exit(1);&lt;br /&gt;
&lt;br /&gt;
[These are just examples and don&#039;t say anything in case you&#039;re trying to read&lt;br /&gt;
into these.]&lt;br /&gt;
&lt;br /&gt;
Alternatively the above struct can be defined like so:&lt;br /&gt;
&lt;br /&gt;
 struct somestruct {&lt;br /&gt;
        int a;&lt;br /&gt;
        int b;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
struct somestruct ST;&lt;br /&gt;
&lt;br /&gt;
Both ways have the same results.&lt;br /&gt;
&lt;br /&gt;
8. union&lt;br /&gt;
&lt;br /&gt;
A union is built up like a struct but the individual members overlap on each&lt;br /&gt;
other.  This is great when you want to exchange values between different &lt;br /&gt;
sized variables/objects.  Consider this:&lt;br /&gt;
&lt;br /&gt;
 union someunion {&lt;br /&gt;
        char array[4];&lt;br /&gt;
        int value;&lt;br /&gt;
 } US;&lt;br /&gt;
&lt;br /&gt;
You can then fill the value in the union US and read the individual bytes of&lt;br /&gt;
that value from a character array of the same length.  I&#039;ll get to arrays a&lt;br /&gt;
little further down.  Pretend you want to change an IP (version 4 - at the&lt;br /&gt;
time of this writing the current) address represented as a 32 bit number and&lt;br /&gt;
write out the dotted quads (as they are called in the networking world) then&lt;br /&gt;
you&#039;d have something like.&lt;br /&gt;
&lt;br /&gt;
        US.value = somevalue;&lt;br /&gt;
        printf(&amp;quot;%u.%u.%u.%u\n&amp;quot;, US.array[0], US.array[1], US.array[2], US.array[3]);&lt;br /&gt;
&lt;br /&gt;
The example is written for a big-endian machine, in order to make it portable &lt;br /&gt;
with little endian (little byte order) machines such as intel or amd processors.&lt;br /&gt;
You need to change it given the htonl(), ntohl() functions.  Read the manual&lt;br /&gt;
pages found online on UNIX systems for these functions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Another good way for a union is to find the byte order of a machine in the&lt;br /&gt;
first place.  Pretend somevalue is 0x01020304 (hexadecimal) then on big &lt;br /&gt;
endian machines you&#039;d see 1.2.3.4 and on little endian machines you should&lt;br /&gt;
see 4.3.2.1.  The order is reversed where MSB (most significant byte) becomes &lt;br /&gt;
LSB (least significant byte).&lt;br /&gt;
&lt;br /&gt;
An example on an amd64 computer:&lt;br /&gt;
&lt;br /&gt;
 neptune$ cc -o testp test.c&lt;br /&gt;
 neptune$ ./testp&lt;br /&gt;
 4.3.2.1&lt;br /&gt;
&lt;br /&gt;
I don&#039;t have a G3 or G4 Macintosh handy at the moment but you&#039;d most likely&lt;br /&gt;
see 1.2.3.4 on that computer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;Pointers and Arrays.&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Every variable type is represented by an address in the memory of your &lt;br /&gt;
computer.  That address stores the value of that variable.  Pointers allow&lt;br /&gt;
you to store another address.  Pretend you have a 32 bit computer and it&lt;br /&gt;
is capable of manipulating address space starting at address 0 all the way&lt;br /&gt;
up to 0xffffffff (hexadecimal).  This gives you a limit of 4 gigabytes of&lt;br /&gt;
memory.  So when you want to read memory in C you can use pointers.  Take&lt;br /&gt;
this example:&lt;br /&gt;
&lt;br /&gt;
        int value = 1;&lt;br /&gt;
        int anothervalue = 2;&lt;br /&gt;
        int *pv = NULL;&lt;br /&gt;
&lt;br /&gt;
Notice the asterisk (star) before pv.  This is a pointer to an integer and it&lt;br /&gt;
is declared to point to NULL (a macro representing 0).&lt;br /&gt;
&lt;br /&gt;
        pv = &amp;amp;value;&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, *pv);&lt;br /&gt;
        printf(&amp;quot;%u\n&amp;quot;, pv);&lt;br /&gt;
        pv = &amp;amp;anothervalue;&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, *pv);&lt;br /&gt;
        printf(&amp;quot;%u\n&amp;quot;, pv);&lt;br /&gt;
&lt;br /&gt;
Consider this.  when you assign the address of &amp;quot;value&amp;quot; to pv you can then &lt;br /&gt;
print the value of &amp;quot;value&amp;quot; by adding an asterisk in front of pv.  To print&lt;br /&gt;
the address that &amp;quot;value&amp;quot; resides in memory you&#039;d just print pv.  In order&lt;br /&gt;
to print the address of any value you prepend it with an ampersand (&amp;amp;). It&#039;s&lt;br /&gt;
straight forward.  Watch how this program executes on an amd64 64 bit system.&lt;br /&gt;
Here&#039;s the program first, notice I changed the variables from int to long in&lt;br /&gt;
order to fit all 64 bits of address space.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 1       #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 2       &lt;br /&gt;
 3       int&lt;br /&gt;
 4       main(void)&lt;br /&gt;
 5       {&lt;br /&gt;
 6               long value = 1;&lt;br /&gt;
 7               long anothervalue = 2;&lt;br /&gt;
 8               long *pv = NULL;&lt;br /&gt;
 9       &lt;br /&gt;
 10              pv = &amp;amp;value;&lt;br /&gt;
 11              printf(&amp;quot;%ld\n&amp;quot;, *pv);&lt;br /&gt;
 12              printf(&amp;quot;%lu\n&amp;quot;, pv);&lt;br /&gt;
 13              pv = &amp;amp;anothervalue;&lt;br /&gt;
 14              printf(&amp;quot;%ld\n&amp;quot;, *pv);&lt;br /&gt;
 15              printf(&amp;quot;%lu\n&amp;quot;, pv);&lt;br /&gt;
 16      }&lt;br /&gt;
&lt;br /&gt;
 neptune$ cc -o testp test.c &lt;br /&gt;
 neptune$ ./testp&lt;br /&gt;
 1&lt;br /&gt;
 140187732443816&lt;br /&gt;
 2&lt;br /&gt;
 140187732443808&lt;br /&gt;
&lt;br /&gt;
Notice the output.  Those addresses are really high numbers telling you a &lt;br /&gt;
few things.  Since addressed memory starts at 0 and grows to a maximum of&lt;br /&gt;
0xffffffffffffffffff (hexadecimal) on 64 bit computers there is a lot of &lt;br /&gt;
expansion room for RAM.  The computer I use has 1 gigabyte of memory.  But&lt;br /&gt;
if you look at the address of value and another value it goes way beyond&lt;br /&gt;
1 billion.  There must be memory holes between 0 and that number.  And this &lt;br /&gt;
is true because of memory address translation (MAT) which is used in UNIX.  &lt;br /&gt;
The physical memory addresses are translated to virtual memory in order to &lt;br /&gt;
protect other memory of other users in the system.  This is all handled by &lt;br /&gt;
the kernel (OS) and is invisible to the user and often irrelevant to the C &lt;br /&gt;
programmer.  Another interesting thing you&#039;ll notice is that the two &lt;br /&gt;
addresses are 8 bytes of address space apart.  Exactly the storage size of&lt;br /&gt;
a long integer (64 bits).  On a 32 bit system (i386) this would be 4 bytes.&lt;br /&gt;
&lt;br /&gt;
So pointers point to an address in memory, and because they have a type they&lt;br /&gt;
can also manipulate bytes starting at that address (offset).  This is a &lt;br /&gt;
useful feature.&lt;br /&gt;
&lt;br /&gt;
On to arrays.  You&#039;ve already seen a character array, and I&#039;ll continue on&lt;br /&gt;
this thread a little bit.  Consider this program:&lt;br /&gt;
&lt;br /&gt;
 1       int&lt;br /&gt;
 2       main(void)&lt;br /&gt;
 3       {&lt;br /&gt;
 4               char array[16];         /* array[0] through array[15] */&lt;br /&gt;
 5               int i;&lt;br /&gt;
 6       &lt;br /&gt;
 7               for (i = 0; i &amp;lt; 16; i++) {&lt;br /&gt;
 8                       array[i] = &#039;A&#039;;&lt;br /&gt;
 9               }&lt;br /&gt;
 10      &lt;br /&gt;
 11              array[15] = &#039;\0&#039;;&lt;br /&gt;
 12      &lt;br /&gt;
 13              printf(&amp;quot;%s\n&amp;quot;, array);&lt;br /&gt;
 14      }&lt;br /&gt;
 15              &lt;br /&gt;
&lt;br /&gt;
Notice the for() loop rushing from 0 through 15, at value 16 it&#039;s not less than&lt;br /&gt;
16 anymore and thus the loop breaks.  An array in C always starts at 0 upwards.&lt;br /&gt;
This is confusing at first but you get used to it (you also start at address&lt;br /&gt;
0 in the computers memory and not 1).  On line 11 the 16th character is &lt;br /&gt;
replaced with a NULL terminator which is equivalent to &#039;\0&#039;.  Finally on line&lt;br /&gt;
13 the array is printed, here is the output:&lt;br /&gt;
&lt;br /&gt;
 test.c: 17 lines, 195 characters.&lt;br /&gt;
 neptune$ cc -o testp test.c&lt;br /&gt;
 neptune$ ./testp &lt;br /&gt;
 AAAAAAAAAAAAAAA&lt;br /&gt;
 neptune$ ./testp | wc -c&lt;br /&gt;
      16&lt;br /&gt;
&lt;br /&gt;
Notice wc -c returns 16 because it counts the newline &#039;\n&#039; as well.  In C&lt;br /&gt;
every string has to be terminated with NULL, or it cannot be printed with&lt;br /&gt;
the %s argument to printf().  Consider this small modification with pointers:&lt;br /&gt;
&lt;br /&gt;
 1       #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 2       &lt;br /&gt;
 3       int&lt;br /&gt;
 4       main(void)&lt;br /&gt;
 5       {&lt;br /&gt;
 6               char array[16];         /* array[0] through array[15] */&lt;br /&gt;
 7               char *p;&lt;br /&gt;
 8               int i;&lt;br /&gt;
 9       &lt;br /&gt;
 10              for (i = 0; i &amp;lt; 16; i++) {&lt;br /&gt;
 11                      array[i] = &#039;A&#039;;&lt;br /&gt;
 12              }&lt;br /&gt;
 13      &lt;br /&gt;
 14              array[15] = &#039;\0&#039;;&lt;br /&gt;
 15              &lt;br /&gt;
 16              p = &amp;amp;array[0];&lt;br /&gt;
 17      &lt;br /&gt;
 18              while (*p) {&lt;br /&gt;
 19                      printf(&amp;quot;%c&amp;quot;, *p++);&lt;br /&gt;
 20              }&lt;br /&gt;
 21      &lt;br /&gt;
 22              printf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
 23      }&lt;br /&gt;
 24              &lt;br /&gt;
&lt;br /&gt;
 test.c: 24 lines, 254 characters.&lt;br /&gt;
 neptune$ cc -o testp test.c&lt;br /&gt;
 neptune$ ./testp &lt;br /&gt;
 AAAAAAAAAAAAAAA&lt;br /&gt;
&lt;br /&gt;
Same output as before but this time what was printed was done so one character&lt;br /&gt;
at a time.  The p pointer is assigned to point to the beginning of array.  We&lt;br /&gt;
know it&#039;s a string (because of the termination) so we can traverse through the&lt;br /&gt;
array in a loop printing the value that p points to (asterisk *) and then&lt;br /&gt;
incrementing the value of the pointer address by one.  Eventually *p on&lt;br /&gt;
line 18 will return the NULL and to while() this is FALSE and the loop will&lt;br /&gt;
break.  Then we print a newline in order to make it pretty for the next&lt;br /&gt;
prompt.  So why doesn&#039;t the value of *p increase with ++?  You&#039;d put brackets&lt;br /&gt;
around it like so:&lt;br /&gt;
&lt;br /&gt;
 printf(&amp;quot;%c&amp;quot;, (*p)++);&lt;br /&gt;
 p++;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
But that won&#039;t do much because the increment is after the value has been passed&lt;br /&gt;
to printf().  This would be better:&lt;br /&gt;
&lt;br /&gt;
 printf(&amp;quot;%c&amp;quot;, ++(*p));&lt;br /&gt;
 p++;&lt;br /&gt;
&lt;br /&gt;
 test.c: 25 lines, 263 characters.&lt;br /&gt;
 neptune$ cc -o testp test.c&lt;br /&gt;
 neptune$ ./testp&lt;br /&gt;
 BBBBBBBBBBBBBBB&lt;br /&gt;
&lt;br /&gt;
That&#039;s how it would look like.&lt;br /&gt;
&lt;br /&gt;
You can replace the char type on any of these with short or int types it&lt;br /&gt;
doesn&#039;t matter the concept is the same.  Obviously you won&#039;t be able to&lt;br /&gt;
print these types but you can work on loops that count the size of the&lt;br /&gt;
array.  The example with the while() loop for the pointers only works on&lt;br /&gt;
NULL terminated strings (character arrays).&lt;/div&gt;</summary>
		<author><name>84.170.160.72</name></author>
	</entry>
	<entry>
		<id>https://hackepedia.org/index.php?title=C_Primer&amp;diff=4515</id>
		<title>C Primer</title>
		<link rel="alternate" type="text/html" href="https://hackepedia.org/index.php?title=C_Primer&amp;diff=4515"/>
		<updated>2010-07-11T20:22:30Z</updated>

		<summary type="html">&lt;p&gt;84.170.160.72: /* #3 The Internet Interface */  #3 is a duplicate of #2 somehow..unfortunately I lost the original document of this&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The [[C]] programming language was invented at [[Bell Labs]] by&lt;br /&gt;
Dennis Ritchie.&lt;br /&gt;
&lt;br /&gt;
Since UNIX and C are intertwined it&#039;s good to know the basics of both.  The &amp;quot;K&amp;amp;R The (ANSI) C Programming Language&amp;quot; written by both Kernighan and Ritchie is the &amp;quot;bible&amp;quot; for C programmers.  Another reference will be  &amp;quot;The UNIX programming environment&amp;quot; written by Kernighan and&lt;br /&gt;
Rob Pike.  This book ties UNIX&#039;s development tools together such as simple&lt;br /&gt;
shell programming as well as the UNIX interface of the C programming language.&lt;br /&gt;
The classic K&amp;amp;R program that the C book starts with is:&lt;br /&gt;
&lt;br /&gt;
 int&lt;br /&gt;
 main(void)&lt;br /&gt;
 {&lt;br /&gt;
        printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You see the structure here of a program.  What you see between the { and } brackets is known as a &amp;quot;block&amp;quot; in C.  It ties a series of instructions together, whether in&lt;br /&gt;
a logical branch (often an if branch) or to define a function or procedure (same thing).  Every C program has a main()&lt;br /&gt;
[[procedure]].  This is where the program starts.  main() returns an integer&lt;br /&gt;
which is signed[1].  The return value can be caught and read by the user of &lt;br /&gt;
the program when the program exits. &lt;br /&gt;
&lt;br /&gt;
A procedure also takes one or more [[argument]]s.  In the code example above the&lt;br /&gt;
argument is [[void]], meaning it&#039;s ignored (even if there is arguments passed to&lt;br /&gt;
the procedure).  main() usually takes 2 arguments to read arguments[2] from&lt;br /&gt;
the program that executed the particular program.  There is a third argument&lt;br /&gt;
on UNIX systems that allows a users environment list to be passed into the&lt;br /&gt;
program as well.  &lt;br /&gt;
&lt;br /&gt;
Finally the instruction, printf().  As you can see it is&lt;br /&gt;
a function as well and it takes as the argument &#039;&#039;&amp;quot;Hello, World\n&amp;quot;&amp;quot;.  The \n&lt;br /&gt;
means newline (ascii hex 0a dec 10) and ensures that when the program returns&lt;br /&gt;
to a user shell that the prompt will be on the next line.  What is printed&lt;br /&gt;
in fact is &amp;quot;Hello, World&amp;quot;.  Then the program exits.  As there is no return&lt;br /&gt;
value passed with the return() or exit() function I&#039;m not sure if it will&lt;br /&gt;
be consistent.  Consistency is key in programming.&lt;br /&gt;
&lt;br /&gt;
== The UNIX Interface ==&lt;br /&gt;
&lt;br /&gt;
As indicated in the introduction, UNIX and [[C]] go together.  The OS provides an [[API]] to hook&lt;br /&gt;
into the [[kernel]] (privileged core of the OS) to make use of [[system call]]s.  &lt;br /&gt;
All input and output to and from a program is dealt with a system call, &lt;br /&gt;
calculations do not and remain in userland.  UNIX has two sides, a kernel&lt;br /&gt;
and [[userland]].  Userland is for users and administrators who request services&lt;br /&gt;
from the kernel which queues the request, and services results back as soon&lt;br /&gt;
as possible.  The kernel schedules processes (programs) in userland to run&lt;br /&gt;
on a fair share basis (at least in theory and determined by the algorithm).&lt;br /&gt;
Free UNIX clones or UNIX-like Operating Systems exists.  These are great for&lt;br /&gt;
personal study, and excellent for learning C because they are included with &lt;br /&gt;
the GNU C compiler.  In the old days one had to dual-boot a computer on &lt;br /&gt;
partitions, today one can run a [[virtual]] computer in a window and run any&lt;br /&gt;
Operating System they like. This eases switching between platforms somewhat.&lt;br /&gt;
&lt;br /&gt;
If you run Mac OS X it is based on UNIX and you can open a terminal to get &lt;br /&gt;
to the command prompt.  [[Linux]] and [[BSD]] OS&#039;s also have this capability.   &lt;br /&gt;
So when you have the C source code (ending in a .c or .cc extension) how do&lt;br /&gt;
you make it work?  In C you compile the source code into a binary code which&lt;br /&gt;
is machine language, unlike the language BASIC C is not interpreted, which&lt;br /&gt;
means the program is a script run inside a program that knows what to do with&lt;br /&gt;
the instructions.  Compiled programs do not need another program to make &lt;br /&gt;
themselves run.  Usually a compiler (such as gcc) produces assembler text&lt;br /&gt;
first round through, and passes that to an assembler to produce the binary&lt;br /&gt;
code.  This is a good feature and allows people familiar with assembler to &lt;br /&gt;
really debug the execution path (order of operations) of a program.  Here is&lt;br /&gt;
a list of useful programs:&lt;br /&gt;
&lt;br /&gt;
 [[gcc]], cc - C compiler (-o file outputs binary code, -static produces static code)&lt;br /&gt;
 [[gdb]] - debugger (allows you to step through your program for every instruction)&lt;br /&gt;
 [[ldd]] - list dynamic dependencies (if dynamically compiled, reduces size of bins)&lt;br /&gt;
 [[objdump]] - disassembler (produces assembly language from binary code)&lt;br /&gt;
 [[file]] - identifies a program (similar to ldd), useful!&lt;br /&gt;
 [[nm]] - identifies symbols in the binary code of a program, probably helpful for reverse engineering although I have never done this.&lt;br /&gt;
 [[vi]], [[ed]], [[pico]] - useful text editors to enter the C language code.&lt;br /&gt;
&lt;br /&gt;
So the small program in the introduction can be compiled like the following:&lt;br /&gt;
&lt;br /&gt;
cc -o helloworld helloworld.c&lt;br /&gt;
&lt;br /&gt;
and then the binary can be executed with ./helloworld &lt;br /&gt;
You may need to add an &amp;quot;&amp;quot;#include &amp;lt;stdio.h&amp;gt;&amp;quot;&amp;quot; to the top, which is the standard&lt;br /&gt;
C input/output library.  The .h is a header file, but we&#039;ll get to that.&lt;br /&gt;
(I hope). You can add -Wall to the command line arguements to show you all of the warnings. &lt;br /&gt;
If you want to write &amp;quot;clean&amp;quot; code, you will fix it until it has no errors. &lt;br /&gt;
&lt;br /&gt;
As soon as you run a program on UNIX and it ends there is an exit code.  Every&lt;br /&gt;
[[shell]] has a different way of querying the exit value as you face the prompt&lt;br /&gt;
again, but with the /bin/[[sh]], [[bash]] and [[ksh]] shell you can type echo $? to query the return value.&lt;br /&gt;
&lt;br /&gt;
Another great feature that UNIX offers other than opening files is pipes.  A&lt;br /&gt;
pipe (symbol | on the command prompt) allows one to direct the output of one&lt;br /&gt;
program into the input of another program and thus you create what is called&lt;br /&gt;
a pipeline.  A [[pipeline]] uses different programs that specialize on one task&lt;br /&gt;
to shape the output at the end into something useable.  Take this example&lt;br /&gt;
of the previous text; if I did:&lt;br /&gt;
&lt;br /&gt;
 $ cat c-programming | grep -A5 ^int | cat -n&lt;br /&gt;
     1  int&lt;br /&gt;
     2  main(void)&lt;br /&gt;
     3  {&lt;br /&gt;
     4          printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
     5  }&lt;br /&gt;
     6&lt;br /&gt;
&lt;br /&gt;
The output is the source code of the helloworld.c program and the -n argument&lt;br /&gt;
to cat adds a sequential line count per line.  Ok so you can put together&lt;br /&gt;
your own programs and programs &amp;quot;&amp;quot;already created&amp;quot;&amp;quot; for you to make the final &lt;br /&gt;
output. There are limits, but this is almost 40 years&lt;br /&gt;
old.&lt;br /&gt;
&lt;br /&gt;
Another important point is that if you want to make custom modifications to&lt;br /&gt;
the UNIX Operating System, you can do this and the source code is in C,&lt;br /&gt;
minor parts are written in assembly but only on really low end stuff.  The&lt;br /&gt;
C source code guarantees that you can edit any of the code you like, or hire someone to edit&lt;br /&gt;
it if you desire to do so. Unfortunately [[Apple]] discontinued [[OpenDarwin]] as far as I know,&lt;br /&gt;
but there is a certain paranoia in most corporate circles that there&lt;br /&gt;
is a loss of income if source code is revealed to scary people. It&#039;s in all our best interests to &lt;br /&gt;
ensure this mindset is corrected by the decision makers.&lt;br /&gt;
&lt;br /&gt;
Most open source operating system vendors show you the steps to turn the C&lt;br /&gt;
program code into binaries that run the final system.  All the code has to&lt;br /&gt;
be compiled which depending on your processor speed takes days to a few&lt;br /&gt;
minutes and then the system requires a reboot.  The reboot is required to&lt;br /&gt;
load the new kernel which then services everything else.&lt;br /&gt;
&lt;br /&gt;
Please see http://www.hackepedia.org for a lot of help on UNIX that I &lt;br /&gt;
contributed my time to.&lt;br /&gt;
&lt;br /&gt;
==  #3 The Internet Interface ==&lt;br /&gt;
&lt;br /&gt;
This section got lost.  I&#039;ll try to write something here in the future.&lt;br /&gt;
&lt;br /&gt;
== #4 Integers, Loops and Branches ==&lt;br /&gt;
&lt;br /&gt;
Variables in C are important.  In fact they exist in all programming languages.&lt;br /&gt;
They are used for temporary or permanent storage throughout the programs life.&lt;br /&gt;
A processor (CPU) has a set of registers that are used to do logical operations&lt;br /&gt;
on numbers stored in them.  The storage size of these registers defines the&lt;br /&gt;
storage size of integers available in any programming language.  More on this&lt;br /&gt;
later.  Often any computer is used to do boring calculations and do these at&lt;br /&gt;
rapid speeds over and over (loops). This is why we invented computers so that&lt;br /&gt;
they can do these repetitive tasks at great speeds.  Take a look at the &lt;br /&gt;
following main() function:&lt;br /&gt;
&lt;br /&gt;
 1               int&lt;br /&gt;
 2               main(void) {&lt;br /&gt;
 3               &lt;br /&gt;
 4                       int count;&lt;br /&gt;
 5               &lt;br /&gt;
 6                       count = 10;&lt;br /&gt;
 7       &lt;br /&gt;
 8                       while (count &amp;gt; 0) {&lt;br /&gt;
 9                               printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
 10                              count = count - 1;&lt;br /&gt;
 11                      }&lt;br /&gt;
 12              }&lt;br /&gt;
&lt;br /&gt;
What this program does is it define a variable of type int (integer) named &lt;br /&gt;
count (line 4).  It then assigns the value 10 (decimal) to it (line 6).  Then&lt;br /&gt;
comes a while() loop.  A while loop will continue to loop as long as the &lt;br /&gt;
condition given as its argument remains true.  In this case (on line 8) the&lt;br /&gt;
condition holds true when the value of count is greater than zero.  On line&lt;br /&gt;
9 we print our familiar string (taken from #1).  Line 10 then decrements the&lt;br /&gt;
value of count by one.  This is the simplest way to decrement by one.  C has&lt;br /&gt;
a few shortcuts to decrement such as:&lt;br /&gt;
&lt;br /&gt;
        count--;&lt;br /&gt;
        --count;&lt;br /&gt;
        count -= 1;&lt;br /&gt;
&lt;br /&gt;
All of these ways are synonymous (the same as) to what you see on line 10.&lt;br /&gt;
Similarily if you wanted to increase the value of count by one you could type:&lt;br /&gt;
&lt;br /&gt;
        count = count + 1;&lt;br /&gt;
        count++;&lt;br /&gt;
        ++count;&lt;br /&gt;
        count += 1;&lt;br /&gt;
&lt;br /&gt;
They all mean the same.  The ++ on either side has a dual functionality which&lt;br /&gt;
I will demonstrate here:&lt;br /&gt;
&lt;br /&gt;
 1       while (count--) &lt;br /&gt;
 2               printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
Notice a few differences.  The obvious decrementor has been stuffed into the&lt;br /&gt;
while condition and the while loop doesn&#039;t have a block bracket {}.  The&lt;br /&gt;
result will print 10 Hello Worlds like the above example.  Because 10 through 1&lt;br /&gt;
are positive and thus logically true while will continue.  As soon as count&lt;br /&gt;
reaches the value of 0 while() will break.  Consider the following difference:&lt;br /&gt;
&lt;br /&gt;
 1       while (--count) &lt;br /&gt;
 2               printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
Here our string will be printed only 9 times.  The reason is the following.&lt;br /&gt;
When a incrementor or decrementor is before a variable/integer the value is&lt;br /&gt;
decremented before it is evaluated in a branch condition (in order to break&lt;br /&gt;
the loop).  If the decrementor is after the integer while will evaluate the&lt;br /&gt;
value and then that value gets decreased.  This allows certain freedoms in&lt;br /&gt;
logic of code and allows a sort of compactness in order to screw with your&lt;br /&gt;
perception and natural logic.&lt;br /&gt;
&lt;br /&gt;
Much like decrementing operations C also has a few different ways to loop.&lt;br /&gt;
&lt;br /&gt;
 do {&lt;br /&gt;
        something;&lt;br /&gt;
 } while(condition);&lt;br /&gt;
&lt;br /&gt;
 for (count = 10; count &amp;gt; 0; count--) {&lt;br /&gt;
        something;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Do/while loops are nice to haves when you have to enter a loop on a condition&lt;br /&gt;
but have to execute the code at least once that is within the loop.  This &lt;br /&gt;
compacts having to write out the same code twice.  for() loops are very &lt;br /&gt;
popular because the three arguments (delimited (seperated) by &#039;;&#039;).  The first&lt;br /&gt;
argument sets a value to a variable.  There can be more than one of these but&lt;br /&gt;
they have to be delimited by a comma (,).  The second argument is the check&lt;br /&gt;
condition in order to break the loop.  And the last argument is the decrementor&lt;br /&gt;
or incrementor of a value, there can be more than one again delimited by a &lt;br /&gt;
comma.  It&#039;s a nice way to compact a loop. &lt;br /&gt;
&lt;br /&gt;
I&#039;m going to go into endless loops but before I do I&#039;m going to introduce a&lt;br /&gt;
simple branch in order to break out of the loop.  Consider this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 1       while (1) {&lt;br /&gt;
 2               printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
 3               &lt;br /&gt;
 4               if (--count == 0) &lt;br /&gt;
 5                       break;&lt;br /&gt;
 6       }&lt;br /&gt;
&lt;br /&gt;
Ok line one defines the endless loop.  1 is always true and it doesn&#039;t get&lt;br /&gt;
increased nor decreased.  Line 4 introduces the if () branch, it is similar&lt;br /&gt;
to the IF/THEN also found in BASIC.  New is the == sign, and this is often&lt;br /&gt;
in confusion.  To test a value, C expects a character before an equal sign&lt;br /&gt;
so the following combinations can work:&lt;br /&gt;
&lt;br /&gt;
        == equals&lt;br /&gt;
        != does not equal&lt;br /&gt;
        &amp;lt;= less than or equal to&lt;br /&gt;
        &amp;gt;= greater than or equal to&lt;br /&gt;
&lt;br /&gt;
        &amp;lt; less than&lt;br /&gt;
        &amp;gt; greater than&lt;br /&gt;
&lt;br /&gt;
Imagine the following scenario (typo):&lt;br /&gt;
&lt;br /&gt;
        if (--count = 0) &lt;br /&gt;
                break;&lt;br /&gt;
&lt;br /&gt;
Then the loop would never exit/break because count gets decremented and then&lt;br /&gt;
assigned the value 0 and 0 is not TRUE it is FALSE.  Luckily todays GCC&lt;br /&gt;
compiler catches this and won&#039;t compile this.  The error message it spits&lt;br /&gt;
back is:&lt;br /&gt;
&lt;br /&gt;
test.c: In function `main&#039;:&lt;br /&gt;
test.c:9: error: invalid lvalue in assignment&lt;br /&gt;
&lt;br /&gt;
Consider we wanted to skip the part where count holds the number 5, then:&lt;br /&gt;
&lt;br /&gt;
 1       while (1) {&lt;br /&gt;
 2               if (count == 5) {&lt;br /&gt;
 3                       count--;&lt;br /&gt;
 4                       continue;&lt;br /&gt;
 5               }&lt;br /&gt;
 6       &lt;br /&gt;
 7               printf(&amp;quot;Hello, World\n&amp;quot;);&lt;br /&gt;
 8               &lt;br /&gt;
 9               if (--count == 0) &lt;br /&gt;
 10                      break;&lt;br /&gt;
 11      &lt;br /&gt;
 12      }&lt;br /&gt;
&lt;br /&gt;
Notice that count has to be decremented before continuing or you&#039;d have an&lt;br /&gt;
endless loop again.&lt;br /&gt;
Remember all examples that have numbers to indicate their position need to&lt;br /&gt;
have the numbers removed.  Here is an example of the last program.&lt;br /&gt;
&lt;br /&gt;
 blah.c: 21 lines, 188 characters.&lt;br /&gt;
 neptune$ cc -o blah blah.c &lt;br /&gt;
 neptune$ ./blah | wc -l&lt;br /&gt;
       9 &lt;br /&gt;
 neptune$ &lt;br /&gt;
&lt;br /&gt;
The program &#039;wc&#039; does a word count and when passed the argument -l it will&lt;br /&gt;
count lines.  You see here that Hello, World was printed 9 times.  Thank&lt;br /&gt;
goodness for pipes or this example would be extremely boring.&lt;br /&gt;
&lt;br /&gt;
== #5 Pointers, Variables and Variables of some sorts ==&lt;br /&gt;
&lt;br /&gt;
Pointers are often seen as something hard to understand, and it is true that&lt;br /&gt;
often C programs have their bugs near pointers.  I think the problem is &lt;br /&gt;
psychological when people think there is difficulty.  I&#039;m going to start&lt;br /&gt;
fairly early with pointers so that they are covered right away.&lt;br /&gt;
&lt;br /&gt;
In C there is different types of variables.  One we covered with loops already&lt;br /&gt;
and that is the Integer (int).  There is a few others.&lt;br /&gt;
&lt;br /&gt;
 1. short                &lt;br /&gt;
 2. int          &lt;br /&gt;
 3. long&lt;br /&gt;
 4. long long            &lt;br /&gt;
 5. char         &lt;br /&gt;
 6. void&lt;br /&gt;
 7. struct                &lt;br /&gt;
 8. union&lt;br /&gt;
&lt;br /&gt;
1. short&lt;br /&gt;
&lt;br /&gt;
short is a short Integer of size 16 bits (2 bytes).  If it&#039;s signed it can&lt;br /&gt;
hold 32767 as maximum, after that it wraps around into the negative.  More&lt;br /&gt;
on this later.  Unsigned limit is 65535.&lt;br /&gt;
&lt;br /&gt;
2. int&lt;br /&gt;
&lt;br /&gt;
Integer.  We shortly covered this in the last article.  An integer is looked&lt;br /&gt;
at as a 32 bit entity (4 bytes). Signed limit is 0x7fffffff (hexadecimal) and&lt;br /&gt;
unsigned limit is 0xffffffff.  Please refer to the /usr/include/limits.h&lt;br /&gt;
header file and follow all inclusions.  There is aliases for most limits.&lt;br /&gt;
&lt;br /&gt;
3. long&lt;br /&gt;
&lt;br /&gt;
A long integer.  On 32 bit architectures this is 32 bits (4 bytes), and on &lt;br /&gt;
64 bit architectures this should be 64 bits (8 bytes).  One should put this&lt;br /&gt;
into consideration when writing portable code for different architectures.&lt;br /&gt;
&lt;br /&gt;
A new way of defining integers is to write out what they are in the code, &lt;br /&gt;
these are aliases to the defined types.  You have the following:&lt;br /&gt;
&lt;br /&gt;
 u_int8_t, int8_t - 8 bit unsigned and signed integer&lt;br /&gt;
 u_int16_t, int16_t - 16 bit unsigned and signed integer&lt;br /&gt;
 u_int32_t, int32_t - 32 bit unsigned and signed integer&lt;br /&gt;
 u_int64_t, int64_t - 64 bit unsigned and signed integer&lt;br /&gt;
&lt;br /&gt;
Now you take away the confusion but must write your own aliases (#define&#039;s)&lt;br /&gt;
for them if you want to compile these integers on old computers with old&lt;br /&gt;
compilers.  Do understand that using a 64 bit integer on a 32 bit architecture&lt;br /&gt;
is most likely going to result in having to split the integer over 2 registers,&lt;br /&gt;
this is a performance degradation and possibly not what you want when you &lt;br /&gt;
count on speed.&lt;br /&gt;
&lt;br /&gt;
4. long long&lt;br /&gt;
I believe what is meant here is the same as a int64_t (8 bytes).&lt;br /&gt;
&lt;br /&gt;
5. char&lt;br /&gt;
A char holds a byte (8 bit).  It is synonymous to 8int_t.  u_char and char&lt;br /&gt;
both take up 8 bits and can be used interchangably.&lt;br /&gt;
&lt;br /&gt;
6. void&lt;br /&gt;
This is a stub.  It is used to indicate nothing you can often see this in&lt;br /&gt;
C source code when a return value of some system call is being ignored such&lt;br /&gt;
as:  &lt;br /&gt;
&lt;br /&gt;
(void)chdir(&amp;quot;/&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
The brackets indicate that it is &amp;quot;casted&amp;quot;.  The system call chdir(&amp;quot;/&amp;quot;); on&lt;br /&gt;
unix systems should always work as UNIX cannot run without a root filesystem&lt;br /&gt;
so you don&#039;t need to check for an error condition, thus void.  void consumes&lt;br /&gt;
32 bits I believe.&lt;br /&gt;
&lt;br /&gt;
7. struct&lt;br /&gt;
struct is a special type.  It comprises an object comprised out of 1 or more&lt;br /&gt;
other variables/objects.  You can build IP packet headers with structs as &lt;br /&gt;
shown in the previous example or just have a grouping of 2 integers.  Here&lt;br /&gt;
is an example:&lt;br /&gt;
&lt;br /&gt;
 struct somestruct {&lt;br /&gt;
        int a;&lt;br /&gt;
        int b;&lt;br /&gt;
 } ST;&lt;br /&gt;
&lt;br /&gt;
Accessing integer a, b then you could use:&lt;br /&gt;
&lt;br /&gt;
  ST.a = 7;&lt;br /&gt;
  ST.b = 12;&lt;br /&gt;
&lt;br /&gt;
  if (ST.a &amp;gt; ST.b)&lt;br /&gt;
        exit(1);&lt;br /&gt;
&lt;br /&gt;
[These are just examples and don&#039;t say anything in case you&#039;re trying to read&lt;br /&gt;
into these.]&lt;br /&gt;
&lt;br /&gt;
Alternatively the above struct can be defined like so:&lt;br /&gt;
&lt;br /&gt;
 struct somestruct {&lt;br /&gt;
        int a;&lt;br /&gt;
        int b;&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
struct somestruct ST;&lt;br /&gt;
&lt;br /&gt;
Both ways have the same results.&lt;br /&gt;
&lt;br /&gt;
8. union&lt;br /&gt;
&lt;br /&gt;
A union is built up like a struct but the individual members overlap on each&lt;br /&gt;
other.  This is great when you want to exchange values between different &lt;br /&gt;
sized variables/objects.  Consider this:&lt;br /&gt;
&lt;br /&gt;
 union someunion {&lt;br /&gt;
        char array[4];&lt;br /&gt;
        int value;&lt;br /&gt;
 } US;&lt;br /&gt;
&lt;br /&gt;
You can then fill the value in the union US and read the individual bytes of&lt;br /&gt;
that value from a character array of the same length.  I&#039;ll get to arrays a&lt;br /&gt;
little further down.  Pretend you want to change an IP (version 4 - at the&lt;br /&gt;
time of this writing the current) address represented as a 32 bit number and&lt;br /&gt;
write out the dotted quads (as they are called in the networking world) then&lt;br /&gt;
you&#039;d have something like.&lt;br /&gt;
&lt;br /&gt;
        US.value = somevalue;&lt;br /&gt;
        printf(&amp;quot;%u.%u.%u.%u\n&amp;quot;, US.array[0], US.array[1], US.array[2], US.array[3]);&lt;br /&gt;
&lt;br /&gt;
The example is written for a big-endian machine, in order to make it portable &lt;br /&gt;
with little endian (little byte order) machines such as intel or amd processors.&lt;br /&gt;
You need to change it given the htonl(), ntohl() functions.  Read the manual&lt;br /&gt;
pages found online on UNIX systems for these functions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Another good way for a union is to find the byte order of a machine in the&lt;br /&gt;
first place.  Pretend somevalue is 0x01020304 (hexadecimal) then on big &lt;br /&gt;
endian machines you&#039;d see 1.2.3.4 and on little endian machines you should&lt;br /&gt;
see 4.3.2.1.  The order is reversed where MSB (most significant byte) becomes &lt;br /&gt;
LSB (least significant byte).&lt;br /&gt;
&lt;br /&gt;
An example on an amd64 computer:&lt;br /&gt;
&lt;br /&gt;
 neptune$ cc -o testp test.c&lt;br /&gt;
 neptune$ ./testp&lt;br /&gt;
 4.3.2.1&lt;br /&gt;
&lt;br /&gt;
I don&#039;t have a G3 or G4 Macintosh handy at the moment but you&#039;d most likely&lt;br /&gt;
see 1.2.3.4 on that computer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;Pointers and Arrays.&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Every variable type is represented by an address in the memory of your &lt;br /&gt;
computer.  That address stores the value of that variable.  Pointers allow&lt;br /&gt;
you to store another address.  Pretend you have a 32 bit computer and it&lt;br /&gt;
is capable of manipulating address space starting at address 0 all the way&lt;br /&gt;
up to 0xffffffff (hexadecimal).  This gives you a limit of 4 gigabytes of&lt;br /&gt;
memory.  So when you want to read memory in C you can use pointers.  Take&lt;br /&gt;
this example:&lt;br /&gt;
&lt;br /&gt;
        int value = 1;&lt;br /&gt;
        int anothervalue = 2;&lt;br /&gt;
        int *pv = NULL;&lt;br /&gt;
&lt;br /&gt;
Notice the asterisk (star) before pv.  This is a pointer to an integer and it&lt;br /&gt;
is declared to point to NULL (a macro representing 0).&lt;br /&gt;
&lt;br /&gt;
        pv = &amp;amp;value;&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, *pv);&lt;br /&gt;
        printf(&amp;quot;%u\n&amp;quot;, pv);&lt;br /&gt;
        pv = &amp;amp;anothervalue;&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, *pv);&lt;br /&gt;
        printf(&amp;quot;%u\n&amp;quot;, pv);&lt;br /&gt;
&lt;br /&gt;
Consider this.  when you assign the address of &amp;quot;value&amp;quot; to pv you can then &lt;br /&gt;
print the value of &amp;quot;value&amp;quot; by adding an asterisk in front of pv.  To print&lt;br /&gt;
the address that &amp;quot;value&amp;quot; resides in memory you&#039;d just print pv.  In order&lt;br /&gt;
to print the address of any value you prepend it with an ampersand (&amp;amp;). It&#039;s&lt;br /&gt;
straight forward.  Watch how this program executes on an amd64 64 bit system.&lt;br /&gt;
Here&#039;s the program first, notice I changed the variables from int to long in&lt;br /&gt;
order to fit all 64 bits of address space.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 1       #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 2       &lt;br /&gt;
 3       int&lt;br /&gt;
 4       main(void)&lt;br /&gt;
 5       {&lt;br /&gt;
 6               long value = 1;&lt;br /&gt;
 7               long anothervalue = 2;&lt;br /&gt;
 8               long *pv = NULL;&lt;br /&gt;
 9       &lt;br /&gt;
 10              pv = &amp;amp;value;&lt;br /&gt;
 11              printf(&amp;quot;%ld\n&amp;quot;, *pv);&lt;br /&gt;
 12              printf(&amp;quot;%lu\n&amp;quot;, pv);&lt;br /&gt;
 13              pv = &amp;amp;anothervalue;&lt;br /&gt;
 14              printf(&amp;quot;%ld\n&amp;quot;, *pv);&lt;br /&gt;
 15              printf(&amp;quot;%lu\n&amp;quot;, pv);&lt;br /&gt;
 16      }&lt;br /&gt;
&lt;br /&gt;
 neptune$ cc -o testp test.c &lt;br /&gt;
 neptune$ ./testp&lt;br /&gt;
 1&lt;br /&gt;
 140187732443816&lt;br /&gt;
 2&lt;br /&gt;
 140187732443808&lt;br /&gt;
&lt;br /&gt;
Notice the output.  Those addresses are really high numbers telling you a &lt;br /&gt;
few things.  Since addressed memory starts at 0 and grows to a maximum of&lt;br /&gt;
0xffffffffffffffffff (hexadecimal) on 64 bit computers there is a lot of &lt;br /&gt;
expansion room for RAM.  The computer I use has 1 gigabyte of memory.  But&lt;br /&gt;
if you look at the address of value and another value it goes way beyond&lt;br /&gt;
1 billion.  There must be memory holes between 0 and that number.  And this &lt;br /&gt;
is true because of memory address translation (MAT) which is used in UNIX.  &lt;br /&gt;
The physical memory addresses are translated to virtual memory in order to &lt;br /&gt;
protect other memory of other users in the system.  This is all handled by &lt;br /&gt;
the kernel (OS) and is invisible to the user and often irrelevant to the C &lt;br /&gt;
programmer.  Another interesting thing you&#039;ll notice is that the two &lt;br /&gt;
addresses are 8 bytes of address space apart.  Exactly the storage size of&lt;br /&gt;
a long integer (64 bits).  On a 32 bit system (i386) this would be 4 bytes.&lt;br /&gt;
&lt;br /&gt;
So pointers point to an address in memory, and because they have a type they&lt;br /&gt;
can also manipulate bytes starting at that address (offset).  This is a &lt;br /&gt;
useful feature.&lt;br /&gt;
&lt;br /&gt;
On to arrays.  You&#039;ve already seen a character array, and I&#039;ll continue on&lt;br /&gt;
this thread a little bit.  Consider this program:&lt;br /&gt;
&lt;br /&gt;
 1       int&lt;br /&gt;
 2       main(void)&lt;br /&gt;
 3       {&lt;br /&gt;
 4               char array[16];         /* array[0] through array[15] */&lt;br /&gt;
 5               int i;&lt;br /&gt;
 6       &lt;br /&gt;
 7               for (i = 0; i &amp;lt; 16; i++) {&lt;br /&gt;
 8                       array[i] = &#039;A&#039;;&lt;br /&gt;
 9               }&lt;br /&gt;
 10      &lt;br /&gt;
 11              array[15] = &#039;\0&#039;;&lt;br /&gt;
 12      &lt;br /&gt;
 13              printf(&amp;quot;%s\n&amp;quot;, array);&lt;br /&gt;
 14      }&lt;br /&gt;
 15              &lt;br /&gt;
&lt;br /&gt;
Notice the for() loop rushing from 0 through 15, at value 16 it&#039;s not less than&lt;br /&gt;
16 anymore and thus the loop breaks.  An array in C always starts at 0 upwards.&lt;br /&gt;
This is confusing at first but you get used to it (you also start at address&lt;br /&gt;
0 in the computers memory and not 1).  On line 11 the 16th character is &lt;br /&gt;
replaced with a NULL terminator which is equivalent to &#039;\0&#039;.  Finally on line&lt;br /&gt;
13 the array is printed, here is the output:&lt;br /&gt;
&lt;br /&gt;
 test.c: 17 lines, 195 characters.&lt;br /&gt;
 neptune$ cc -o testp test.c&lt;br /&gt;
 neptune$ ./testp &lt;br /&gt;
 AAAAAAAAAAAAAAA&lt;br /&gt;
 neptune$ ./testp | wc -c&lt;br /&gt;
      16&lt;br /&gt;
&lt;br /&gt;
Notice wc -c returns 16 because it counts the newline &#039;\n&#039; as well.  In C&lt;br /&gt;
every string has to be terminated with NULL, or it cannot be printed with&lt;br /&gt;
the %s argument to printf().  Consider this small modification with pointers:&lt;br /&gt;
&lt;br /&gt;
 1       #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 2       &lt;br /&gt;
 3       int&lt;br /&gt;
 4       main(void)&lt;br /&gt;
 5       {&lt;br /&gt;
 6               char array[16];         /* array[0] through array[15] */&lt;br /&gt;
 7               char *p;&lt;br /&gt;
 8               int i;&lt;br /&gt;
 9       &lt;br /&gt;
 10              for (i = 0; i &amp;lt; 16; i++) {&lt;br /&gt;
 11                      array[i] = &#039;A&#039;;&lt;br /&gt;
 12              }&lt;br /&gt;
 13      &lt;br /&gt;
 14              array[15] = &#039;\0&#039;;&lt;br /&gt;
 15              &lt;br /&gt;
 16              p = &amp;amp;array[0];&lt;br /&gt;
 17      &lt;br /&gt;
 18              while (*p) {&lt;br /&gt;
 19                      printf(&amp;quot;%c&amp;quot;, *p++);&lt;br /&gt;
 20              }&lt;br /&gt;
 21      &lt;br /&gt;
 22              printf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
 23      }&lt;br /&gt;
 24              &lt;br /&gt;
&lt;br /&gt;
 test.c: 24 lines, 254 characters.&lt;br /&gt;
 neptune$ cc -o testp test.c&lt;br /&gt;
 neptune$ ./testp &lt;br /&gt;
 AAAAAAAAAAAAAAA&lt;br /&gt;
&lt;br /&gt;
Same output as before but this time what was printed was done so one character&lt;br /&gt;
at a time.  The p pointer is assigned to point to the beginning of array.  We&lt;br /&gt;
know it&#039;s a string (because of the termination) so we can traverse through the&lt;br /&gt;
array in a loop printing the value that p points to (asterisk *) and then&lt;br /&gt;
incrementing the value of the pointer address by one.  Eventually *p on&lt;br /&gt;
line 18 will return the NULL and to while() this is FALSE and the loop will&lt;br /&gt;
break.  Then we print a newline in order to make it pretty for the next&lt;br /&gt;
prompt.  So why doesn&#039;t the value of *p increase with ++?  You&#039;d put brackets&lt;br /&gt;
around it like so:&lt;br /&gt;
&lt;br /&gt;
 printf(&amp;quot;%c&amp;quot;, (*p)++);&lt;br /&gt;
 p++;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
But that won&#039;t do much because the increment is after the value has been passed&lt;br /&gt;
to printf().  This would be better:&lt;br /&gt;
&lt;br /&gt;
 printf(&amp;quot;%c&amp;quot;, ++(*p));&lt;br /&gt;
 p++;&lt;br /&gt;
&lt;br /&gt;
 test.c: 25 lines, 263 characters.&lt;br /&gt;
 neptune$ cc -o testp test.c&lt;br /&gt;
 neptune$ ./testp&lt;br /&gt;
 BBBBBBBBBBBBBBB&lt;br /&gt;
&lt;br /&gt;
That&#039;s how it would look like.&lt;br /&gt;
&lt;br /&gt;
You can replace the char type on any of these with short or int types it&lt;br /&gt;
doesn&#039;t matter the concept is the same.  Obviously you won&#039;t be able to&lt;br /&gt;
print these types but you can work on loops that count the size of the&lt;br /&gt;
array.  The example with the while() loop for the pointers only works on&lt;br /&gt;
NULL terminated strings (character arrays).&lt;/div&gt;</summary>
		<author><name>84.170.160.72</name></author>
	</entry>
</feed>