Download as pdf or txt
Download as pdf or txt
You are on page 1of 21

What Are the Different C Variable Types?

1. We have used variables before in our programs (like x, y, z or count). A variable is a named
data storage location in the microcontroller’s memory that is assigned a value.

2. Although you can name a variable just about anything there are some constraints:

 Names can only contain letters, digits and underscores


 The first character must be a letter
 Variables are case sensitive
 They cannot be a previously reserved word like while, for, and if

3. In addition to variables, the C programming language also allows you to designate a memory
location as a constant (designated with the prefix const). Constants are like variables only the
value cannot be changed in your program after being declared.

4. Variables and constants are often time differentiated by their names. Often, constants have names
written with UPPER CASE letters (WATER_BOIL_TEMPERATURE) where variables are written in
lower case letters (count).

5. Constants are very helpful in larger codes where you want to avoid changing certain values, like
, but in this class we’ll tend avoid these in our codes as they usually aren’t necessary.

Copyright © 2012-2015 Page 1 of 21


Valparaiso University
6. There are several different types and sizes of variables which can be used in different situations.

The basic variables types are characters, integers, long integers and floating point.

 characters (or char) are variables that only use one byte of memory. They derive
their name from the fact that each char variable can hold one text character

 integers (or int) are variables that use two bytes of memory. Because they use more
memory than char variables, int variables can hold significantly larger numeric values

 long integers (or long) are variables that use four bytes of memory. Because they use
more memory than char and int variables, long variables can hold significantly larger
numeric values

 floating point numbers (or float) are variables that also use four or eight bytes of
memory. However, unlike char, int, and long variable types, float variables can
store integers and fractional numbers with a relatively good amount of precision.

7. Next, characters, integers, long integers can be specified as unsigned or signed variables.

 unsigned variables are used to store non-negative integers

 signed variables are used to store any integer value

For example, you can designate two variables, a and b like this:

unsigned char a;
signed char b;

Since both variables have a base type of char, they will each use one byte of your
microcontroller’s memory.

Copyright © 2012-2015 Page 2 of 21


Valparaiso University
8. Recall from our digital logic section, that one-byte of memory can hold the non-negative integers
from 0 to 255 (or 256 different possible values). Therefore, the range of integers that you can
store in an unsigned char are 0 to 255.

signed char variables also use only one byte of memory, therefore, they are also limited to
only 256 different possible values. This limits the maximum and minimum integer values they
can store from -128 to +127.
Below, you can see each of the common data types, the amount of memory they consume, and
their effective memory range. (Note, in a couple more steps, you will see what happens when
you try to store a number outside of these ranges.)

So what variable types should you use? Unfortunately, like a lot of things in life, the answer
depends. However, there are two general rules that you can use:

1) Do not use float variables unless absolutely necessary. While they are comparable in
size to the other variable types, float variables are much more difficult for your
microcontroller to manipulate. If you use even one float operation (like addition), your
program may grow by several kilobytes.

2) Use a smaller variable type to hold smaller values.

Copyright © 2012-2015 Page 3 of 21


Valparaiso University
9. Declaring variables and initializing their values is very simple. You have done this a number of
times already in this class. Just remember, you don’t need to declare a value right away. You
can state the type and then initialize it to a value later. For example, all of these are valid
statements in the C programming language to create and initialize four different variables.

unsigned char a;
signed int b = -204;
unsigned long c = 3;
float pi;

a = 255;
pi = 3.14159;

10. Another handy trick is you can declare multiple variables of the same type at once by separating
their names with a comma:

unsigned char a, b, c, d, e;

Copyright © 2012-2015 Page 4 of 21


Valparaiso University
11. As stated earlier, we will avoid using constants in this course. However, if you want to see an
example of how they can (and cannot!) be used, take a look at the example below.

As you can see, line 13 is an acceptable use of a constant, but line 15 is invalid and generates an
error.

Copyright © 2012-2015 Page 5 of 21


Valparaiso University
12. Let us see how these variable types behave in CCS. Copy this program into a new CCS project.

Don’t forget to turn off optimization!

#include <msp430.h>
main()
{
char a;
char b;
unsigned char c;
signed char d;
int e, f;
unsigned int g, h;
signed int i, j;
unsigned long int k;
signed long int l;
float m, n;
double o;

a = 200;
b = -100;
c = 200;
d = -100;
e = 40000;
f = -10000;
g = 40000;
h = 100000;
i = -10000;
j = -50000;
k = 100000;
l = -50000;
m = 3.4565;
n = 5.4345235645;
o = 5.4345235645;

while(1);
}

Copyright © 2012-2015 Page 6 of 21


Valparaiso University
13. Save and Build your project. At this point, you will see a number of warnings listed by some of
your program’s lines (see below). For now, don’t worry about this. We will take a look at what
these mean when we look at the variable values with the Debugger.

Copyright © 2012-2015 Page 7 of 21


Valparaiso University
14. Launch the Debugger. Your screen will look something like this. Note, you may have different
values in your variables before your program runs, so do not worry if the values do not match the
screenshot.

Copyright © 2012-2015 Page 8 of 21


Valparaiso University
15. For the variables a – l, right click on their Values, and change the Number Format to
Decimal.

Also, widen the Value column sufficiently so you can see the entire cell contents.

Copyright © 2012-2015 Page 9 of 21


Valparaiso University
16. Click Resume to run your program. After a few moments, click Suspend (pause) to see the
updated Values in the Variables pane.

Take a look at the images below. Do the variable Values match their expected values from your
program? There is a lot going on here, so we tried to break this out step-by-step for you.

The variables a and b were defined as type char in the program without a further designation of
signed or unsigned. CCS will default these to unsigned char variables (stores 0 to 255).
This allow you to correctly store a=200, but results in an incorrect result when you try to store
b=-100.

c was defined as an unsigned char and correctly stores the value of 200.

d was defined as an signed char (stores -128 to +127) and correctly stores the value of -100.
Note, that the variable type is simply shown as char in the Variables pane. The signed
designator is implicit.

Copyright © 2012-2015 Page 10 of 21


Valparaiso University
The variables e and f were defined as type int in the program without a further designation of
signed or unsigned. CCS will default these to signed int variables (stores -32,768 to
+32,767). This allow you to correctly store f=-10000, but results in an incorrect result when
you try to store e=+40000. Note, that the variable type is simply shown as int in the
Variables pane. The signed designator is implicit.

g was defined as an unsigned int (0 to +65,535) and correctly stores the value of 40,000.

h was defined as an unsigned int and incorrectly stores the value of 100,000 which exceeds
the upper limit).

i was defined as a signed int (-32,768 to +32,767) and correctly stores the value of -10,000.

j was defined as a signed int and incorrectly stores the value of -50,000 which is lower than
the -32,768 bottom limit.

k was defined as a unsigned long int (0 to approximately +4,000,000,000) and correctly


stores the value of +100,000.

l was defined as a signed long int (approximately -2,000,000,000 to approximately


+2,000,000,000) and correctly stores the value of -50,000.

m was defined as a float which allows you to store non-integers with approximately 7 digits of
precision. Therefore, since 3.4565 is less than 7 digits long, its value is stored correctly.

n was defined as a float which allows you to store non-integers with approximately 7 digits of
precision. However, since 5.4345235645 is more than 7 digits long, the stored value only
approximates the desired value.

o was defined as a double which allows you to store non-integers with approximately 15 digits
of precision. Therefore, since 5.4345235645 is less than 15 digits long, its value is stored
correctly.

Copyright © 2012-2015 Page 11 of 21


Valparaiso University
17. Let’s look at some of these concepts a little bit closer. Create a new CCS project with the
following instructions.

Do not forget to turn off all the optimizations. If you do not turn off the optimizations, you may
not be able to watch the value of the count change in the Variables pane.

#include <msp430.h>

main()
{
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

unsigned char count = 250;

while(1)
{
count = count + 1;
}
}

18. Save and Build your project and launch the Debugger.

19. Start stepping through it using the Step Into command. Watch the value of count closely
(make sure it’s displayed in decimal). Pay close attention when you get to 255 decimal.

Copyright © 2012-2015 Page 12 of 21


Valparaiso University
20. When you press Step Into again, it will return to 0 because the maximum limit the unsigned
char can hold is 255.

21. Let us look at one more example, this time using signed variables. Copy the program below
into a project. Make sure optimization is turned off. Save and Build the program.

#include <msp430.h>

main()
{

WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

signed char count_up = +120;


signed char count_down = -120;

while(1)
{
count_up = count_up + 1;
count_down = count_down - 1;
}

Copyright © 2012-2015 Page 13 of 21


Valparaiso University
22. Launch the Debugger. Make sure the Number Format for count_up and count_down are
Decimal.

Step through your code until the two variables are +127 and -127, respectively.

23. Before we increment count_up again, let us take a moment and think about the expected result.

Normally, when we add 1 to 127, and we would expect a result of 128. However, as we saw
earlier, the maximum positive value a signed char variable can store is 127.

What do you think will happen?

Copyright © 2012-2015 Page 14 of 21


Valparaiso University
24. Go ahead and click Step Into and increment count_up. The variable value changes from
+127 to -128.

Copyright © 2012-2015 Page 15 of 21


Valparaiso University
25. We will take a look at why this happens in just a moment, but first, let us see what happens to
count_down.

Continue stepping through the program until count_down reaches -128. Again, normally, when
we subtract 1 from -128, we would expect a result of -129. However, as we saw earlier, signed
char variables cannot store numbers below -128.

What do you think will happen?

Copyright © 2012-2015 Page 16 of 21


Valparaiso University
26. Go ahead and click Step Into and decrement count_down. The variable value changes from
-128 to +127.

Copyright © 2012-2015 Page 17 of 21


Valparaiso University
27. So, to summarize… In a signed char:

+127 + 1 = -128

-128 – 1 = +127

This does not seem to make a lot of sense, but there is a method to it.

Normally, we think of numbers on a number line. Many of you learned about numbers this way
in school.

If we add one to a number, we move in the positive direction to the right.

If we subtract one from a number, we move in the negative direction to the left.

More More
Negative Positive
-4 -3 -2 -1 0 +1 +2 +3 +4

28. This method works well for our imagination because we can conceive of incredibly large
numbers like +47,295,955,994,225,014,396 and -8,934,098,469,524,114,735.

However, these numbers are too large for most microcontrollers to store. Remember, in our
example, our signed char variable only has one byte of memory and can store only 256
different values (-127 to +128).

Copyright © 2012-2015 Page 18 of 21


Valparaiso University
29. For microcontroller memory, the number line actually takes the form of a number circle. It does
not stretch to positive and negative infinity. Rather, it wraps around upon itself. For example,
here is what it looks like for signed char variables.

As we are adding one to a number, we move clockwise around the circle:

+120, +121, +122, +123, +124, +125, +126, +127

When we reach the bottom of the circle, the number line “wraps” around to the most negative
number (-128). If we were to continue adding one to our example, we would see the process
repeats.

+127, -128, -127, -126, -125, … , -2, -1, 0, +1, +2, … , +126, +127, -128, -127, -126…

-1 0 +1
-2 +2
-3 +3
-... +...

Subtracting 1 Adding 1

-... +...
-125 +125
-126 +126
-127 -128 +127

Copyright © 2012-2015 Page 19 of 21


Valparaiso University
30. Similarly, for unsigned variables, the number line again becomes a circle:
0, +1, +2, +3, … , +253, +254, +255, 0, +1, +2, … , +254, +255, 0, +1, +2, …

+255 0 +1
+254 +2
+253 +3
-... +...

Subtracting 1 Adding 1

-... +...
+131 +125
+130 +126
+129 +128 +127

31. While this may seem very problematic, working with signed variables or unsigned variables is
only a concern when the program move beyond the threshold values that a variables can hold.

In practice, this is rarely a problem when systems and programs are well planned, but accidents
can occur. Therefore, if you see an unusual result like:

123 + 10 = -129

You may want to go back and look at your variable types.

Copyright © 2012-2015 Page 20 of 21


Valparaiso University
All tutorials and software examples included herewith are intended solely for
educational purposes. The material is provided in an “as is” condition. Any
express or implied warranties, including, but not limited to the implied warranties
of merchantability and fitness for particular purposes are disclaimed.

The software examples are self-contained low-level programs that typically


demonstrate a single peripheral function or device feature in a highly concise
manner. Therefore, the code may rely on the device's power-on default register
values and settings such as the clock configuration and care must be taken when
combining code from several examples to avoid potential side effects.
Additionally, the tutorials and software examples should not be considered for use
in life support devices or systems or mission critical devices or systems.

In no event shall the owner or contributors to the tutorials and software be liable
for any direct, indirect, incidental, special, exemplary, or consequential damages
(including, but not limited to, procurement of substitute goods or services; loss of
use, data, or profits; or business interruption) however caused and on any theory
of liability, whether in contract, strict liability, or tort (including negligence or
otherwise) arising in any way out of the use of this software, even if advised of
the possibility of such damage.

Copyright © 2012-2015 Page 21 of 21


Valparaiso University

You might also like