C Programming in 2021

by Ray Dall

################################################################################
Section 5
################################################################################
Now let's look at this program in more detail:
/*
   NAME:        calc1.c
   DESCRIPTION: Teaches definitions, float TYPEs, scanf(), if-then, and maths.
   SYNOPSIS:    ./calc1
*/

#include <stdio.h>

#define PI 3.1415926

int main()
{
printf("\033[H");printf("\033[J"); // clears the screen
printf("%f\n",PI);
return(0);
}



In this program, we have introduced a new command - printf(). Whenever you encounter a new command, you should take the time to read the unix programmers manual on that command. In this case:

man 3 printf

If you type this into a terminal, you will get the manual (use q to escape), which is WAY more information overload than you can absorb at the moment. There are some things in the manual that are important to notice though:

For starters - how do you USE this function in a C program? Usage is covered under the SYNOPSIS section:
SYNOPSIS
       #include 

       int printf(const char *format, ...);
       int fprintf(FILE *stream, const char *format, ...);
...
printf prints out (to the terminal) FORMATTED text - hence print f.

The format is usually as follows:

printf("THIS IS A TEST"); - this simply prints out the text between the quotes.

printf("%f",PI); - this will print out the float PI wherever you put the %f between the quotes.
so
printf("PI = %f"); - will print out on the screen:
PI = 3.1415926536

Another important thing to know is what the return value is.
Like all functions, the printf function has a return. What does it return and why is it important? If we read our manual (man 3 printf), we get this:
RETURN VALUE
       Upon successful return, these functions return the number of  characters
       printed (excluding the null byte used to end output to strings).
...
       If an output error is encountered, a negative value is returned.
What this tells us is what to expect if it works, or more importantly - if it fails. We know because printf is an int type, it will always return an integer. This could be a positive, negative, or zero integer. If it prints nothing, it will return a zero. If it prints anything else, it will return a positive integer equivalent to the number of characters it printed out. But if it fails - it will return a NEGATIVE integer. This becomes important when you start writing error checking in to your programs.

ALL PROGRAMS can have errors. Sometimes they are due to mistakes you made in the code. Sometimes it is due to unexpected user input (Your program asks for a float or an int, and you type in a sentence like "the sky is blue". If a program does something unexpected, it sometimes fails, and when it does, if the program is written well, it returns a value that tells the user/programmer HOW and WHERE in the program it failed. Error checking can be a lifesaver. That is why we need to know what a function normally, and abnormally, should return.

Of course, there is much more information found in the man file. So much an entire course could be written on man pages, what you can find in them, how they are created, and why you should write a man page for every project you complete... but this is not that course.

Now let's continue with our simple calculator program.

The calculator program will, when finished, calculate the circumfance and area of a circle, given the radius. Of course, in order to write the program, you have to know the basics of circle math.

A circle has a radius, a diameter, a circumfrance and an area.

I find the best way to describe these is to use goat technology.

Assume that a goat is tied to a pole. The diameter is the distance across the circle, from one side to the other, if the goat were to walk from one edge to the other in a straight line across the middle pole.

The radius is half that long, or the distance from the pole in the exact middle of the circle to one edge. The math for that is:

Diameter = 2 times the Radius, or
D=2*R

The circumfrance is the distance around the circle if the goat were to start at one point and walk all the way around the circle until you reach that same point. The formula for circumfrance is:

Pi (π), pronounced like pie, is the greek symbol that roughly can be estimated by 355/113. The exact number is infinite, and is calculated by calculation from real measurements of real circles (the bigger the circle, the more accurte the estimation of π).

Circumfrance = 2 times π times the radius, or
C=2πR or
2 * PI * R

Finally, the area of a circle is the measurement of grass that the goat would eat if it continued walking in circles around the pole, with the rope constantly getting shorter as it wound around the pole. Eventually all the grass inside the circle would be eaten, and that would be the area of the circle. (Assuming the goat didn't eat the rope too!

Area = π times the square of the radius, or
πR2

Since the square of any number simply means multiplying the number times itself, we could also write that as π * R * R

Now on with the program:

/*
   NAME:        calc1.c
   DESCRIPTION: Teaches definitions, float TYPEs, scanf(), if-then, and maths.
   SYNOPSIS:    ./calc1
*/

#include <stdio.h>
#define PI 3.1415926

int main()
{
float RADIUS=0.0;
float CIRCUMF=0.0;
float AREA=0.0;
printf("\033[H");printf("\033[J"); // clears the screen

printf("THIS PROGRAM CALCULATES THE AREA AND CIRCUMFRANCE OF A CIRCLE\n");
printf("Assume: PI = %i\n",PI);
printf("Enter the RADIUS of the circle:\t");
scanf("%f",&RADIUS);
CIRCUMF=2*PI*RADIUS;
AREA=PI*RADIUS*RADIUS;
printf("If the radius is %f, then the\n",RADIUS);
printf("CIRCUMFRANCE is %f, and the\n",CIRCUMF);
printf("AREA is %f.\n\n",AREA);
return(0);
}
If you recall in section 2, we covered types, and specifically the "int" type, which is short for integer. Integers are whole numbers that can be written without any fractions or decimal parts.
5 is an integer
5.25 is a decimal, it is not an integer.
5/16 is a fraction. It is also not an integer.
-2, 144, and 0 are all integers.

If in C we wish to use a decimal, we call it a "float", or floating point decimal. Before we can use a variable, we have to declare it. If we declare a variable that is a float, we don't declare it as an int, or it won't come up with the correct results. We declare it as a float.


// type	 identifier	arguments	endpunc
   int	 main		()		{}
   int   printf         ()              ;
   int   ZERO           = 0             ; // Note - no decimal point and "int"

   float RADIUS         = 23.6          ; // Note - decimal point and "float"



So in our calc1.c program, we declare 3 variables:
float RADIUS=0.0;
float CIRCUMF=0.0;
float AREA=0.0;


After a few printf() statements, we then do something we've not done before. We let the computer ask you a question and wait for input. We do this using the scanf() function.

We didn't write the scanf() function, so we have to #include it at the top. But where can the computer find the pre-written scanf() function, and how does it work? Well - let's check the manual ( RTFM ).

man 3 scanf

When we read SYNOPSIS of the scanf programmers manual, we find that it is included in the standard input/output header file.
SYNOPSIS
       #include <stdio.h>

       int scanf(const char *format, ...);
Fortunately, we've already used its sister command printf(), so we already have
       #include <stdio.h>
in our header. We don't need to add it a second time.

We also see how the program is used (rougly), and find that it is used nearly identical to the printf() function.
One difference, though, is that when you give it input, it needs to store the data you typed in somewhere. It stores it in the computer's memory. YOU don't need to know where it stores it, but the computer does - so it expects an ADDRESS. All computer memory has addresses. Think of it like mail boxes. If you mail a letter to someone, it goes to their mail box. The postman knows which box to put it in based on the address number. Same with a computer. When the computer looks for a piece of data, it will only find the data located in that address.

In our program, we have the function:
     scanf("%f",&RADIUS);

Prior to that, we had a declaration of a function:
     float RADIUS=0.0;

We declared the float "RADIUS" and defined it with a value of 0.0
Now, we wish to use RADIUS, and store some random data into it.
scanf() (a function somone else wrote years ago) needs to store the input data someplace. In doing so, scanf() needs to know the exact memory location of the variable. The ampersand ( & ) in C means "The Address Of". & is called as address operator. For example, &temp would be the ADDRESS where the variable temp is stored in memory.

So when we tell the program
     scanf("%f",&RADIUS);

we are telling it to scan for a keyboard input in float form, and store it into the ADDRESS of the variable RADIUS (&RADIUS).

The next two lines perform the calculations:
     CIRCUMF=2*PI*RADIUS;
     AREA=PI*RADIUS*RADIUS;


Then finally it prints the answer.

Go ahead - type the program into nano, save it, compile it and run it. Use a few different radii (plural of radius), and see the difference. Use floats and integars.

Try a radius of 1, 2, and 3. You may be surprised at the outcome.

################################################################################
1 2 3 4 5 6
################################################################################