C Programming Tutorial 4 - Variables and Memory

In this tutorial series so far, we have discussed how to create and run a basic C program, what are preprocessors, as well as basics of variables. Now let's dig a bit deep into variables and discuss the memory aspect.

Assuming you have already gone through all our tutorials so far (or you have basic knowledge required to understand this tutorial), let's begin with a simple code example we used in one of our previous tutorials.

#include <stdio.h>

int main (void)
{
int num = 0, temp=0;
printf("\n Enter a positive integer: ");
scanf("%d", &num);
temp = num;
int result = 1;
while (temp > 0)
{
result = result * temp;
temp = temp -1;
}

printf("\n Factorial of %d is %d\n", num, result);

return 0;
}

This program, as you can see, calculates factorial of a number entered by a user.

Now, for smaller integers like 5 or 6, this program will work fine - it will correctly output the factorial result. But, let's say you try it out for number 13. Here's the result you'll get:

Factorial of 13 is 1932053504

But that's not true as the factorial of 13 is 6227020800. So, naturally, the question is why our program gave wrong answer? Well, the answer lies in the amount of memory an int variable occupies in system.

In most systems today, int occupies 4 bytes (or 32 bits) of memory. Note that you can use the following line in your program to know the amount of bytes int occupies on your system.

printf("\n int size in bytes is: %d ", sizeof (int));

And since an int variable can store negative values as well, the range of values it can store varies from -2,147,483,648 to 2,147,483,647.

Now, since factorial of 13 is far greater than the maximum value an int variable can hold, our program gives a wrong output. The only way to get the program corrected is to use a variable type that has the capacity to hold 6227020800. 

If you want to hold a bigger positive integer value, you can use 'unsigned int', which can store values ranging from 0 to 4,294,967,295 (assuming this type of variables occupy 4 bytes on your system). But here, even 'unsigned int' won't do as the factorial of 13 is beyond its max capacity.

So our savior here would be 'long long,' which occupies 8 bytes or 64 bits of memory. So here's the revised program:

#include <stdio.h>

int main (void)
{
long long num = 0; long long temp=0;
printf("\n Enter a positive integer: ");
scanf("%d", &num);
temp = num;
long long result = 1;
while (temp > 0)
{
result = result * temp;
temp = temp -1;
}

printf("\n Factorial of %lld is %lld\n", num, result);

return 0;
}

The way you make printf or scanf identify a 'long long' variable is by using %lld (or %I64d in some cases). Here's the output this modified program produces:

Factorial of 13 is 6227020800 

Which is correct.

So, now we know the limitation of 'int' and how 'unsigned int' and 'long long' can be used to overcome that. Keep in mind that 'long; ' is also a variable type but on most systems today, both int and long occupy 4 bytes.

Oh, and yes, while 'int', 'unsigned int' and 'long long' are for integers, there's 'float' and 'double' for floating point numbers. Float is 32 bit and has 7 decimal digits of precision, while double is 64 bit and has 15 decimal digits of precision. 

The mention of floating point numbers brings me to another important point here. It's related to division. Let's take a simple C code example to understand this.

int main (void)
{
int a=5, b=10;

printf("\n a/b is %d", a/b);

return 0;
}

So this program does nothing, but divide a by b, or 5 by 10.

In real life, if you ask anyone the result of 5/10, you'll get 0.5 as the answer in majority of the cases. But here, the answer will be zero (0). Reason being, both 'a' and 'b' are integers, and hence the result of their division will also be considered as an integer, and so the floating part will get disregarded.

To preserve the floating part, you'll have to make sure both 'a' and 'b' are floating point variables.

#include <stdio.h>

int main (void)
{
float a=5, b=10;

printf("\n a/b is %f", a/b);

return 0;
}

In this case, the output would be 0.5.

Conclusion

In this tutorial, we discussed about variable size and how it affects storage of values. I hope you'd got a good idea on how and when to use int, unsigned int, long long, float, and double. In the next tutorial, we'll be discussing character type variables as well as arrays. 

Share this page:

Suggested articles

1 Comment(s)

Add comment

Comments

By: Crito Philippatos at: 2019-05-09 17:55:45

First, thanks for these excellent tutorials.

The factorial example above contains an error, however. scanf still expects an integer and num is defined as long long. So I changed:

 int num = 0; long long temp = 0, result = 1;

 printf("\n Factorial of %d is %lld\n", num, result);