C Data Types

The basic C data 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 C data types

Advertise on this site. I promise you will like the rates :)

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:

  • char
  • int
  • float
  • double
  • void
  • _Bool (C99)

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 null terminated character arrays.

Using printf for output

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);

  • "The number is %d" is the format string
  • %d is a format specifier
  • 5 is an argument

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.

All examples that you see below are available on Git Hub. I encourage you to download the source code, run it yourself and make changes to see how it works.

char

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 value.
To print a char value with the printf function, you will use the %c specifier. Here is how we print different symbols:

1
2
3
printf("%c", 'a');
printf("%c", '1');
printf("%c", ';');

And here is how we do the same with only one call of printf:

    pritnf("%c%c%c", 'a', '1', ';');

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:

    printf("%c, %c, %c", 65, 32, 66);

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:

    printf("%c %c %c", 'a', 'a'+1, 'a'+2);

int

The int C data type stands for “an integer number”. Using ints is straight forward. We print an int with the %d specifier:

pritnf("%d", 5);
printf("%d", 5+6);

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:

printf("%d", 'A');
printf("%d", 'Z');
printf("%d", 'a');

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.

float

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:

    printf("%f", 9.95f);

Notice that the float value end with an 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:

    printf("%.2f", 9.95f);

If you try to save a number with long precision, data will be lost. The following line:

    printf("%f", 9.9876543210f);

will output something like: 9.987655

For better precision we have the next type - double.

double

The data type 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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
void doubleDemo()
{
    printf("Double doesn't overflow with the same value, but printf doesn't show it all: ");
    printf("%lf", 9.9876543210d);
    printf("\n\n");
    printf("Printing a double with higher precision: ");
    printf("%.10lf", 9.9876543210d);
    printf("\n\n");
    printf("Using double by default(no 'd' specificator: ");
    printf("%lf", 9.9876543210);
    printf("\n============================\n");
}

Here is the demo for the entire C data types lesson. And this is how its output looks like:

void

void is not really a data type. void means no data type. We use the void keyword in several contexts:

  • for functions that don't return result
  • for functions that don't accept parameters
  • for void pointers

We will talk about these topics later.

_Bool

The C99 standard added _Bool to the the C data types. Before that 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.
_Bool  can hold the two boolean values 0 and 1. For more convenience, the standard adds the header <stdbool.h>. It contains the macros

  • bool - Macro for the keyword _Bool. Before C99, all primitive C data types used keywords in lowercase only. The new keywords like _Bool, are defined different, to avoid problems with existing code.
  • true - represents the "true" boolean value, using the constant 1
  • false - represents the "false" boolean value, using the constant 0

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. 

Size and sign modifiers

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.

Previous: C Language Program

Next: Variables

   Search this site: