Table of Contents

What is a data type in C?

The C Programming language provides a standard and minimal set of basic data types. Sometimes these are called primitive data types. More complex data structures can be built up from these basic data types. Data types specify how we enter data into our C programs and what type of data we use for different operations. C language has some predefined set of data types to handle various kinds of data that we can use in our program.

1) Integer Data Types

The “integral” types in C form a family of integer types i.e. whole numbers without a fractional component such as int, short int, long int, long long int. They all behave like integers and can be mixed together and used in similar ways. The differences are due to the different number of bits used to implement each type.

int or integer data type

Integer or int is the default data type in C. It is at least 16 bits, with 32 bits being typical. If you do not really care about the range for an integer variable, declare it int since that is likely to be an appropriate size (16 or 32 bit) which works well for that machine.

short data type

short Small integer — at least 16 bits which provides a signed range of -32768 to 32767. This data type is not commonly used however it is used in situation where memory is an issue, for example in embedded system.

long or large integer data type

Large integer — at least 32 bits. Typical size is 32 bits which gives a signed range of about -2 billion ..+2 billion. Some C and C++ Compilers support “long long” for 64 bit ints so it may have a range of -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807.

The integer types can be preceded by the qualifier unsigned which disallows representing negative numbers, but doubles the largest positive number re-presentable. For example, a 16 bit implementation of short can store numbers in the range -32768..32767, while unsigned short can store 0..65535. You can think of pointers as being a form of unsigned long on a machine with 4 byte pointers.

In my opinion, it is best to avoid using unsigned unless you really need to. It tends to cause more misunderstandings and problems than it is worth.

2) Character Data Types

char data type

The char data type is used to store single ASCII character. This data type is always a byte which is 8 bits which is enough to store a single ASCII character. It provides a signed range of -128..127 or an unsigned range is 0..255.

The char data type is also used to represent strings in C, which are sequences of characters. In this context, an array of char variables is used, with the last character being a null terminator \0 to indicate the end of the string. For example:

3) Pointer Data Type

In C and C++, a pointer is a data type that stores the memory address of another variable. Pointers allow you to manipulate memory directly. A pointer variable is declared by placing an asterisk * before the variable name i.e. int *, char *, double *, etc. For example you can declare a pointer as below:

4) Floating point Data Types

In C, a floating-point number is a data type used to represent real numbers, i.e., numbers with a fractional component. We use two data types to represent floating point number i.e. float and double. Single precision floating point number typical size 32 bits double Double precision floating point number typical size: 64 bits long double Possibly even bigger floating point number Constants in the source code such as 3.14 default to type double unless the are suffixed with an ‘f’ (float) or ‘l’ (long double).

Most C programs use double for their computations. The main reason to use float is to save memory if many numbers need to be stored. The main thing to remember about floating point numbers is that they are inexact. For example, what is the value of the following double expression?

The sum may or may not be 1.0 exactly, and it may vary from one type of machine to another.

You should never compare floating numbers to each other for equality (==) — use inequality (<) comparisons instead. Realize that a correct C program run on different computers may produce slightly different outputs in the rightmost digits of its floating point computations.

5) Composite Data Types

A composite data type in C is a data type that groups together multiple variables of different data types into a single unit. The individual variables in a composite data type are known as elements or members.

Composite data types allow you to represent more complex data structures in your program and make it easier to manage and manipulate related data. Examples of composite data types in C include arrays, structures (struct), and unions (union) and enumeration (enum).

6) Boolean Data Type in C?

The C programming language does not have a distinct boolean data type, use int or char data type instead. The language treats integer 0 as false and all non-zero values as true. So the following statement will execute until the variable i takes on the value 10 at which time the expression (i – 10) will become false (i.e. 0).


A constant is a value that cannot be changed once it has been assigned. You can declare constants by using the const keyword. Constants are typically used to provide a fixed value that is used throughout a program, such as the value of pi or the maximum size of an array.

char Constants

A char constant is written with single quotes (‘) like ‘A’ or ‘z’. The char constant ‘A’ is really just a synonym for the ordinary integer value 65 which is the ASCII value for uppercase ‘A’. There are special case char constants, such as ‘\t’ for tab, for characters which are not convenient to type on a keyboard.

‘A’ uppercase ‘A’ character
‘\n’ newline character
‘\t’ tab character
‘\0’ the “null” character — integer value 0 (different from the char digit ‘0’)
‘\012’ the character with value 12 in octal, which is decimal 10

int Constants

Numbers in the source code such as 234 default to type int. They may be followed by an ‘L’ (upper or lower case) to designate that the constant should be a long such as 42L. An integer constant can be written with a leading 0x to indicate that it is expressed in hexadecimal — 0x10 is way of expressing the number 16. Similarly, a constant may be written in octal by preceding it with “0” — 012 is a way of expressing the number 10.

Portability Problems

Instead of defining the exact sizes of the integer types, C defines lower bounds. This makes it easier to implement C compilers on a wide range of hardware. In particular, if you are designing a function that will be implemented on several different machines, it is a good idea to use typedefs to set up types like Int32 for 32 bit int and Int16 for 16 bit int. That way you can prototype a function foo(Int32) and be confident that the typedefs for each machine will be set so that the function really takes exactly a 32 bit int. That way the code will behave the same on all the different machines.

Data Type Conversion


In C, data type promotion refers to the automatic conversion of a lower precision data type to a higher precision data type. This conversion is performed by the compiler to ensure that the result of an expression is stored in the most appropriate data type.

For example, consider the following code:

Here, a is an int variable, and b is a float variable. When the expression a + b is evaluated, a is automatically promoted to a float so that it can be added to b. The result of the expression is a double, which is stored in c.


The opposite of promotion, truncation moves a value from a higher precision data type to a smaller type. In that case, the compiler just drops the extra bits. It may or may not generate a compile time warning of the loss of information. Assigning from an integer to a smaller integer (e.g.. long to int, or int to char) drops the most significant bits. Assigning from a floating point type to an integer drops the fractional part of the number.

The assignment will drop the upper bits of the int 321. The lower 8 bits of the number 321 represents the number 65 (321 – 256). So the value of ch will be (char)65 which happens to be ‘A’.

The assignment of a floating point type to an integer type will drop the fractional part of the number. The following code will set i to the value 3. This happens when assigning a floating point number to an integer or passing a floating point number to a function which takes an integer.

What are Operators in C?

In C, operators are symbols or keywords used to perform operations on values and variables. We can use operators to perform a wide range of tasks, including arithmetic calculations, logical operations, and comparisons.

1) Assignment Operators ( =, +=, -=, *=, /=, %= )

The assignment operator is the single equals sign (=).

The assignment operator copies the value from its right hand side to the variable on its left hand side. The assignment also acts as an expression which returns the newly assigned value. Some programmers will use that feature to write things like the following.

Other Assignment Operators (>>=, <<=, &=, |= and ^=)

In addition to the plain = operator, C includes many shorthand operators which represents variations on the basic =. For example “+=” adds the right hand side to the left hand side. x = x + 10; can be reduced to x += 10;. This is most useful if x is a long expression such as the following, and in some cases it may run a little faster.

Here’s the list of assignment shorthand operators…

2) Arithmetic Operators (+, -, /, * and %)

C includes the usual binary and unary arithmetic operators. These are used to perform basic arithmetic operations such as addition (+), subtraction (-), multiplication (*), division (/), and remainder after division (%) modulo division.

Personally, I just use parenthesis liberally to avoid any bugs due to a misunderstanding of precedence. The operators are sensitive to the type of the operands. So division (/) with two integer arguments will do integer division. If either argument is a float, it does floating point division. So (6/4) evaluates to 1 while (6/4.0) evaluates to 1.5 — the 6 is promoted to 6.0 before the division.

3) Unary Increment or Decrement Operators (++ and –)

The unary ++ and — operators increment or decrements the value in a variable. There are “pre” and “post” variants for both operators which do slightly different things (explained below)

4) Relational or Comparison Operators (==, !=, >, <, >= and <=)

These operate on integer or floating point values and return a 0 or 1 boolean value to show the comparisons between two operands.

Using both assignment (=) and comparison (==) operators together

An absolutely classic pitfall is to write assignment (=) when you mean comparison (==). This would not be such a problem, except the incorrect assignment version compiles fine because the compiler assumes you mean to use the value returned by the assignment. This is rarely what you want

This does not test if x is 3. This sets x to the value 3, and then returns the 3 to the if for testing. 3 is not 0, so it counts as “true” every time. This is probably the single most common error made by beginning C programmers.

The problem is that the compiler is no help — it thinks both forms are fine, so the only defense is extreme vigilance when coding.

5) Logical Operators ( !, && and ||)

In Logical operators in C, the value 0 is false, anything else is true. The operators evaluate left to right and stop as soon as the truth or falsity of the expression can be deduced. (Such operators are called “short circuiting”) In ANSI C, these are furthermore guaranteed to use 1 to represent true, and not just some random non-zero bit pattern.

6) Bit-wise Operators (~, &, |, ^, >> and <<)

C includes operators to manipulate memory at the bit level. This is useful for writing low level hardware or operating system code where the ordinary abstractions of numbers, characters, pointers, etc… are insufficient — an increasingly rare need. Bit manipulation code tends to be less “portable”. Code is “portable” if with no programmer intervention it compiles and runs correctly on different types of computers. The bit-wise operations are typically used with unsigned types. In particular, the shift operations are guaranteed to shift 0 bits into the newly vacated positions when used on unsigned values.

Do not confuse the Bit-wise operators with the logical operators. The bit-wise connectives are one character wide (&, |) while the Boolean connectives are two characters wide (&&, ||). The bit-wise operators have higher precedence than the Boolean operators. The compiler will never help you out with a type error if you use & when you meant &&. As far as the type checker is concerned, they are identical– they both take and produce integers since there is no distinct Boolean type.

7) Pointer Operators (*, & and ->)

In C, pointer operators are operators that are used in conjunction with pointers. There are several pointer operators in C, including:

  1. Address-of operator (&): Returns the memory address of a variable. When used with a variable, the & operator returns the address of the variable in memory.
  2. Dereference operator (*): Accesses the value stored at a memory address. When used with a pointer, the * operator returns the value stored at the address pointed to by the pointer.
  3. Indirection operator (->): Accesses a member of a structure through a pointer. The -> operator is used to access members of a structure when a pointer to the structure is used.

8) Conditional Operators (? :)

The conditional operator (also known as the ternary operator ) is a shorthand way of writing an if statement. It allows you to conditionally execute an expression based on the value of a condition. The syntax of the ternary operator is as follows:

Operators Diagram (Infographics)

The following diagram shows list of operator categories and operators used in C.

C/C++ Operators
C/C++ Operators

If you want to see these operators in action, look at the following C Programs: