Skip to main content

Sphere - With Functions

A new version of Sphere Program

Suppose I want to change the Sphere program that we wrote in the previous chapter. What I want to do is to ask the user to enter the radius of 3 different spheres, then we calculate

  • the total volume of all 3 spheres.
  • the total surface area of all 3 spheres.

Breaking up this problem, we see the following general steps:

  1. Prompt and read the radius of the first sphere
  2. Prompt and read the radius of the second sphere
  3. Prompt and read the radius of the third sphere
  4. Calculate the volume of the first sphere
  5. Calculate the volume of the second sphere
  6. Calculate the volume of the third sphere
  7. Add up the volumes
  8. Calculate the surface area of the first sphere
  9. Calculate the surface area of the second sphere
  10. Calculate the surface area of the third sphere
  11. Add up the surface area
  12. Output the results

Other than needing to find the formula for calculating the surface area of a sphere, we already know how to do everything above. However, what you notice about the above is that there is actually a lot of similarities between steps 1 to 3. There is also a lot of similarities between steps 4 to 6 and steps 8 to 10.

Looking at spec :

  • We need to repeat the code to prompt and read 3 times.
  • We need to calculate the volume 3 times and then we would need to add up the volumes.
  • We need to also calculate the surface area 3 times and add up those values.
  • We need to print the total volume and total surface area
  • We don't need to print out the volume of any one sphere.

To find the surface area of a sphere, we can find this on the internet:

Surface Area of sphere = 4π(radius2){4}\pi({radius}^2)

Now, lets put this together... we write the code to read the radius, calculate volume and area, then we copy and paste the code 3 times:

#include <stdio.h>
int main(void)
{

double radius;
double volume;
double area;

printf("Please enter the radias of the sphere: ");
scanf("%lf",&radius);
volume = 4.0/3 * 3.14159 * radius * radius * radius;
area = 4 * 3.14159 * radius^2

printf("Please enter the radias of the sphere: ");
scanf("%lf",&radius);
volume = 4.0/3 * 3.14159 * radius * radius * radius;
area = 4 * 3.14159 * radius^2

printf("Please enter the radias of the sphere: ");
scanf("%lf",&radius);
volume = 4.0/3 * 3.14159 * radius * radius * radius;
area = 4 * 3.14159 * radius^2

total = volume + volume + volume;
printf("Total volume = %.2lf\n", total);

total = area + area + area;
printf("Total surface area = %.2lf\n" total);

return 0;
}

The above program is create by copying and pasting.. it has bugs... can you spot them all?

Expand for bug list... how many did you find?
Details
  1. total is undeclared
  2. the value of each of the later two calculations for surface area and volume overwrote the previous. A single variable cannot hold the result of 3 different calculations at the same time. Each time you calculate volume, the previous volume is replaced by the value of the new epression
  3. missing , in printing of total surface area. missing semi-colon at end of surface area calculation
  4. area calculation is not calculating radius2{radius}^2 because the ^ operator does not calculate exponents.
  5. radius is spelled incorrectly in the prompt as "radias"

How do we fix this?

If we were to fix the code but leave the structure of the code the same, we will find that we would have to fix the same bug in multiple places. In a larger program, we may end up having copied the error to multiple files. Is there a better way to do this?

Use functions!

We have 3 separate basic things we want to do:

  • prompt and read
  • calculate volume
  • calculate area

Each of these can be turned into a function. Each function has the following:

  • a descriptive name (just like variables)
  • 0 or more parameters. Parameters are the data to the function allowing the results to vary based on this data.
  • a return value. The return value is the result of the function. It is also possible that no results are given back from a function.

Prompt and Read Function:

This function prompts the user to enter a radius, read the value in and returns it

Start by giving the fuction a good descriptive name. In this case, I'm going to call it getRadius. This name describes what the function does.

Next, we want to consider what the result of this function is. This function will read in a radius so we want the result of the function to be the radius we read in

Finally, what parameters (if any) do we want to provide? If we are fine with using the same prompt every time, we do not need any parameters. However, we can pass in a number indicating which sphere's radius we are reading in. This will allow us to slightly vary the prompt each time.

Function Definition

This block of code below is called a function definition. It is made of the steps the functions will perform everytime we use it.

double getRadius(int sphereNumber)
{
double radius;
printf("Please enter the radias of sphere # %d: ",sphereNumber);
scanf("%lf",&radius);
return radius;
}

Function Calls

To use the above block of code, we must make a function call.

#include <stdio.h>
int main(void)
{

double radius;

//getRadius(1) is a function call to the getRadius function
//main pauses at this point and we execute the code in the
//getRadius() function.
radius = getRadius(1);


}

Similarly we can create a function to calculate the volume of a sphere and the surface area of a sphere as follows:

double volumeOfSphere(double radius)
{
return 4.0/3 * 3.14159 * radius * radius * radius;
}
double surfaceAreaOfSphere(double radius)
{
return 4 * 3.14159 * radius^2
}

You will notice that the code haskept all the errors from our previous example. This is on purpose to illustrate the changes we would need to make to fix our program.

Putting all this together, our program now looks like this:

#include <stdio.h>

double volumeOfSphere(double radius)
{
return 4.0/3 * 3.14159 * radius * radius * radius;
}

double surfaceAreaOfSphere(double radius)
{
return 4 * 3.14159 * radius^2
}

double getRadius(int sphereNumber)
{
double radius;
printf("Please enter the radias of sphere # %d: ",sphereNumber);
scanf("%lf",&radius);
return radius;
}

int main(void)
{
double radius;
double volume;
double area;

radius = getRadius(1);
volume = volumeOfSphere(radius);
area = surfaceAreaOfSphere(radius);

radius = getRadius(2);
volume = volumeOfSphere(radius);
area = surfaceAreaOfSphere(radius);

radius = getRadius(3);
volume = volumeOfSphere(radius);
area = surfaceAreaOfSphere(radius);

total = volume + volume + volume;
printf("Total volume = %.2lf\n", total);

total = area + area + area;
printf("Total surface area = %.2lf\n" total);
return 0;
}

This code still has all the errors we had previously identified. Lets look at how to fix each of the errors.

Recall that the errors were:

  1. total is undeclared
  2. the value of each of the later two calculations for surface area and volume overwrote the previous. A single variable cannot hold the result of 3 different calculations at the same time. Each time you calculate volume, the previous volume is replaced by the value of the new epression
  3. area calculation is not calculating radius2{radius}^2 because the ^ operator does not calculate exponents.
  4. missing semi-colon at end of surface area calculation
  5. radius is spelled incorrectly in the prompt as "radias"

Bugs 1 to 3.

The third bug is just a syntax error. We fix it by adding the comma into the correct position

The first two bugs can actually be solved together. Firstly, we don't need to store each of the individual volumes and areas. What we need is to simply have a running total of these values.

Thus, the fix is to remove the total variable all together and modify the name of the volume and area variables to indicate that they are storing the total. After the first function call, we can just add the result to the total

warning

renaming variables do not alter what the code does. However, it does help to remind us what it is that we plan to do with a variable. We should always be as clear as possible in our variable naming.

Thus, our code is now this.

#include <stdio.h>

double volumeOfSphere(double radius)
{
return 4.0/3 * 3.14159 * radius * radius * radius;
}

double surfaceAreaOfSphere(double radius)
{
return 4 * 3.14159 * radius^2
}

double getRadius(int sphereNumber)
{
double radius;
printf("Please enter the radias of sphere # %d: ",sphereNumber);
scanf("%lf",&radius);
return radius;
}

int main(void)
{
double radius;
double totalVolume;
double totalArea;

radius = getRadius(1);
totalVolume = volumeOfSphere(radius);
totalArea = surfaceAreaOfSphere(radius);

radius = getRadius(2);
totalVolume += volumeOfSphere(radius);
totalArea += surfaceAreaOfSphere(radius);

radius = getRadius(3);
totalVolume += volumeOfSphere(radius);
totalArea += surfaceAreaOfSphere(radius);

printf("Total volume = %.2lf\n", totalVolume);
printf("Total surface area = %.2lf\n", totalArea);
return 0;
}

Bugs 4 to 6:

  • area calculation is not calculating radius2{radius}^2 because the ^ operator does not calculate exponents.
  • missing semi-colon at end of surface area calculation
  • spelling error

These two bugs can be modified by just doing the operation by multiplying radius by itself and fixing the semicolon:

As we are using functions, we only need to make the following fix:

double surfaceAreaOfSphere(double radius)
{
return 4 * 3.14159 * radius * radius;
}

That is, the fix is in one single place. By fixing the one line, we fixed it for every call.

Similarly, to fix our spelling error, we only need to fix the printf in this one function:

double getRadius(int sphereNumber)
{
double radius;
printf("Please enter the radius of sphere # %d: ",sphereNumber);
scanf("%lf",&radius);
return radius;
}

Function prototypes:

Our main() function is at the bottom of the file. Adding all these functions to the file makes it harder for us to read our code as the main() function, the starting point for our program, is buried further down in the file.

If we move the main() function to the top of our file, the program will actually no longer compile. It will instead produce a syntax error that essentailly says that it doesn't know what our functions are. This is because of a programming concept called declaration before use. Since main() was listed first, it essentially hasn't gotten to a point where it knows what getRadius(), volumeOfSphere() or calculateArea() is...it hasn't seen these functions in the code yet.

To solve this problem, we use something called function prototypes. A function prototype consists of the following:

returnType functionName(argtype1 <optional name>, argtype2 <optional name>, ...);

For example, here is the function prototype for our volumeOfSphere() function.

double volumeOfSphere(double radius);

In the prototype, we do not need to put in the name as we are only stating that this function must accept a double as it's only argument.

Putting all of this together, here is the final version of our program:


#include <stdio.h>

// function prototypes
double volumeOfSphere(double radius);
double surfaceAreaOfSphere(double radius);
double getRadius(int sphereNumber);

int main(void)
{

double radius;
double totalVolume;
double totalArea;

radius = getRadius(1);
totalVolume = volumeOfSphere(radius);
totalArea = surfaceAreaOfSphere(radius);

radius = getRadius(2);
totalVolume += volumeOfSphere(radius);
totalArea += surfaceAreaOfSphere(radius);

radius = getRadius(3);
totalVolume += volumeOfSphere(radius);
totalArea += surfaceAreaOfSphere(radius);

printf("Total volume = %.2lf\n", totalVolume);
printf("Total surface area = %.2lf\n", totalArea);
return 0;
}

//function definitions:

double volumeOfSphere(double radius)
{
return 4.0/3 * 3.14159 * radius * radius * radius;
}

double surfaceAreaOfSphere(double radius)
{
return 4 * 3.14159 * radius^2
}

double getRadius(int sphereNumber)
{
double radius;
printf("Please enter the radius of sphere # %d: ",sphereNumber);
scanf("%lf",&radius);
return radius;
}