C basic Data Types

in #c7 years ago (edited)

C programming language has four basic data types. All other types are derived from combination of these. Those basic types are: integers, floating point values, pointers and aggregate types like structures and arrays.

Integers

Integers exists in forms of characters, short integers, integers and long integers. These contain signed and unsigned versions.
To get a better ideia, lets start explaining its most basic type, the characters. Characters, represented in the C language as the type char, have a range between 0 to 127. That means, if we assign a value beyond this range like:


char c = 129;


The compiler will not complain but you may get undesirable results, like a number different from 129. In small programs, this kind of error may be easy to spot, but in large programs, it can be really difficult sometimes to spot this type of error, since the compiler will not complain, you will have a hard time trying to figure out why you are not getting the desirable results from your code.

Now, lets take a look at what happens when we use this same datatype with its signed and unsigned version:


unsigned char c = 129;
signed char c2 = 129;


img1.jpg

It worked? kinda of. The unsigned modifier may look like increased the range, however unsigned does not allow a integer bellow 0, and signed modifier allow a negative (or positive) number, as long as it is within its range. In this case the range for the unsigned version of the char datatype is 0 to 255, and the range of the signed version, goes from -127 to 127. You can check the range of each integer type below:


=======================
Type: char, Range: 0 to 127
Type: signed char, Range: -127 to 127
Type: unsigned char, Range: 0 to 255
---------------------------------
Type: short int, Range: -32,767 to 32,767
Type: unsigned short int, Range: 0 to 65,535
---------------------------------
Type: int, Range: -32,767 to 32,767
Type: unsigned int, Range: 0 to 65,535
----------------------------------
Type: long int, Range: -2,147,483,647 to 2,147,483,647
Type: unsigned long int, Range: 0 to 4,294,967,295

========================


-Observation: note the value range of integer is implementation dependent. In this table we took as parameter a standard 16 bit system, but it can vary depending of your plataform and system. If you are using a 32 or 64 bit windows system, you most likely gonna get a int range from -2,147,483,647 to 2,147,483,647. Also note, when you do not especify if it is unsigned and signed, you gonna get a signed version of the integer datatype as default.

The function printf() again

With a little basics explained, lets return to our old function from library "stdio.h" seen in previous posts, our friend printf()!
printf() can format output according to parameters we pass to the function, for example, lets take the datatype char c = 110.


printf("printing: %d \n": c);
printf("printing: %c \n": c);


img2.jpg

The first printf() called, has printed the number 110 itself and the second printf() has printed the ASCII character represented by the number 110. You can take a look at different printf() formats right at cplusplus website: http://www.cplusplus.com/reference/cstdio/printf/

Now we can give a better format to the values we pass to our printf()!

Floating Point Values

Numbers like 3,14 cannot be stored as integer values, as the compiler will make evident to you. We must then, store fractional numbers as floating point values. These values include the types float, double and long double. On modern machines a float is 4 bytes, a double is 8, and a long double can be equivalent to a double (8 bytes), 80-bits (often padded to 12 bytes), or 16 bytes. That means we can store datatypes lower in bytes size, like char(1 byte), with no information loss. So, it also means we can store a float into a double, and a float or double into a long double.

Pointers

Pointers are variables which may contain memory adresses. Each program you write, ocuppy a memory adress on your system, and each data you declare, like a memory variable, ocuppy a memory adress on your program. With pointers, you can work directly with that memory, meaning you will have direct acess to the adress of these data, and its contents.
To declare a pointer, all you have to do is declare its type, following by a *, then the pointer's name, then you will be able to assign a value to it:


int *pointer;
pointer = 0;

Altough, you can do it in one line:


int *pointer = 0;

You just assigned the last pointer to 0, means it points to nowhere. Now lets try to assign this same pointer to a memory adress, the adress of a variable previously declared.


int x = 57;
int y = 23;
pointer = &x;
int *pointer2 = &y; 

Now, why not print what we got:


printf("pointer adress: %d\n", pointer);

Wow! That crazy number is not what lies into our variable int x, which we assigned the value 57. What is it then? Simple. Thats the memory adress the program assigned to this variable when it started running. Each time you run this program, it may assign a new memory adress to this variable.
If we would like to output on the screen the value which this memory adress contains, all we have to do is dereference our pointer:


printf("pointer value: %d\n", *pointer);

Thats right! When we declare the pointer, we assign the memory adress of the variable, and to acess this adress, we just use the pointer name, in this case, pointer, and to dereference it and get acess to its contents, all we have to do is add a * before the pointer name, like *pointer. Easy isnt?

We can now acess directly the variable int x assigned to our pointer, through the pointer itself:


*pointer += 3;
printf("pointer value: %d\n", *pointer);


Now when we print the variable x, it has changed to 57 + 3(which is 60), since we changed indirectly via pointer.


printf("int x value: %d\n", x);

img3.jpg

Pointers have a certain flexibility in the way they can be declared like in one line:


int y = 23;
int *pointer2 = &y;

Or with the * declared near the datatype or the variable name, both are valid:


int *pointer2 = &y; 
int* pointer2 = &y;

In my oppinion, i like the first one, since you may get confused into declare more than one pointer in one line, like this:


int* x, y, z;

However, in this case, only x will be a pointer, y and z will be normal integer variables.