|
~ Introduction to Programming: C ~ Session 2 - Some C Fundamentals |
Take this simple example. Try typing it in and running it. We will use it to demonstrate a number of important C concepts.
#include
<stdio.h>
#include
<conio.h>
/*
Two ways of defining constants */
#define
LENGTH 10
int
const breadth=20;
/*
Pre-define a function using a prototype */
int
vol_calc(int b, int w, int h);
/*
Main function entry point of program */
void
main() {
int height = 0;
printf("Volume Calculator\n-----------------\n");
printf("Length
is %d, Breadth is %d\n",
LENGTH,breadth);
printf("Enter value for Height: ");
scanf("%d",&height);
printf("%dx%dx%d gives volume: %d\nPress a key\n",
LENGTH,breadth,height,
vol_calc(LENGTH,
breadth, height)
);
getch();
}
/*
function previously defined by prototype
Calculates volume based on length*breadth*height
*/
int
vol_calc(int lngth, int brdth, int ht) {
return lngth*brdth*ht;
}
You can see that a C program has a specific structure. We will look at these and try examples that demonstrate their use in this session to get you used to the look and feel of the language.
This particular example takes two constant values of length (10) and breadth (20) and asks the user for a value of height and then calculates the volume using a function, and shows the resulting volume value on the screen.
Try entering the
value of 5 this should give a result of 10x20x5=1000. Try entering 0.5
as an integer was expected, this gives a result of 0.
Functions work similarly to Pascal. Remember that a function is a way to take a number of commands, and package them up under a given name so that they can be reused. For example, the printf function is used a lot in programs, but how it works is defined once in a function.
Every C program must
have a function called main it is rather like the Program
statement in Pascal programs. It defines what instructions should be executed
when the program is first executed. The start of the main function is denoted by a { (opening curly brace) and this is equivalent to the Pascal begin command. The end of the main
function (and thus the end of the program) is denoted by a }
(closing curly brace) and this is the equivalent to the Pacal end;
command.
The
() after the name of the program is empty because we are not passing any
information into the main
function from outside of the program.
Thus,
every program must have a main
function that looks at least something like this:-
#include
<blahblahblah.h>
void
main() {
/* This is my program */
}
Note
that, as with Pascal programs, any instructions inside a function should be
indented slightly to show that they belong to that function.
You
can create your own functions too in our program :-
int
vol_calc(int lngth, int brdth, int ht) {
return lngth*brdth*ht;
}
is
a function called vol_calc
which takes three pieces of information from outside of the function (three inputs)
they are all int type values (i.e. they are integers whole numbers) and are called lngth, brdth
and ht for length, breadth and
height. Note also the int
before the vol_calc name. This gives a
return type i.e. what sort of value will be passed back from the function
when it has finished. In this case, we will want to pass back the volume amount,
which will be an integer amount hence the int keyword.
The
function starts with a {
and ends with a } as with the main() function.
The
return keyword states that the calculation that follows will be returned from
the function as a result. Thus, the
sum lngth*brdth*ht
will multiply together the three values, which gives the volume, which is the
value returned from the function.
To
use the function from your program, you could do the following:-
int myval = vol_calc(2,3,4);
which will pass these values to the vol_calc function and return
the value of 24
and place it into the new integer variable myval
The
following diagram shows how this progresses
So
within the function, lngth=2,
brdth=3, and ht=4
This
means that the function lngth*brdth*ht evaluates to 2*3*4
= 24
Thus
return lngth*brdth*ht can be
read instead as return 2*3*4
or return 24
The
value of 24 is returned from the vol_calc function and the original equation that called vol_calc becomes in my val = 24;
Note
that the return type (the int before the vol_calc
name) matches the type of the variable myval that the result is placed into.
Note
that these examples are provided as an example, rather than for typing out.
Finally,
we meet a new concept known as the function
prototype. This is a way of
declaring that a function exists within the program before actually saying what
it does. The following is the function prototype for the vol_calc
function:-
/*
Pre-define a function using a prototype */
int
vol_calc(int b, int w, int h);
It
is simply a copy of the start of the function, showing what the inputs and
outputs are to the function without stating how the function does its job
i.e. no curly braces, and no instructions within those curly braces.
Try
taking this out of your program. You will get a compiler error. This is because
the function is defined after it is used, so when the program is compiled, the computer does not know
that the function exists when it tries to use it (it is further down the
program). Declaring a function prototype tells the compiler the function exists
further down the program, and what form it will take (i.e. what are its
parameters in, and what type of value it returns).
You
can avoid using function prototypes by putting the function before the main()
function, which means that the function is compiled before it is used. However,
this can be messy, because the important part of the program, the main()
functions finishes up being at the end of the program, which is far less
structured.
Another
use of declaring prototypes is that you can tell by looking at the top of your
program what functions are in your program.
As we have already seen, we can create variables and assign a value to that variable in one go.
Let's go back a stage.
C is what is known as loosely typed language. This means that it will not prevent compilation if two types don't match. For example, a character can be treated as an integer value (i.e. its ASCII value) when convenient or vice versa.
The principle types that can be used for variables and constants are as follows:-
C Type |
Lower
Most Value |
Upper
Most Value |
Pascal
Equivalent |
char |
|
|
char |
short int |
-32768 |
32767 |
integer |
int |
-231 |
+231-1 |
longint |
float |
-3.2x 10±38 |
+3.2x 10±38 |
real |
double |
-1.7x10±308 |
+1.7x10±308 |
double |
What
no Strings? These are represented as arrays of characters, which we will look at
in the next session.
So
to define a new variable or constant, we can place the declaration either
outside (above) the function (as in the case of the breadth
constant) if we wish the value to be available from any
function in the program.
Alternatively, we can place the declaration inside a function, if that variable
will be used only by that function for example the height
variable in the main() function.
To
declare a variable (usually at the top of your program or function), but after
the opening curly brace ({), put the type
of the variable first (e.g. int for an integer (whole number) variable) followed by a space (or any other
"whitespace" such as tab characters or further spaces) followed by the
name to be given the variable. You can also at this stage give the variable an
initial value by following the declaration with an = sign (which is the C
assignment operator, like the Pacal := operator) followed by an initial value.
Finally,
always terminate a C command with a semi-colon (;)
character.
Thus
to declare a variable to hold a whole number called myvar
and set it to have an initial value of 5 do the following:-
int
myvar=5;
If
you later wanted to change the value, you could assign a new value to it. E.g.
myvar=3;
You
can also perform arithmetic as in Pascal. The operators you can use are the same
as Pascal, and brackets can be used as in Pascal.
Operator
precedence is similar to Pascal, except some operators are typed slightly
differently. E.g.
|
(
) [
] ->
. |
|
!
~ - * & sizeof cast ++ - |
|
*
/ % |
|
+
- |
|
<
<= >= > |
|
==
!= |
|
&
| |
|
^ |
|
&& |
|
|| |
|
?
: |
|
=
+= -= |
|
, |
So, when reading an expression, the top-most operators would be read first (e.g. brackets get evaluated first). A Unary operator only works on one value. E.g. c++ would take the variable c and add 1 to it.
Constants are the same as variables, except they cannot be changed once they have
been defined. To define a constant, simply add the const keyword after the type
declaration.
E.g.
int const myvar=5;
If
you tried to issue the following command:-
myvar=3;
later
in your program, you would get a compiler error. A constant cannot be changed.
Constants
are typically defined at the top of your program to specify a value that should
be the same throughout the program, but may change at some future date e.g.
a filename, vat rate etc.
C is a "case sensitive" language. This means that variables names, function names etc. need to be typed exactly the same, taking into account capitalization, throughout your programs.
For example, if you declare a variable called myVar and refer to it later in your program as MyVar, a compilation error will be generated, as the capitalization (i.e. case) is different. Be careful when defining variable names. You could declare two variables called myVar and MyVar, but it would be very easy to get the two mixed up when looking through your program.
As
in Pascal, putting comments in your C code is very important to describe what is
happening in your program, so that you can follow how it works when you come
back to your program at a later date, or if somebody else needs to understand
how it works.
In
Pascal, you start a comment with a { and end it with a }.
In C you start a comment with a /* and end it with a */
- thus a comment can stretch over multiple lines.
§
#include and #define are examples of preprocessor
commands i.e. any instructions starting with a hash (#) character get
looked at before the program gets compiled, and turned into lines of
code, as if they were part of the program.
The #include command will take the contents of the file given in between the opening < and closing > (for example conio.h) and place the contents of this file into the program at the point the #include command appears.
This command tends to be used to include libraries of standard functions to be used by programs rather like the uses command in Pascal. For example, the conio.h file contains details of functions in a library that relate to console in/out i.e. text taken from the keyboard and place to the black console window. The equivalent Pascal command might be uses Crt;.
Virtually every
program your right will have the command
#include <stdio.h> as this holds many useful functions, such as the
printf and scanf functions, used to write to and read from the
console.
As an example, just say we wanted to change the above program to not wait for a value typed in at the keyboard, but to give a random value between 1 and 100.
The first task is to locate a function that relates to random numbers. Try looking in the C++ Builder help by typing out the word rand (short for random) anywhere in your program (make sure it is separated from any other commands), hold down the Ctrl key and press F1. Help related to the keyword you typed will be displayed. There is a function called rand() which retrieves a potentially massive random number. Helpfully, the help tells us which library the rand() function can be found in stdlib.h thus we need to include this at the top of our program to use the rand() function.
If you click on the Example link at the top of the help page, you will see that the example shows how to generate ten random numbers, each one being from 0 to 99. This is achieved by using the % or modulus operator (equivalent to the mod operator in Pascal). This will find the remainder after you have divided the first number by the second. We will try a program later to demonstrate what this does.
So to find a random number between 1 and 100, we could use the command (rand()%100)+1. Alternatively, if we only wanted multiples of 10 between 10 and 100, we could use the command ((rand()%10)+1)*10 this will find a number between 0 and 9, add 1 to it (so it is between 1 and 10) and then times it by ten (so it is between 10 and 100).
#include
<stdio.h>
#include
<conio.h>
#include
<stdlib.h>
/*
Two ways of defining constants */
#define
LENGTH 10
int
const breadth=20;
/*
Pre-define a function using a prototype */
int
vol_calc(int b, int w, int h);
/*
Main function entry point of program */
void
main() {
int height = 0;
printf("Volume Calculator\n-----------------\n");
height = ((rand()%10)+1)*10;
printf("Length is %d, Breadth is %d, Height is %d\n",
LENGTH,breadth,height);
printf("%dx%dx%d gives volume: %d\nPress a key\n",
LENGTH,breadth,height,
vol_calc(LENGTH,
breadth, height)
);
getch();
}
/*
function previously defined by prototype
Calculates volume based on length*breadth*height
*/
int
vol_calc(int lngth, int brdth, int ht) {
return lngth*brdth*ht;
}
Try making the changes shown in bold, and run the program a number of times. Do you notice that it seems to show the same "random" number each time. This is because the program needs to be randomised at the start. To do this, insert the randomize(); function at the top of the program as follows:-
int height = 0;
randomize();
printf("Volume Calculator\n-----------------\n");
Try running the program again a number of times. The value should now be different each time (note that the laws of probabilities say that you'll get the same number twice in a row sometimes!)
So how does the % modulus operator work? Well, it takes the value before the % and divides it by the value after the %, and returns not the result, but rather the remainder value. So, for example, 6%3=0 because 6 divided by 3 gives 2 exactly, so there's no remainder. However, 7%3=1 because 3 goes into 7 two times, with one left over. And so on. Type in the following program to get a better idea. You will need to type in a number (preferably between 1 and 10) that will be used for the value after the % operator, and all values between 1 and 20 will be shown before the % operator to show you what's happening
#include
<stdio.h>
#include
<conio.h>
void
main() {
int after = 0;
printf("Modulus demonstration\n\n");
printf("Enter value from 1-10: ");
scanf("%d",&after);
for(int before=1;before<=15;before++) {
printf("%d %% %d = %d\n",before,after,before%after);
}
printf("Press a key: "); getch();
}
The for statement will take a variable before and execute the printf command for each value of before between 1 and 15.
Try this program with a value of 4.
You should get results that look something like the following diagram:-
Modulus
demonstration
Enter
value from 1-10: 4
1
% 4 = 1
2
% 4 = 2
3
% 4 = 3
4
% 4 = 0
5
% 4 = 1
6
% 4 = 2
7
% 4 = 3
8
% 4 = 0
9
% 4 = 1
10
% 4 = 2
11
% 4 = 3
12
% 4 = 0
13
% 4 = 1
14
% 4 = 2
15
% 4 = 3
Press a key:
You can see that every times the number on the left hand side is a multiple of the value on the right hand side, the modulus value is 0 i.e. there is nothing left over.
This helps us with our random number problem, as the number returned from the rand() function could be any whole number. Thus by finding its modulus for the maximum value we want to find, it can only be from 0 to that value minus 1 (e.g. if we wanted to find a number from 0 to 3, then rand()%4 would do the trick!
The #define statement works like a constant, in that you declare a name and a value that goes with that name, and wherever that name occurs in your program, it will be substituted with the value before the program is even compiled. This is traditionally how constants have been declared, although the advent of the const keyword, described earlier, with the ANSI standardized version of C, you need not generally use it.
The #define statement can be used in a more complex form which we will not go into in this course most good C books will explore the subject further.
E.g.
#define
LENGTH 10
could be replaced with
int const LENGTH=10;
Once advantage (or disadvantage, according to your viewpoint) of the #define statement is that it is not typed i.e. you do not have to specify that it is an integer. This is because the value is simply substituted into your source code at the relevant points before it even gets compiled so
int
area=LENGTH*width;
would be changed to:-
int area=10*width;
before the program is compiled.
The printf command works rather like the write and writeln statements in Pascal.
In its simplest form:-
printf("Hello");
is the equivalent of
Write("Hello");
in Pascal.
However:-
printf("Hello\n");
is the equivalent of
WriteLn("Hello");
in Pascal. The \n is read as new-line. Therefore, to output the following text:-
Name Program
============
What is your name?
In Pascal you would need three commands:-
WriteLn("Name Program");
WriteLn("============");
Write("What is your name? ");
whereas with C you would need only one:-
printf("Name Program\n===========\nWhat is your name? ");
If you want to specify a value to write in the middle of the text (e.g. an integer variable), just use the %d specifier, and add the variable to place at that point as an extra parameter.
For example, in Pascal:-
i := 30; j:=20; WriteLn("The sum ",i,"*",j,"=",i*j);
would output The sum 30*20=600
The equivalent C would be:-
I=30; j=20; printf("The sum %d*%d=%d",i,j,i*j);
Each %d gets replaced by the value specified after the string. So the first %d gets replaced by the contents of the i variable (30), the second %d gets replaced by the contents of the j variable (20) and the third %d gets replaced by the result of the sum i*j=30*20=600.
To read data in from the keyboard, use the scanf command. This works like the printf command, except the variables that appear after the text need to have ampersand (&) characters prefixed to them (this represents the "address of " symbol this will be explained in a future session).
For example:-
ReadLn(i);
in Pascal (assuming i is an integer) would be this in C:-
scanf("%d",&i);
Thus, the computer waits for an integer (represented by the %d) to be entered at the keyboard, and the result gets put into the i variable.
This may seem a bit convoluted, but it can be quite powerful. For example, to input a date, you might issue the following command:-
scanf("%d/%d/%d",&d,&m,&y);
if you wanted the date to be entered in the format day/month/year
The following program (type it in if you would like to try it) will take the date in the above format, but display it in American format, with dashes instead of slashes.
#include
<stdio.h>
#include
<conio.h>
void
main() {
int d,m,y;
printf("Date? Format d/m/y: ");
scanf("%d/%d/%d",&d,&m,&y);
printf("Date is %d-%d-%d\n",m,d,y);
printf("Press a key: "); getch();
}
Here's an example results screen:-
Date?
Format d/m/y: 5/6/1972
Date is 6-5-1972
If you have time, try some of these exercises:-
1. Create a program that generates two random numbers between 1 and 10 using the rand() function, storing them into two separate variables called val1 and val2. Multiply these together and store the result into another variable called result. Then display the sum and the result using a printf command, remembering to use the %d specifiers and listing the variables as parameters at the end of the printf command. At the end, use the getch(); command to pause the display so you can see your result.
2. Write a program that generates a random number between 1 and 10, and asks the user to input a number. Write the two numbers out to the screen so that you can visually see if they match.
3. Write a program that asks for somebody's date of birth in the format date:month:year using these words as variable names. Use the formula (year-1900)*365+month*12+date to work out roughly a day value. Now take today's date in the same format from the user and use a similar formula to work out a day value for today's date. Now take the birth day value from today's day value and display this on the screen as roughly the number of days the person has been alive.