Professional Documents
Culture Documents
First Year Computer Engineering For C Basic
First Year Computer Engineering For C Basic
Document conventions
If on your browser, curly brackets {} look similar to curvy brackets (), you will want to change the fixed
with font on the Netscape browser. Select Edit, then Preferences, then, when the new panel appears, select
Fonts, and choose Lucida Typewriter (B&H) at size 10 or 12 for the Fixed Width font.
1. Getting Started
02/20/2008 11:00 AM
2 of 14
You are going to build a C program in elementary steps to highlight aspects of the structure of the language. At
each step, you will compile and execute the program to see what happens.
void main()
{
The gcc program (The Gnu C Compiler) will compile squares.c, link it automatically to the standard C
library, and the -o squares puts the executable output into a file called squares.
3. Execute the program To execute the program, type in the cmdtool window:
% squares
Step A: Observations.
1. There were no complaints from Unix, so the program executed. However, as expected, it did not do
anything.
2. Every program has at least a ``main'' routine, which is where the program starts executing. Each routine
has a ``type'', defining the type of the return value of the function. Here though the routine does not return
a value, so it of ``void'' type. Most routines have a list of arguments given inside the (), but here we have
none. All routines surround their bodies with curly brackets { }. Here there are no statements though!
3. As we follow the steps below, you will see the general structure of a C program emerging: the program
comprises a set of routines, each of the form
02/20/2008 11:00 AM
3 of 14
{
declaration1;
declaration2;
...
statement1;
statement2;
...
return( value );
}
4. Also you will see the development cycle emerging, of edit, compile, then execute.
#include <stdio.h>
void main()
{
printf("Squares from 1 to 10\n");
}
Step B: Observations
1. Each statement inside the body of the code surrounded by the outer curly { } must end with a semicolon.
The statement actually calls another routine printf() , which writes output to the standard output. The
"\n" puts a newline at the end of the text.
2. The #include <stdio.h> is a compiler directive which makes sure that C knows how printf() is defined.
(stdio.h is a file defining a number of routines for input and output.)
02/20/2008 11:00 AM
4 of 14
/* Name : squares.c */
/* Version: 1.0 */
/* Author : E Jarvis Thribbs */
/* Date : 12 Oct 98 */
#include <stdio.h>
void main()
{
/* This program will eventually
print out squares from 1 to 10 */
printf("Squares from 1 to 10\n");
}
Save again.
2. Compile and Execute. Save some fingerwork by using the exclamation mark shorthand
% !gcc
which will repeat the last command starting gcc. (This works for any command by the way: !p repeats the
last command line beginning with p, !pa the last beginning with pa, and so on.)
Step C: Observations
1. Nothing changes in the executable program. All text between /* and */ is ignored by the compiler, and has
no effect on the code.
2. Comments can appear anywhere in the source code. One restriction is that you cannot nest comments as
in /* A comment /* Nested = Bad */ */
To save space below, some of the comments in the printed code may disappear. Obviously there is no need for
you to delete them.
#include <stdio.h>
void main()
{ /* This program will eventually
02/20/2008 11:00 AM
5 of 14
int i,isq;
const int lolimit=1, hilimit=10;
Remember to save.
2. Recompile using !gcc
3. Execute.
Step D: Observations
1. The first set of statements in a routine are the declarations mentioned earlier. They always come at the top
of the routine, and the declared identifiers are valid only within the routine itself. Each variable and
constant must be declared --- there are no default values.
2. Here we use integer variables i and isq, and integer constants called lolimit and hilimit. Constants cannot
change their value during a routine.
3. The output is achieved using printf(). On execution, the format code %d is replaced with the
corresponding integer value.
#include <stdio.h>
void main()
{
int i,isq;
const int lolimit=1, hilimit=10;
printf("Squares from %d to %d\n",lolimit,hilimit);
i=lolimit;
while (i <= hilimit) {
isq = i*i; /* i multiplied by i */
printf("%d squared is %d\n",i,isq);
i = i+1;
}
printf("Finished looping because i=%d \n",i);
}
02/20/2008 11:00 AM
6 of 14
Remember to save.
2. Recompile (!gcc)
3. Execute.
Step E: Observations
There are few restrictions on layout in C. Each compiler directive has to be on a separate line, and care must be
taken splitting strings, but apart from that anything goes. As the mess below illustrates ugly programs are hard
to understand and debug, and are thus bad engineering practice.
#include <stdio.h>
void main(){ int i,isq; const int lolimit=1, hilimit
=10;printf("Squares from %d to %d\n",lolimit, hilimit)
;i=lolimit; while
(i<=hilimit){isq=i*i;printf(
"%d squared is %d\n",i,isq);i = i+1;}printf(
"Finished looping because i=%d \n",i);}
EXERCISE 3A
Don't just hack the existing program. Think a little about the design, so that your program, even though it
is small, is elegant and efficient. Perhaps the output should appear as a table:
i i^2 i^3
---------------
2 4 8
etc
Some observations
02/20/2008 11:00 AM
7 of 14
1. If there were language errors in your program, the compiler prints error messages to help you find the
mistakes. Use the editor to correct them, save the editted file, and recompile.
2. It is important to realize that if the compiler fails, no new executable file is written.
So if you had a working version of cubes, then altered sqcubes.c but introduced an error, and tried to
compile, the old version of sqcubes would not be overwritten. So, sqcubes might appear to run, but it
would be the old not new version.
int icubed;
...
icubed = isq*i;
Now suppose you had been asked to evaluate many more powers within the program. It would be tedious and
error-prone to write the expressions out explicitly. Instead you might wish to write a separate routine.
#include <stdio.h>
02/20/2008 11:00 AM
8 of 14
void main()
{
int i,i2,i4,i6,i8;
const int lolimit=1, hilimit=10;
printf("No Pow2 Pow4 Pow6 Pow8\n");
i=lolimit;
while (i <= hilimit) {
i2 = power(i,2);
i4 = power(i,4);
i6 = power(i,6);
i8 = power(i,8);
printf("%2d %4d %6d %7d %9d\n",i, i2, i4, i6, i8);
i = i+1;
}
}
2. Compile powers.c
3. Execute powers
Step F: Observations
1. The routine power() has type int because it returns an integer value using the return(pwr). The routine
has two arguments, number and pow. Note how the routine is called in the main program.
2. We slightly altered the printf() format string: %4d supplies an output field with a fixed with of 4 places.
These types can be modified in several ways, but for now these will suffice. Mathematical functions tend to use
double precision floating point numbers rather than floats.
...
void main()
{
02/20/2008 11:00 AM
9 of 14
int count;
float volume;
double fred;
char label;
...
count = -356;
volume = 2345.456;
fred = 2.123477834599725;
label = 'a';
/* Notice these are closing-apostrophes' '
and not `speech marks' */
}
5. Operators
c=2(a+b); /* WRONG */
c=2*(a+b); /* RIGHT */
There are strict rules for operator precendence. Expressions in brackets are worked on first. Multiplies and
divides are done before adds and subtracts. A succession of multiplies and divides or adds and subtracts is
worked on left to right. So, for example, suppose a=12 and b=4 and c=2, then
02/20/2008 11:00 AM
10 of 14
It is always sensible to use brackets to make your meaning clear to you, others, and the compiler.
Avoid
j+=2; add 2 to j. Same as j=j+2;
j-=2; take 2 from j. Same as j=j-2;
j*=2; j=j*2;
j/=2; j=j/2;
EXERCISE 3B
What value would c have at the end of this ugly piece of code?
a = 8.0;
b = a - 2.0 * 3.0;
a -= 4.0;
c = ( (a/2.0/b) * 3.0/a*b)/b;
c *= 2.0;
6. Conditionals
The while loop you included in your code was controlled by testing a condition. Conditionals are either
numerically based or logically based. A list of numerical conditionals is
Operator Example Result
< (a < b) True if a less than b
<= (a <=b) True if a less than or equal to b
> (a >b) True if a greater than b
>= (a >=b) True if a greater than or equal to b
== (a ==b) True if a equal to b
!= (a !=b) True if a not equal to b
02/20/2008 11:00 AM
11 of 14
Conditionals are also used in the very frequently used if statement, which executes the statements in the block
where the respective condition is TRUE. There are three flavours of if:
Using plain if
if ( Condition ) {
... statements A ...
(Executed if Condition is True)
}
if ( Condition ) {
... statements A ...
(Executed if Condition is True)
}
else {
... statements B ...
(Executed if Condition is False)
}
if ( Condition1) {
... statements A ...
(Executed if Condition1 is True)
}
else if ( Condition2) {
... statements B ...
(Executed if Condition2 is True)
}
else {
... statements Z ...
(Executed if all Conditions are False)
}
if( i<0 ) {
printf("i is negative!\n");
}
else if ( i>0) {
02/20/2008 11:00 AM
12 of 14
printf("i is positive!\n");
}
else if (j>0) {
printf("i is zero and j is positive\n");
}
else {
printf("i is zero and j is zero or negative\n");
}
EXERCISE 3C
Recall the program powers.c which used a routine to compute the value of integer raised to an integer power.
The integer power had to be greater or equal to zero.
Your task now is to modify the routine to allow in addition raising to negative integer power.
There are many ways of achieving this. It is worth thinking first about some common aspects to any solution.
1. The routine power() will have to check for a negative argument. This requires the use of the if
condition.
2. Because an integer raised to a negative number is a floating point number, the result will now have to be a
double rather than an int. This will have repercussions in the main routine too.
3. Usually, the less ``clever'' you make the code, the easier it is to write and debug, and the easier it is to
understand at a later date.
1. % cd ~/exercise8
2. Load npowers.c into the text editor. You will see that the main routine is complete, but the subroutine is
not.
3. Sort out the four ``FIXMEs'' in the code. Save the program, compile and link. If unsuccessful, reedit until
it executes properly. If you feel you are making no progress, consult a demonstrator sooner rather than
later.
/* LISTING of npowers.c */
#include <stdio.h>
02/20/2008 11:00 AM
13 of 14
result=1.0;
i=pow;
if( FIXME ) { /* This should deal with negative pow */
while(i < 0) {
result = FIXME ;
i= FIXME ;
}
} else {
while(i > 0) { /* This should deal with positive or 0 pow */
result = result * (double)number;
i = FIXME ;
}
return(result);
}
void main()
{
/* we will work out i^(-2,-1,0,1,2) */
int i;
const int limit=11;
double im2,im1,iz,ip1,ip2;
i=1;
while(i < limit) {
im2 = power(i,-2);
im1 = power(i,-1);
iz = power(i,0);
ip1 = power(i,1);
ip2 = power(i,2);
printf("%lf %lf %lf %lf %lf\n",im2,im1,iz,ip1,ip2);
i = i+1;
}
}
Logging out
02/20/2008 11:00 AM
14 of 14
As ever
exit openwin
And then don't forget to logout from the console
Summary
Assigments, eg result=1.0 + a;
We have also gone round and round the design, edit, compile, execute cycle.
02/20/2008 11:00 AM