C has a very compact set of data types. The basic types can represent integers, symbols and floating point numbers. The integers are a big deal in C. We use them to represent numbers, symbols and truth values. It just depends on how we interpret them. We will talk about this a little later.
Primitive types are those that are build in the language itself. Usually each of them has a reserved keyword in the language. The primitives in C are:
Originally, C didn't have a boolean data type. Instead it used 0 for "false" and any non-zero value for "true". ISO C99 introduced the new _Bool data type.
C has no string type. Instead it uses character arrays for strings.
In the next examples, we will use the printf function to output values of the different C data types. Here is an example that I will use for the explanation:
printf("The number is %d", 5);
printf uses a format string and arguments. The format string is a sequence of characters, enclosed in quotes. This string will be printed in the output.
The format string could contain special sequences, called format specifiers. The specifiers begin with the symbol “%”. They are not printed literally. Instead, the value of the corresponding argument will be output in its place.
The arguments are values that are placed after the format string. The arguments are separated by commas. Their number must be equal to the number of specifiers in the format string.
The “char” keyword is short for character. This is the type that we use to save a single symbol. The symbols are saved as numbers, according to the ASCII table. We call these numbers “ASCII code”.
The codes range from 0 to 255, although only the first 128 (code 0..127) characters are standardized by ASCII. To save these 256 values(0..255) we need only 1 byte. Therefore the char data type in C takes 1 byte of space.
In the source code, you need to put the char values between apostrophes: 'a', 'b', 'c', '1', '2' etc.
This way, the compiler will recognize those symbols as char values.
To print a char value with the printf function, you will use the %c specifier. Here is how we print different symbols:
And here is how we do the same with only one call of printf:
C data types are very flexible. We can use one type and tell the compiler to interpret it like another. For instance, we can treat a number like a character:
In the example above, we print the chars that have code 65, 32 and 66. The output of that command is “A B”. In fact, the compiler doesn't care if we write 65 or 'A' in our code – this is the same value.
Because characters are just numbers for the computer, we can perform arithmetic operations with them. It is called “character arithmetic”. We can add, subtract, compare them etc.
Here is one example:
The int C data type stands for “an integer number”. Using ints is straight forward. We print an int with the %d specifier:
Just like we can interpret number as a char, we can interpret char as a number. For instance, the following will output the numeric codes of the symbols:
In C, the size of int is not fixed. It depends on the implementation and the machine. For decades, the int size matched the machine word size. For 16 bit architectures the int was 16 bits(2 bytes), for 32 bit machines 32b (4B). Today it is common for 64 bit machines the size of the int data type to stay 32 bits. At this early stage, this is not a thing that will bother you, but it is good to be aware of that.
The float keyword is short for floating point number. This type represents the fractional numbers like prices, transfer amount etc. Its size is 4 bytes. Here is how we can output float values:
Notice that the float value end with f. If you omit the f, the fraction value will be read as double.
If you run the above example, you will notice that some trailing zeros are printed. You can specify the printing precision, by adding a point and a precision number between the % and the f:
If you try to save a number with long precision, data will be lost. The following line:
will output something like: 9.987655
For better precision we have the next type - double.
Double is just like float, except that it uses 8 bytes to save the data. This allows it to store much bigger values with better precision. Double values end with a 'd', but since by default all fractional values are interpreted as double, the d suffix is rarely used.
To print a double value, use the %lf specifier. With or without the 'd' suffix, these two lines will give the same output
Void is not really a data type. “void” means no data type. We use the void keyword in several contexts:
We will talk about these topics later.
Before C99, C didn't have a boolean type. It used numeric variables to save the values. The standard was that any non-zero value is "true" and the values zero and '\0' (null) were false.
Introduced in ISO C99, the boolean data type can hold the two boolean values 0 and 1. For more convenience, the standard adds the header <stdbool.h>. It contans the macros
If you are writing C99 compatible code, you should include the <stdbool.h> header when you are working with logic. Use the macros bool, true, false to maintain a good coding style.
The int and char types could be signed or unsigned. By default all integer types are signed. Signed types can represent positive and negative numbers. Unsigned types can represent only positive numbers, but they have twice as wide range.
In addition, int could be short or long, which is again affecting its size and range.
We will get back to the topic in the next lesson, when we create and use variables.