Advertise

Monday 16 September 2013

C Programming Part 1 - Introduction and Functions in Detail

C Programming Language Primer


This document is a quick introduction to the C programming language. It is written by a novice, and is intended for use by a novice. However, it does assume familiarity with a programming language.

The C programming language is a "middle-level" language. It provides low-level programming capability at the expense of some user-friendliness. Some cynics claim that C combines the flexibility and power of assembly language with the user-friendliness of assembly language". However with experience programmers find that the limited set of keywords and the use of pointers allows for fast and elegant programming solutions. C has been used in the design of Windows operating sytems from their earliest versions. It is also used in the design of microcontrollers and super-computers.

The original implementations of C were defined as described in the classic reference, THE C PROGRAMMING LANGUAGE, by Brian Kernighan and Dennis Ritchie. This definition left a few things to be desired, and the American National Standards Institute (ANSI) formed a group in the 1980s to tighten up the spec. The result was "ANSI C", which is the focus of this document.

Tools For Programming


If you are new to programming then there are certain "tools" you need. The good news is that these tools are readily available for free and can be downloaded immediately. One of the major obstacles for beginners is the idea of using a compiler. A compiler is just a program that takes your "code" (which is the technical term for the lines of programming language that you will write) and "compiles" it into an executable (everytime you click an *.exe to install a program you are essentially running code that has been compiled and is ready to install or use on your computer).

When most people start to program in C the first question they ask is "Where are the windows that I see in MS Word". Its only natural in a graphics dominated computer world to want to create a graphical interface for your program. The easiest way to write a Windows "style" program in C is by downloading Visual C++ (from Microsoft). This IDE (Intergrated Development Environment) allows you to call the GUI (Graphical User Interface) provided by Microsoft where all the buttons, windows, dialog boxes, etc are already designed and ready for use in your program. If you are just starting out then Microsoft provides a free version of Visual C++ with features and functionality that almost matches the professional version.

Though the programming examples given in this book are not GUI based you can still use Visual C++ to compile them. Please note that there are many free C and C++ compilers and coding tools offered by companies other than Microsoft. If you wish to try another IDE, forums and freeware sites are ideal places to find out about these.

An Introductory C Program


Here's a simple C program to calculate the volume of a sphere:

PHP Code:
/* sphere.c */

#include                   /* Include header file for printf. */

#define PI 3.141592654f             /* Define a constant. */
 
static float sphere(float);         /* Function prototype. sphere is given internal linkage with the keyword
                                        'static' since it isn't used outside of this translation unit. */
 
int main(void)                      /* Main function. */{
        
float volume;               /* Define a float variable. */
        
float radius 3;           /* Define and initialize variable. */

        
volume sphere(radius);    /* Call sphere and copy the return value into volume. */
        
printf"Volume: %f\n"volume );  /* Print the result. */
        
return 0;
}
 
float sphere(float rad)             /* Definition of a volume calculating function. */{
        
float result;               /* "result" is defined with an automatic storage duration and block scope. */

        
result rad rad rad;
        
result PI result 3;
        return 
result;              /* "result" is returned to the function which called sphere. */

The first feature that can be observed in this program is that comments are enclosed by "/*" and "*/". Comments can go almost anywhere, since the compiler ignores them. Another obvious feature is that individual statements in the program end with a ";". Either forgetting a ";" or adding one where it isn't needed is a common C programming bug. Lines of code are grouped into blocks by using curly brackets ("{ }").

C is case-sensitive. All C keywords are in lower-case. Program variable and function names in whatever case desired, but by convention they should be in lower case. "Constants", to be discussed a bit later, are upper case by convention.

Not all the lines in a C program are executable statements. Some of the statements shown above are "preprocessor directives".

C compilation is a multi-pass process. To create a program, a C compiler system performs the following steps:
  • It runs the source file text through a "C preprocessor". All this does is perform various text manipulations on the source file, such as "macro expansion", "constant expansion", "file inclusion", and "conditional compilation", which are also explained later. The output of the preprocessor is a second-level source file for actual compilation. You can think of the C preprocessor as a sort of specialized automatic "text editor".
  • Next, it runs the second-level source file through the compiler proper, which actually converts the source code statements into their binary equivalents. That is, it creates an "object file" from the source file.
  • The object file still cannot be executed, however. If it uses C library functions, such as "printf()" in the example above, the binary code for the library functions has to be merged, or "linked", with the program object file. Furthermore, some addressing information needs to be linked to the object file so it can actually be loaded and run on the target system.

These linking tasks are performed by a "linker", which takes one or more object files and links them to binary library files to create an "executable" file that can actually be run.

C has a large number of libraries and library functions. C by itself has few statements, so much of its functionality is implemented as library calls.

Commands intended for the C preprocessor, instead of the C compiler itself, start with a "#" and are known as "preprocessor directives" or "metacommands". The example program above has two such metacommands:

PHP Code:
#include 

#define PI 3.14 

The first statement, "#include ;", simply merges the contents of the file "stdio.h" into the current program file before compilation. The "stdio.h" file contains declarations required for use of the standard-I/O library, which provides the "printf()" function.

Incidentally, the "stdio.h" file, or "header file", only contains declarations. The actual code for the library is contained in separate library files that are added at link time. Custom header files loaded with custom declarations can be created if needed, and then included in a program as follows:

PHP Code:
#include "mydefs.h" 

Angle brackets ("< >") are not used with custom header files. They only are used to define the default header files provided standard with a C compiler (and which, on Unix/Linux systems, are found in directory "/usr/include" ).

A C program is built up of one or more functions. The program above contains two user-defined functions, "main()" and "sphere()", as well as the "printf()" library function.

The "main()" function is mandatory when writing a self-contained program. It defines the function that is automatically executed when the program is run. All other functions will be directly or indirectly called by "main()".

A C function is called simply by specifying its name, with any arguments enclosed in following parentheses, with commas separating the arguments. In the program above, the "printf()" function is called as follows

PHP Code:
printf"Volume: %f\n"volume ); 

This invocation provides two arguments. The first -- "Volume: %f\n" -- supplies text and some formatting information. The second -- "volume" -- supplies a numeric value.

A function may or may not return a value. The "sphere()" function does, and so is invoked as follows:

PHP Code:
volume sphereradius ); 

A function uses the "return" keyword to return a value. In the case of "sphere", it returns the volume of the sphere with the statement:

PHP Code:
return result

All variables in a C program must be "declared" by specifying their name and type. The example program declares two variables for the "main" routine:

PHP Code:
float volume;float radius 3

and one in the "sphere" routine:

PHP Code:
float result

The declarations of "volume", "radius", and "result" specify a floating-point variable. The declaration allows variables to be initialized when declared if need be, in this case declaring "radius" and assigning it a value of "3".

All three of these declarations define variables block scope. Variables with block scope exist only within the blocks that declare them. Variables of the same name could be declared in different blocks without interference. It is also possible to declare variables with file scope that can be shared by all functions by declaring them outside of all blocks within a translation unit. By default, all identifiers with file scope are given external linkage. It is only with the keyword "static" that an identifier is given internal linkage. Declarations like this:

extern int a;

identify "a" as an int whose storage is defined elsewhere; preferably in another translation unit.

PHP Code:
/* global.c */

   #include 

   
void somefuncvoid );
   
int globalvar;

   
void main()
   {
     
extern int globalvar;
     
globalvar 42;
     
somefunc();
     
printf"%d\n"globalvar );
   }

   
void somefuncvoid )
   {
     
extern int globalvar;
     
printf"%d\n"globalvar );
     
globalvar 13;
   } 

Besides the variable declarations, the example programs above also feature a function declaration, or "function prototype", that allows the C compiler to perform checks on calls to the function in the program and flag an error if they are not correct:

PHP Code:
float sphere(float); 

The function prototypes declare the type of value the function returns (the type will be "void" if it does not return a value), and the arguments that are to be provided with the function.

Finally, the "printf()" library function provides text output capabilities for the program. The "printf()" function can be used to print a simple message as follows:

PHP Code:
printf"Hello, world!" ); 

-- displays the text:

PHP Code:
Helloworld

Remember that "printf()" doesn't automatically add a "newline" to allow following "printf()"s to print on the next display line. For example:

PHP Code:
printf"Twas bryllig " );
   
printf"and the slithy toves" ); 

-- prints the text:

Code:
Twas bryllig and the slithy toves

A newline character ("\n") must be added to force a newline. For example:

PHP Code:
printf"Hello,\nworld!" ); 

-- gives:

Code:
Hello,
   world!

These examples only print a predefined text constant. It is possible to include "format codes" in the string and then follow the string with one or more variables to print the values they contain:

Code:
printf( " Result = %f\n", result );

This would print something like:


PHP Code:
Result 0.5 

The "%f" is the format code that tells "printf" to print a floating-point number. For another example:

PHP Code:
printf"%d times %d = %d\n"ab); 

-- would print something like:

PHP Code:
4 times 10 40 

The "%d" prints an integer quantity. Math or string expressions and functions can be included in the argument list.

To simply print a string of text, there is a simpler function, "puts()", that displays the specified text and automatically appends a newline:

PHP Code:
puts"Hello, world!" ); 

Just for fun, let's take a look at what our example program would be like in the pre-ANSI versions of C:

PHP Code:
/* oldspher.c */

   #include 
   #define PI 3.141592654

   
float sphere();        /* Parameters not defined in function prototype. */

   
main()
   {
     
float volume;
     
int radius 3;

     
volume sphereradius );
     
printf"Volume: %f\n"volume );
   }

   
float sphererad )
   
int rad;               /* Parameter type not specified in function header. */
   
{
     
float result;

     
result rad rad rad;
     
result PI result 3;
     return 
result;
   } 

C Functions in Detail


As noted above, any C program must have a "main()" function to contain the code executed by default when the program is run.

A program can contain as many functions as needed. All functions are "visible" to all other functions. For example:

PHP Code:
/* fdomain.c */

   #include 

   
void func1void );
   
void func2void );
  
   
int main()
   {
     
puts"MAIN" );
     
func1();
     
func2();
   }

   
void func1void )
   {
     
puts"FUNC1" );
     
func2();
   }

   
void func2void )
   {
     
puts"FUNC2" );
     
func1();
   } 

In this example, "main()" can call "func1()" and "func2()"; "func1()" can call "func2()"; and "func2()" can call "func1()". In principle, even

"main()" could be called by other functions, but it's hard to figure out why anyone would want to do so. Although "main()" is the first function in the listing above, there's no particular requirement that it be so, but by convention it always should be.

Functions can call themselves recursively. For example, "func1()" can call "func1()" indefinitely, or at least until a stack overflow occurs. You cannot declare functions inside other functions.

Functions are defined as follows:

PHP Code:
float sphereint rad )
   {
      ...
   } 

They begin with a function header that starts with a return value type declaration ("float" in this case), then the function name ("sphere"), and finally the arguments required ("int rad").

ANSI C dictates that function prototypes be provided to allow the compiler to perform better checking on function calls:

PHP Code:
float sphereint rad ); 

For an example, consider a simple program that "fires" a weapon (simply by printing "BANG!"):

PHP Code:
/* bango.c */

   #include 

   
void firevoid );

   
void main()
   {
     
printf"Firing!\n" );
     
fire();
     
printf"Fired!\n" );
   }

   
void firevoid )
   {
     
printf"BANG!\n" );
   } 
This prints:

Code:
Firing!
   BANG!
   Fired!

Since "fire()" does not return a value and does not accept any arguments, both the return value and the argument are declared as "void"; "fire()" also does not use a "return" statement and simply returns automatically when completed.

Let's modify this example to allow "fire()" to accept an argument that defines a number of shots. This gives the program:
PHP Code:
/* fire.c */

   #include 

   
void fireint n );

   
void main()
   {
     
printf"Firing!\n" );
     
fire);
     
printf"Fired!\n" );
   }

   
void fireint n )
   {
     
int i;
     for ( 
1<= ; ++)
     {
       
printf"BANG!\n" );
     }
   } 
This prints:

Code:
Firing!
   BANG!
   BANG!
   BANG!
   BANG!
   BANG!
   Fired!

This program passes a single parameter, an integer, to the "fire()" function. The function uses a "for" loop to execute a "BANG!" the specified number of times -- more on "for" later.

If a function requires multiple arguments, they can be separated by commas:


PHP Code:
printf"%d times %d = %d\n"ab); 

The word "parameter" is sometimes used in place of "argument". There is actually a fine distinction between these two terms: the calling routine specifies "arguments" to the called function, while the called function receives the "parameters" from the calling routine.


When a parameter is listed in the function header, it becomes a local variable to that function. It is initialized to the value provided as an argument by the calling routine. If a variable is used as an argument, there is no need for it to have the same name as the parameter specified in the function header.

For example:

PHP Code:
fireshots );
  ...
  
void fireint n )
  ... 

The integer variable passed to "fire()" has the name "shots", but "fire()" accepts the value of "shots" in a local variable named "n". The argument and the parameter could also have the same name, but even then they would remain distinct variables.


Parameters are, of course, matched with arguments in the order in which they are sent:

PHP Code:
/* pmmatch.c */

   #include 

   
void showmeint aint b );

   
void main()
   {
     
int x 1100;
     
showmex);
   }

   
void showmeint aint b )
   {
     
printf"a=%d  b=%d\n"a);
   } 
This prints:

Code:
a=1  b=100

This program can be modified to show that the arguments are not affected by any operations the function performs on the parameters, as follows:

PHP Code:
/* noside.c */

   #include 

   
void showmoreint aint b );

   
void main()
   {
      
int x 1100;
      
showmorex);
      
printf"x=%d  y=%d\n"x);
   }

   
void showmoreint aint b )
   {
      
printf"a=%d  b=%d\n"a);
      
42;
      
666;
      
printf"a=%d  b=%d\n"a);
   } 
This prints:

Code:
a=1  b=100
   a=42  b=666
   x=1  y=100

Arrays can be sent to functions as if they were any other type of variable:

PHP Code:
/* fnarray.c */

   #include 
   #define SIZE 10
  
   
void testfuncint a[] );
  
   
void main()
   {
     
int ctra[SIZE];
     for( 
ctr 0ctr SIZE; ++ctr )
     {
       
a[ctr] = ctr ctr;
     }
     
testfunc);
   }
  
   
void testfuncint a[] )
   {
     
int n;
     for( 
0SIZE; ++ )
     {
       
printf"%d\n"a[n] );
     }
   } 

It is possible to define functions with a variable number of parameters. In fact, "printf()" is such a function. This is a somewhat advanced issue and we won't worry about it further in this document.

The normal way to get a value out of a function is simply to provide it as a return value. This neatly encapsulates the function and isolates it from the calling routine. In the example in the first section, the function "sphere()" returned a "float" value with the statement:

Code:
return( result );

The calling routine accepted the return value as follows:

Code:
volume = sphere( radius );

The return value can be used directly as a parameter to other functions:

PHP Code:
printf"Volume: %f\n"sphereradius ) ); 

The return value does not have to be used; "printf()", for example, returns the number of characters it prints, but few programs bother to check.

A function can contain more than one "return" statement::

PHP Code:
if( error == )
   {
     return( 
);
   }
   else
   {
     return( 
);
   } 
A "return" can be placed anywhere in a function. It doesn't have to return a value; without a value, "return" simply causes an exit from the function. However, this does imply that the data type of the function must be declared as "void":

PHP Code:
void ftestint somevar )
   {
      ...
      if( 
error == )
      {
        return();
      }
      ...
   } 
If there's no "return" in a function, the function returns after it executes its last statement. Again, this means the function type must be declared "void".
The "return" statement can only return a single value, but this value can be a "pointer" to an array or a data structure. Pointers are a complicated subject and will be discussed in detail later.
 
World of Hacker © 2011 Creative Commons License
World of Hacker by KroKite is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Based on a work at http://www.worldofhacker.com.
Permissions beyond the scope of this license may be available at https://groups.google.com/forum/#!newtopic/hackerforum.