printf("The program is Over");
This simple C code adds an additional component to the one we
saw earlier, it calls a function "printit".
As before you can see the "include" files, or
what are called header files. Then we will see the main part of the program.
This program is basically computing square root of the variable x and it is
printing it out on the screen. Then it is calling some function, which prints
out a statement.
Here we see on of the main feature of a
C program. The main part does some of the calculations and it calls another
The function we called, named printit, which simply prints the sentence "the program is
over." can be
put it a separate file. Let is call it "print.c". We
will see that how it can be compiled and how it can be executed.
There are two ways to compile
To compile these programs we could type
cc -c sample.c and cc -c print.c separately.
This commands will create sample.o and print.o files. We
can create the executable by typing the command.
cc sample.o print.o -lm -o a.out
In this linking command we have put
together the two files and also included the math library file m.a
We can now execute the program by typing
You could try variations of these
commands and programs to figure out why we need the math.h
file and why we need to include -lm in the linker etc. Also try it for different math functions, for
example calculating the logarithm or trigonometric functions etc.
Another way to compile and generate an
executable from this is to simply type
cc sample.c print.c -lm -o a.out
In this the compilation and linking is
Let us try another program to illustrate the use of math
library and the compilation and linking procedure.
Here is the file "sample.c",
FP = fopen("sample.dat", "w");
y = tanh(x);
printf("The program is over" "\n");
discussed above, there are two ways for compiling.
sample.c creates the file called sample.o
print.c creates the file
Now, we put them together and
produce an executable. In the process we will link it to the math library using -lm and use -o to direct the executable to an output "myexe".
cc sample.o print.o -lm -o myexe
this will create a file myexe. Now, if
we did not use the part of the command after "-lm", an executable file a.out will be created by the compilation.
We could also do it (creating the
executable) in one step with the command
cc sample.c print.c -lm -o myexe
To run the program, we use ./myexe. Then it prints on the
screen that the "program is over". This is what we have asked the function print.c.
what does this program do? It is computing the tangent hyperbolic function for a range of values of x. We achieve this using the "while" function. The output is written in a file called "sample.dat". Note the "fopen" and "fprintf" functions were called for this purpose. Then it calls the function printinit(). Printinit () just prints out "the program is over" using the function "printf". We will see more examples of the use of these functions as we go along.
As we saw above in one command we
can do two things, compile and link. We can do compilation alone by invoking
-c along with cc. If we won't use -c, it
will compile and link, that is the default. -lm is here for linking to math
Let us see what happens if we do nnt use
"-lm" in the command , that is we do not
Link it to
the math library and type only
cc sample.c print.c -o myexe
Does it work?
ą it says that it cannot
Since, tanh is built into the
math library, we need that math library to compile
this program. To use mathematical functions, we need to link to math library. For other functions, we
might need other libraries. These libraries are stored in different parts of
the computer. For example in a Linux platform, these libraries are stored in
/users/lib . In general, for different operating
systems, the library functions are in different places
We were also using header files
in the program. Header files are used with "#include" statements. Try removing header file #include<studio.h> and then try to compile
cc sample.c print.c -lm -o myexe
It says that it cannot understand
fopen statement and and *FP
FILE, fopen and all the statements are actually put in into the header file called <studio.h>. For simple "printf"
statements, we don't need it.
So, we now have a basic idea
about how to create a program, compile it and run it. We have seen simple codes
with the function and we compile it and run it.
anatomy of a program
Let us look at the anatomy of a
program once again. It can be summarized as below.
Compiler preprocessor commands
main function name()
We have some compiler preprocessor commands.
This includes various #include files. Then comes the
main function. Some name can also be given to the main function. Then, we have
the variable declarations used in the main code. Then we have sub-functions.
In the previous example, we had the sub functions as a separate files. But you can also include them it into the main code. In this case, in one file, we can have main program of the main function and sub-functions or separately. It is a good idea to have the sub-functions separately. We also compile them n link them separately. It is always safer to do that. For large programs, it is good to have sub functions separately. Sub function has also the same structure like main function. It might have some arguments which would be passed into it. Then comes argument declaration. Then we have some variable declarations which is only private to sub functions only. We will see the examples of these.
Before going to the example, let
us look at each one these in detail.
The standard C compiler has four filters. The
first one is known as the preprocessor. This part handles the inclusion of
files mentioned using the
#include command, definition of constants, macro definition etc.
The second filter checks the language
statements, generates a symbol table and reports any errors found.
The third part generates the code and a
fourth filter optimizes the code for better performance
The fourth one optimizes the function. It
improves the code and modifies the code and so that it runs faster. This is an optional part of the compiler.
Then we look at variable
C language require
that all variables are declared before they can be used. Here we declare the
variable with its class name and the data type.
The variable declarations can have the
[class] [type] [name][ = initial value].
value" is not a necessary quantity.
For example we can declare the real variable "trial" using "auto
float trial" or "auto float trail = 0.0". In the latter we also
assign the variable a value "0.0".
We will now take a closer look at the 'class' statement.
In the statement for declaring the variable "trial"
we used "auto float trial" . This means we have assigned the [class]
as auto. In fact this is the default class and not necessary to be mentioned in the
n auto variable is local to the function within which it is
declared. Every time the function is entered we need to assign a value to it
before it is used.
Auto variable is a default one.
If we say float, it is taken it as auto. That is the default variable
declarations. Here are more examples.
printf("%f %f %f \n", x,pow(x,2),y);
y = x*x*x;
Here, the variable is declared as "float x,y". This is nothing
but "auto float x, y".
We can add more number of variables to one declaration. When we are
using more variables, it is separated by comma. Here we are using two
In the C program, all the lines are separated by semi-colon.
The variable declared as an auto
variable float x,y is only
private to the main function unless one
passes it to other functions. We
can have the same variable declared in another function. For example, float y
is declared in the sub function. The y value it takes inside the sub function
is different from the other declared outside it. So for the main function to get the result of
the computation done in the sub function the value has to be "returned".
In this program x value takes starting from 0 in steps
of one in floating point. (We will discuss more on what is a floating point and
how is the floating point and
an integer actually stored in the computer etc., a little later .
Right now, the floating point is the real number.)
The sub function actually
computes the cubic value of x, returns the value to
the main function and prints it. While executing the program, we get the value
of square of x (through the "pow" function) as well
as cube of x.
In the function call y = cube(x),
we are passing the variable "x" to the sub funtion.
But we are only passing the value of the
variable. In the sub function
statement the variable name need not be the same. Even if it is the same it has
to be decalred just after the function statement. and If we don't declare the use the float x inside the sub
function, we will get the cube of x as zero.
That is, auto variable float x is
private to the function.
another class that is possible. An external variable is global to the program. It should be defined
outside the function boundary. A function that uses it should declare it as extern.
The first declaration creates the storage and
the subsequent declarations does not create storage,
but just tells the compiler that the reference to this variable should be
resolved by the linker. An example program that uses the real variable as external
is given below.
float z; /* External variable is common to the
whole program and is decalred outside the main
extern float z; /* The
main and sub functions that uses the
variable should be declare it as extern */
x = 0.0;
printf("%f %f \n",x,z);
This is the main program. Here we have declared float z outside the
main function. That is
z has been declared as an external floating point. We are using extern float z
in the main function also. The sub function here that the program calls is add(x). That function is shown below.
extern float z;
y = sqrt(a);
z = x+y;
This function is receiving the
variable "x" passed by the main function as variable "a". As we have discussed
earlier these variables should be declared next line to the function
statement. It is also using the variable
z which is declared as extern float z. If it
is not declared in the sub function, the function will not know what z is. If
the z value changes in the main function then automatically the value changes
in the sub function and vice versa.
Now, the compilation is done by ,
cc sample3.c add.c -lm -o a.out.
not creating the object file. We just do everything together. Then the program
We run it and check what value "z" takes in the program of add.c if we change it in
main. We should add printf statements inside the
program add.c to do this.
extern float z;
y = sqrt(x);
z = x+y;
printf ("%f \n",z);
Put similar print statements in
the "main" to show that the value of "z" is changed even though it is not
"passed" through the function call.
could have a static variables. These are special
Static variables are initialized only
once by the function. The static data is assigned the initial value only on the
first time the function is entered and is not re-initialized every time the
function is entered.
We will see this here with an
extern float z;
x = 0.0;
printf("%f %f \n",x,z);
static float y = 0.0;
extern float z;
y = y+2;
z = x+y;
We declared the static variable y
= 0.0 here. It means that it will initialize the value for y as 0 at first.
Then, it won't. If we run the program, we get the results as 2,4,6. First it takes the value 0 and then in every further
calls to add it increments by 2.
Check what happens when static
statement is removed? It would initialize this variable the first time it
enters the sub function. Since "y" is
initialized every time the values of "z" will be 2 every time
Static variables are very useful.
In many cases, for example, in the case of random number generator, we have some kind of seed. We
pass this see to a random number generator and is returns a random number and
updates the see. The next time we call the random number generator it give a new number because the seed is new. This is a case
where we don't want the seed to me initialized in every call. We want to get a new
random number in every call. So in subsequent calls the seed value
should not be initialized, that is it should be treated as "static".
We have auto variable
,static variable and external variables. These are the basic three
classes that we have gone through. Going back to our
definitions in the variable declaration. We have [class] [type] [name ]=[initial
We can put any names here. We have to be careful, the variables in the c language are
case-sensitive. We mayor may not put the initial value.
Second thing is the type. So far we
have used only one or two types, float and int..
Here is the summary or the chart of the
various data types.
We could have an integer or we could have an floating point or we could have an character. Characters
are declared as char and integers are
declared as int and floating points as float.
There are two different types of integers which we can
declare, Long integer and Short integer. In most of the present day compilers
the integers declared as int are only Long integers. It means if you have 32
bits, then 2^31 is the largest integer which we can represent. One bit is used
for sign. The third one refers the unsigned interger,
here can use the extra bit for representing integer without sign. So,it
is slightly longer than the long integers.
Then, we have floating point. Here again we could have single
precision or double precision. When we say float, it is single precision. If we
say double, then it is double precision..
Let us look at the program which uses
all the data types. Here is the program (sample4.c)
char letter, chain[ ] = "a quick fox\n" ;
letter = 'B';
Y = 1.01;
i = 9247562;
i = 2;
%lf %ld %c %s\n", y, i,letter,chain);
j = 0;
x = y*y ;
k = 2*i ;
y = x ;
i = k ;
Here the variables x and y are
declared as a double. (i.e. x and y - floating point
(double) auto variables.). Then variables i.j.k are declared as long integers. If we are using large numbers, it is advisable to
use long int. Long int can also be represented as long. We don't need to write
"letter" is a character and is declared using char. Then we have a character array or the character
string , 'a quick fox' which is called chain[ ].
These are the examples of
character declarations. You can declare a single letter character or a group of
characters as letter. We could have an array or string of characters. Here,
letter is defined as 'B'. Letter is the character here when it is assigned to a
character B. Usually, the character is assigned within single quotes.
Then the integer i, has been assigned a number
value two. Then, it is printed out. This program contains many printf
statements. This example also demonstrates how do we
use printf statements. printf usually prints on the
screen. As shown in the previous example, you could also open a file and use a fprinf for printing into
If we are going to print out a
double precision number, then we use %lf or we could use '%e'. For long
integers, we use %ld. In a C program, if we use wrong
format in the printf statements, it will print junk but will not give
compilation or run time errors The characters are
printed using %c and the strings are printed using %s.
Run the program and see what it prints.
The program has a loop in which j
value increases from 0 to 31. The j value is first assigned to zero and
increased by steps
of one up to 31. The y value
is assigned to 1.01 to start with. It then computes the square of
that number and it is assigned to y. Basically, it computes the (1.01) ^2 and
the square of (1.01)^2 etc. so we will see how long it
will go before goes beyond the capability of the computer.
What I want to show you is that
this floating points and integers, there is a limit to the size of the numbers
which the computer can handle because the computer has a finite precision.
When then, the program is compiled
and run, it prints the number y, integer i , the letter B and the string a quick fox.
Then it enters into the loop and
prints the square of "x"
every time. It prints x=1.02.Then it squares that and keeps
squaring it. Since "x" has been declared as double precision, we can see that
it goes all the way up to j=16. Then the machine cannot handle it anymore. At j=17 th loop, "x" is printed as
infinite. As for as the computer is concerned, it is
Similarly the integer "I"
continues to double as "j" increments by one. You can see that 2^30 is the
largest integer it could print. It cannot do beyond that. Then, it gives junk.
In the previous program, we can
make a little change. Instead of double x,y , we can change it by float
x,y. Now, we see what happens. Again we compile it and run it. Now, we see it
could not go beyond j=13. But it went up to 16 last time.
So, if we want to use larger numbers and we want more precision it is better to
Let is now summarize what we have learned about the structure of a c program.
A few word about constants. We see
above an example of constant assignment z = 2.0/3.0. Now, z
is a floating point. For a mathematician 2/3 = 2.0/3.0; but for a computer 2/3 is zero and 2.0/3.0 is non zero!. In
general if we find the ratio of 2 integers, the result is the integer only. If
we declare z= 2/3 , then we get the value of zero. So,
we have to be careful while making constant assignment and remember to write it
as z=2.0/3.0 or z=2/3.0 or z=2.0/3.
Next:Pointers and Arrays Up :Main