\\
Corning Community College
\\
UNIX/Linux Fundamentals
\\
\\
Case Study 0x8: Data Types in C
\\
\\
~~TOC~~
=====Objective=====
To determine and test the limits of common data types in C.
=====Background=====
There are several data types available for you to manipulate in C:
^ data type ^ description |
| char | ASCII characters |
| short int | small range of integers |
| int | standard integer range |
| long long int | large range of integers |
Each data type can be a signed or unsigned quantity. The sign of a quantity is simply whether or not it includes negative values. For example, let's look at an unsigned 4-bit quantity:
^ decimal ^ hexadecimal ^ binary |
| 0 | 0x0 | 0000 |
| 1 | 0x1 | 0001 |
| 2 | 0x2 | 0010 |
| 3 | 0x3 | 0011 |
| 4 | 0x4 | 0100 |
| 5 | 0x5 | 0101 |
| 6 | 0x6 | 0110 |
| 7 | 0x7 | 0111 |
| 8 | 0x8 | 1000 |
| 9 | 0x9 | 1001 |
| 10 | 0xA | 1010 |
| 11 | 0xB | 1011 |
| 12 | 0xC | 1100 |
| 13 | 0xD | 1101 |
| 14 | 0xE | 1110 |
| 15 | 0xF | 1111 |
So, in a 4-bit quantity, you've got 16 distinct values. It is considered 4-bit because we are dealing with the binary values-- what the computer deals with. If we were dealing with an 8-bit quantity, there would be 8 bits for use in counting.
Actually, to determine the number of unique states, you'd use the following: **2^n**
Where n is the number of bits you are dealing with. In this case: 4-bits = 2^4 = 16
The values in the above table are all unsigned quantities, in that they are only the positive representation. To play with signed quantities, we use the leftmost bit (the Most Significant Bit (MSB)) as the sign-- where 0 is positive and 1 is negative.
In this case, we now have the following values:
^ decimal ^ signed binary |
| -8 | 1000 |
| -7 | 1001 |
| -6 | 1010 |
| -5 | 1011 |
| -4 | 1100 |
| -3 | 1101 |
| -2 | 1110 |
| -1 | 1111 |
| 0 | 0000 |
| 1 | 0001 |
| 2 | 0010 |
| 3 | 0011 |
| 4 | 0100 |
| 5 | 0101 |
| 6 | 0110 |
| 7 | 0111 |
NOTE: Negative values are obtained by subtracting one and then inverting all the bits.
To obtain the negative bit representation of a number, we perform an operation known as **two's complement**:
6 = 0110
6 - 1 = 5 ---> 0110 - 0001 = 0101
Then invert (turn 0's to 1's, and 1's to 0's): 0101 ---> 1010
As you can see, we still have all 16 distinct states, but they are now represented in positive and negative values. The range of 4-bit signed integers here is -8 to +7, where the range of 4-bit unsigned integers is 0 to 15.
Now, you may be wondering why this is relevant-- basically, the ranges of things like integers aren't a fixed absolute value from system to system.
This could result in some calculation problems if a program is written expecting integers to be 32-bit values and the host system treats integers as 16-bit values.
It is important to know what these values are on any system you program on. Guess what you get to determine and experiment with in this Case Study :)
=====Procedure=====
Checking the values: **limits.h**
^ 1. ^|Using the **find**(**1**) utility:|
| ^ a.|Locate the **limits.h** header file.|
|:::^ b.|Where is it?|
|:::^ c.|What was your invocation to **find**(**1**)?|
NOTE: There will be multiple **limits.h** files on the system.. use the one in the same directory as **stdlib.h**
^ 2. ^|View **limits.h** and derive me the following:|
| ^ a.|How many bits are in a **char**?|
|:::^ b.|How many unique states can this type of value have?|
|:::^ c.|What is the range of the **signed short int**egers?|
|:::^ d.|How many bits is a **short int**?|
|:::^ e.|What is the range of the **unsigned int**egers?|
|:::^ f.|How many bits is an **int**?|
|:::^ g.|And finally, how many bits in a **long long int**?|
#include
int main()
{
unsigned int a, x;
signed short int b, y;
a = 0; // zero not letter "O"
b = 0;
x = a - 1;
y = b - 1;
printf("unsigned int before: %u \t after: %u\n", a, x);
printf("signed short int before: %hd \t after: %hd\n", b, y);
return(0);
}
Be sure to check the **printf**(**3**) manual page for the proper format specifier to use for displaying particular types of variables. In the example above, we used **%u** for an unsigned integer, and **%hd** for a signed short integer.
Testing the limits:
^ 3. ^|Do the following:|
| ^ a.|Using **vi**, create a file called **dtypes.c** in your **devel/** directory and enter the above program.|
|:::^ b.|Don't forget to save!!|
|:::^ c.|Compile the program. How did you do it?|
|:::^ d.|If you get errors, attempt to fix them; you may seek clarification on the class IRC or mailing list.|
Now let's run it.
^ 4. ^|Execute your program:|
| ^ a.|What was the value of the unsigned int afterwards?|
|:::^ b.|Have you seen this value anywhere else? Where?|
|:::^ c.|And what is the value of the signed short int afterwards?|
|:::^ d.|Did you expect this? Why did you get this value?|
Time for some modifications.
^ 5. ^|Editing this program, make the following changes:|
| ^ a.|Change the line b = 0; to allow b to be equal to the maximum positive signed short int (which you found earlier)|
|:::^ b.|Change the line **y = b - 1;** to add instead of subtract|
|:::^ c.|Delete the first **printf** line and leave the second intact.|
Save, exit, and recompile **dtype.c**
^ 6. ^|After recompiling, execute the program:|
| ^ a.|What is the final result?|
|:::^ b.|Does the result make sense for the range of the data type? Why?|
|:::^ c.|Provide your modified **dtype.c** code.|
^ 7. ^|For some further experimentation:|
| ^ a.|Create a small program to play with a: **long long int**|
|:::^ b.|Have your program show me the maximum value this data type can hold.|
|:::^ c.|Show me the minimum value.|
|:::^ d.|Why might this be a useful data type?|
|:::^ e.|Extend your program to also show the same activity using an: **unsigned long long int**|
|:::^ f.|Provide this code.|
=====Conclusions=====
This assignment has activities which you should tend to. While there is no formal submission required, it would be prudent to document some of the knowledge and experience gained on your Opus.
As always, the class mailing list and class IRC channel are available for assistance, but not answers.