Professional Documents
Culture Documents
Document conventions
this typeface indicates something the machine should present,
this typeface indicates
1. Getting Started
Login, and start Openwindows. From your home directory, type into the cmdtool window % /packages/demo/yr1/script3 [return] which generates directories session3 and exercise3, and places several files in them. Change directory into "session3". % cd session3 [return]
02/20/2008 11:00 AM
2 of 14
void main() { }
2. Compile and link At the moment, the program squares.c is just a text file, and cannot be executed by the machine. To turn the program into an executable file, we first ``compile" the program, then ``link" it to the other routines we require. Use the following incantation in the cmdtool window: % gcc squares.c -o squares 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
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.) Step C: Adding comments It is good practice to add comments to help explain your code.
02/20/2008 11:00 AM
4 of 14
/* /* /* /*
*/ */ */ */
#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 */ */ Step D: Declarations of variables and constants To save space below, some of the comments in the printed code may disappear. Obviously there is no need for you to delete them. 1. Edit. Go back to the editor and add/alter:
*/
02/20/2008 11:00 AM
5 of 14
print out squares from 1 to 10 int i,isq; const int lolimit=1, hilimit=10;
*/
#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 1. The variable i is initialized to lolimit. 2. The while
(condition) {statements ... } tests
loop to execute the statements. When the condition becomes false, execution jumps to the first statement after the loop's body. 3. Notice the statement i=i+1; What would happen if this had been omitted?
#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
1. In a cmdtool window, copy the file squares.c to the file sqcubes.c 2. Edit the program sqcubes.c so that it calculates and prints BOTH the squares AND cubes of even integers between 2 and 16 inclusive. 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.
#include <stdio.h> int power(int number, int pow) { /* This routine returns an integer value * equal to number raised to the pow. * Pow can be zero or positive. */ int pwr,i; pwr=1; i=pow; while(i>0) { pwr = pwr * number; i = i-1; } return(pwr); }
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.
int, which can represent integers from - (231) to +231-1. float for floating point numbers. The largest float values are about &plumn; 3.40282 1038 and
the smallest non-zero float is 1.40129 10-45.
double provide a floating point nummber with higher precision and range. char is used for single characters.
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
5.1 Standard operators
+ Add
(eg c=a+b;)
d=a/b+2; /* this is (a/b) + 2, => d = 5 d=a/(b+2); /* and not this! => d = 2 d=a/b*c; /* is (a/b) * c d=a/(b*c); /* and not this d=a/b/c; /* is (a/b)/c
*/ */
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. 5.3 Some shorthand operators 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 b a c c
6. Conditionals
6.1 Numerical 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 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) } else { ... statements B ... (Executed if Condition is False) }
Using if ... elseif ... else
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) }
Here is an example of an ``if ... else if ... else statement
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. A partial solution has been supplied to you, and is listed later. 1. % cd ~/exercise8 and then check that file npowers.c exists. 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. 4. Finally, show your results to a demonstrator
13 of 14
double power(int number, int pow) { int i; double result; 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
In this session We have seen the following basic programming constructions in C: Assigments, eg result=1.0 Loops, eg for(i=1; Conditionals, eg if
+ a;
i<= 10; i++) { ... } (i==2) { ... } else {...} = power( 3.0, -1.0);
Subroutines, eg result
We have also gone round and round the design, edit, compile, execute cycle. Lab devised by: David Murray Lab Organizer: David Murray Last changed June 15th, 1999
02/20/2008 11:00 AM