Data types in C are specified or identified as the data storage format that tells the compiler or interpreter how the programmer enters the data and what type of data they enter into the program. Data types are used to define a variable before use in a program. Data types determine the size of the variable, space it occupies in storage.
C language supports a wide variety of data types to accommodate any data manipulation. The variety of data types available allows the programmer to select the type appropriate to the program’s needs and the machine. Mainly the C language supports two types of data. Type such as:
C supports different types of data which may be represented differently within computer’s memory.
Data types are divided into following three categories,
(a)Basic or Primary data types
(b)Derived data types
(c)User-defined data types
We’ll be covering the following topics in this tutorial:
Primary Data Types in C
All the C compilers support five Primary(Built-in) Data Types, namely int, char, float, double and void. They are argumented by using data type qualifiers such as short, long, signed and unsigned.
Integer Data Types in C
Integers are whole numbers without a fractional part. In C, the keyword int is used to represent integer quantity. They generally require 2 bytes of memory for their storage. It is a signed data type, i.e. it can be used to store both positive as well as negative values. The range of values that variables of this type can hold lies between -32768 to +32767. This range can be calculated by using the formula -2x-1 to +2x-1 -1 where x is the total number of bits used to store the signed integer type. Here, 1 has been subtracted as one bit is reserved for the signed bit and the remaining for the magnitude. Here we have subtracted 1 from the upper limit of the range because 0 is also included.
For example : A variable of int type requires 2 bytes (= 2 x 8 = 16 bits). Out of this, 1 bit is reserved for sign (-or+) and remaining 15 bits can contain 0 or 1. So the range of values supported will be -215 (-32768) to +215-1 (+32767).
Therefore, out of the allocated memory space for integers, the leftmost bit is reserved for the number sign. If this bit is 0, the number is positive, and if it is 1, the number is negative. However, it decreases the size of memory and hence the maximum value that can be stored in the allocated memory to half because we are losing the most significant bit.
The declaration of a variable length of int type is as follows,
int length ;
The variable length can store integers lying in the range -32768 to +32767. The conversion character used with this data type is %d . We shall use this conversion character while printing variables of type int.
Integers also differentiated into the following three categories according to their size:
(i) For variables having small integer values, the type code is short int or short.
(ii) For variables having an intermediate range of values, the type code is int.
(iii) For variables having large integer values, the type code is long int or long.
(iv) For variables having very large values, the type is long, long int, or only long long.
Qualifier | Size (Bytes in memory) | Numerical range | Conversion Character | |
Minimum | Maximum | |||
short | 1 | -128 (= -27) | +127(=27-1) | %hd |
unsigned short int | 1 | 0 | 255 | %hu |
unsigned int | 2 | 0 | 65535(=+216-1) | %u |
long | 4 | -2,147,483,648 (-231) | +2,147,483,647 (-231 -1) | %ld |
unsigned long | 4 | 0 | 4,294,967,295 (+232 -1) | %lu |
Note: The amount of memory occupied by variables of these types varies from computer to computer. The int type only provides a range of integers to be operated on. But while making programs, we may require integers beyond +32767 and integers below -32768. So to solve this problem, C provides certain qualifiers like short, long, unsigned that extends the functionality of the int type. These qualifiers are prefixed before int can be used by simply using the qualifier before the variable name in the variable declaration. The table enlists the various qualifiers that can be used with int type.
Short Data Type in C
In certain programs, you may not need integers as large as the standard int type provides. In such cases, C provides a short qualifier that can be prefixed before the int in the variable declaration. Variables of such type require 1 byte for their storage and can support values ranging from -128 (-27) to +127 (+27-1).
Generally, in a 32-bit computer system, the size of a Short (also written as short int) is 2 bytes (16 bits) are allocated for storage of short int; out of the 16 bits, the leftmost bit reserved for the sign. Therefore, only 15 bits are available for the storage of the value.
Therefore, the values of short or short int or signed short int variables may vary from -32,768 to 32,767. As mentioned above, for the positive numbers, the leftmost bit is 0; for negative numbers, the leftmost bit is 1, and the remaining bits store complement of the number plus 1.
The declaration of a variable temperature of short int type is as follows,
short int temperature ;
You can also put the qualifier short before the variable name in the variable declaration.
short temperature ;
The variable temperature can store integers lying in the range -128 to +127. The conversion character used with it is %hd.
Long Integers
In some programs, you may need very large integers. But we can specify only a small range of integers with standard int type. Therefore, C provides keyword long that extends the range of int type variables. The variables of long int requires 4-byte for their storage and therefore can store an integer value that can range from -2,147,483,648 (-231) to +2,147,483,647 (+231-1).
A variable distance of type long int can be declared as
long int distance ;
You can also put the qualifier long before the variable name in the variable declaration,
long distance ;
The variable distance can store integer lying in the range -2,147,483,648 to +2,147,483,647.
The conversion character used with such a variable is %ld.
Unsigned Integers
In some programs, you may need only non-negative integers such as the number of pages in a book, the number of players in a football team, and age, etc. C provides a keyword unsigned that can use with int, short, and long to specify positive integers. The range of such type variables lies between 0 to 2x – 1, where x is the total number of bits need to store the unsigned integer type. Here, we have subtracted 1 from the upper limit of the range because 0 included. When unsigned used in association with int type, the range will lie between 0 and 65535 (216-1).
A number in this sequence is the address of the byte. This number has to be positive. Such numbers are called unsigned numbers.
The signed numbers can be positive or negative, but unsigned numbers are always positive. Unsigned numbers are also categorized according to their size, as shown in Table.
Range of values of unsigned numbers
Type | Memory allocated | Maximum value | Range of values |
unsigned char | 1 byte | 28– 1 | 0 to 255 |
unsigned short int | 2 bytes | 216– 1 | 0 to 65535 |
unsigned int | 4 bytes | 232– 1 | o to 4294967295 |
unsigned long int | 4 bytes | 232– 1 | 0 to 4294967295 |
unsigned long long int | 8 bytes | 264– 1 | 0 to 18446744073709551615 |
We can use the entire allocated memory space for storing an unsigned number because no bit requires representing the number’s sign. Therefore, the maximum value of an unsigned number stored in a given memory space is double that of signed numbers.
Variable pages of unsigned int type can be declared as follows,
unsigned int pages;
The variable pages can store integers lying in the range 0 to 65535. The conversion character used with unsigned int is %u.
As discussed above, unsigned can also use in association with short and long. For example
unsigned short int age; unsigned long int count_of_people; unsigned short a; unsigned long b; /* b is of unsigned long int type */ unsigned x; /* x is of unsigned int type */
The age variable of unsigned short int type can store integers lying in the range 0 to 255. The conversion character used with the variable of an unsigned short int is %hu.
The variable count_of__people is of unsigned long int type and can store integers lying in the range 0 to 4,294,967,295 (232 – 1). The conversion character used with variables of this type is %lu.
The following program would clear your logic.
main() { short a,b; long x; unsigned i; unsigned long int j; .................. .................. scanf ("%hd%ld%u", &a,&x,&i); printf {"%hd%ld%u" ,a,x, i); .................. .................. scanf ("%hd%lu",&b, &j); printf ("%hd%lu",b, j); .................. }
You can find the value ranges of integer types for your C compiler in the header file limits.h, which defines macros such as INT_MIN and INT_MAX and many more. The INT_MIN determines the minimum value that an int type can store, and INT_MAX determines the maximum value that an int type can store. In addition to these macros, it also contains macros such as UINT_MAX, LONG_MAX, LONG_MIN, CHAR_MAX, CHAR_MIN. To see all of these and more, see the limits.h header file.
Now let us consider the following program.
To display the maximum and minimum range of some data types?
#include<stdio.h> #include<limits.h> main() { printf ("Minimum value of int = %d", INT_MIN); printf ("\nMaximum value of int = %d", INT_MAX); printf ("\nMaximum value of unsigned int = %u", UINT_MAX); printf("\nMinimum value of long int = %ld",LONG_MIN); printf("\nMaximum value of long int = %ld",LONG_MAX); }
Output :
Minimum value of int = -32768 Maximum value of int = 32767 Maximum value of unsigned int = 65535 Minimum value of long int = -2147483648 Maximum value of long int = 2147483647
Character Type
A variable may have value in the form of a character. The type of such variables is char. The char type represents only a single character, which may be a letter or a digit or a punctuation mark and so on. It generally takes 1 byte of memory. Characters assigned to a variable of the char types are stored using its ASCII code, an integer. For instance, character.
In C language, the characters define as integer constants according to ASCII code. This code comprises Latin alphabets from A to Z in uppercase and a to z in lowercase, digits 0 to 9, symbols such as+, -, *, etc.
According to this code, ‘A’ is represented in memory by its ASCII code equivalent, an integer 65. The char type can be either signed or unsigned. As a signed type, the value stored in a variable of type char can range from -128 to +127. In the list, the value of each character differs from that of the previous by 1. In the case of unsigned type, the value stored ranges from 0 to 255. By default, the character data type is treated as an unsigned character. The conversion character used with this data type is %c.
Some examples are,
char letter = 'B'; char digitl = '5'; char symbol = '#'; char newline = '\n';
The following program would tell how characters are accessed and declared.
main() { char ch = 'a'; printf("\nASCII code of %c is %d",ch,ch); }
Here, in the declaration statement, we have declared a variable ch of type char and assigned value a to it. In the printf() statement, we are printing its value and corresponding ASCII equivalent.
So the answer is ASCII code of a is 97.
Therefore %d is the conversion character used with characters to print the ASCII values.
The ASCII code supports only Latin alphabets and other symbols with values from 0 to 127 and can store in 1 byte of memory. Other languages did not represent by ASCII code. For defining the alphabets of major languages of the world, the International Organization for Standardization (ISO) has created a Universal Character Set (UCS) code.
It designates as ISO 10464 standard. In this code, a character allocates 4 bytes for storing its value. It is known as UCS-4. Before this standard adopts, the Unicode (also called UCS-2) allocated 2 bytes for a character was prevalent. The Unicode standard has also been modified to 4 bytes by ISO standard. The new ISO standard supports all the three, that is, ASCII, UCS-2, and UCS-4. The revised C standard supports the ISO standard.
Floating Point Numbers
The integer types do not provide the facility to represent decimal numbers so whenever you define a number with a decimal such as 3.142, use a floating-point data type. If you try to use an integer type to store a number with a fractional part, the fractional part will discard. C provides two standard floating-point types: float and double to store numbers with fractional parts. These give you a choice in the number of digits precision available to represent your values in the range of values that can accommodate.
Float: The float data type requires 4-bytes (32-bits) for their storage. Consider that the number 52.5 is to be stored. In a binary number system, it writes as 110100.1. The number store as .1101001 x 26. On a 32-bit system, the number 1101001 is stored on the 23-bit segment of the 32 bits, while the power 6 or 110 in binary floated, that is, it is stored separately on the 8-bit segment of the remaining 9 bits. The leftmost bit (32nd bit) is kept for the sign (+ or -).
For positive numbers, this bit takes the value 0, and for negative numbers, this bit has value 1. The scientific notation for floating-point numbers is the exponential notation. The number 7685.43 may write as 7.68543 x 103. In C language, the scientific notation of the number 7685.43 may express as 7.68543 e+3 or 7.68543 E+3.
The data types for floating-point numbers are float, double, and long double. The distinction between float and double is according to the precision, that is, the number of digits after the decimal point. On most 32-bit systems, a float has 7 significant digits and allocate 4 bytes of memory, whereas a double has 15 significant digits, nearly double the precision of float. It may get 8, 10, 12, or 16 bytes for storage on some systems. The memory spaces generally allocate for a float, double, and long double given in Table.
Memory allocated for floating point numbers
Type | Memory allocated | Range of values that may be stored |
float | 4 | ± (3.4 e-38 to 3.4 e+38) |
double | 8 | ± (1.7 e-308 to 1.7 e+308) |
long double | 10 | ± (3.4 e-4932 to 1.1 e+4932 |
A variable average of float data type can be declared as follows,
float average;
The conversion character used with this data type is %f usually. To represent the result in exponential form, the conversion character %e used.
Double: In certain situations, like meteorology, we need to work with large decimal numbers that require a high degree of accuracy. The float type is inappropriate in such cases. Here, we use the double data type. The double data type uses 8 bytes (64 bits) for their storage. Their digits of precision are 15, and their range lies between 1. 7E-308 to +1.7E308.
A variable sunDistance of double type can be declared as follows,
double sunDistance;
The conversion characters used with double type are %lf,%le,%lg.
The only qualifier that can use with double type is long. A variable of long double type requires 10 bytes of memory. For example :
long double a,b;
The conversion characters that can use with this data type is %Le,%Lfand %Lg.
void TYPE
The void type designated by the keyword void; does not have any values or operations. It is primarily used to indicate that.
• A function does not return a value. For instance, void factorial (int n);
• The function does not have any parameters. For example, int date (void) ;
• A generic type, which means that it can represent any of the standard types.
Now let us consider the following program,
#include<stdio.h> void func_hello(void); /*function prototype*/ main() { func_hello(); /*function call*/ } void func hello(} /*function definition*/ { printf ("Hello Everbody"); }
Here, void written before the function name func_hello indicates that this function does not return anything. The void written in parentheses indicates that this function accepts no arguments.
C also supports the pointer to void type ( specified as void ). A program can convert a pointer to any type of data to a pointer to void and back to the original type without losing information.
Derived Data Types
A derived type formed by using the basic types in combination. Array, function and pointers are the derived types. Here, we are discussing them briefly.
Array
An array is a collection of elements of the same data type. It used to handle a large amount of data, without the need to declare many individual variables separately. The array elements stored in contiguous memory locations (i.e. one after the other). All the array elements must either any primary data type like int, float, char, double etc., or they can be any user-defined data type like structure and unions.
To declare an array, you need to specify the type of the array elements and number of elements.
The syntax is
data_type arrayname{size];
For example, to declare an array a containing 5 elements of type int, you need to write.
To access a particular element of an array, you need to specify the array name followed by the position number of the elements enclosed in square brackets. This position number is formally called index number or subscript. Array elements always numbered starting from 0, so the array elements of an array of length n indexed from 0 to n – 1. For example, If a is an array with five elements, then they are designated by a[0], a[1]. a[2], a[3], a[4] and a[5].
An array can be one dimensional or multidimensional depending upon the subscript used.
Functions
A function is a self-contained block of statements that performs a specific task. It allows us to avoid duplicating code that used more than once. Using functions, in the extensive program, can divide into smaller self-contained parts that are easier for us and others to understand, modify and maintain.
Functions can divided into two categories: library functions (in-built functions) and user-defined functions.
Library functions are predefined and precompiled functions that designed to perform some specific tasks. For example, scanf (), printf (), sqrt (), pow(), strlen () etc.
User-defined functions are the functions which are explicitly defined by the user to meet his requirements. A user-defined function generally created when a user may require to perform some specific task repeatedly, and there is no library function available for performing this task.
Every function in C consists of following components function definition (part of the function where actual code is defined), function prototype (specifies the name of the function, number and type of parameters (if any) and its return type), function call (It used to invoke the function by specifying the function name followed by a list of arguments separating the function name followed by a list of arguments separated by commas enclosed in pair of parentheses).
Pointer
A pointer is a variable that contains the address of the data items such as variable or function or array rather than a value. It is a derived data type as it built from one of the basic types available in C. Pointers frequently used in C because of
• providing efficient techniques for manipulating data in arrays.
• returning multiple values from a function.
• supporting the dynamic allocation of memory.
• manipulating dynamic data structures such as linked list, trees, graphs etc.
A pointer variable declared in the same way as that of normal variable except that an asterisk must precede the name of the pointer variable (*). The syntax is
data_type *ptr_var_name For example int *ptr;
Here, ptr is a pointer variable. Which stores the address of any variable having data type int.
Once the pointer variable is declared, we can initialize the pointer variable by assigning the address of some other variable by using the address of operator (&). For example :
int i = 5; int *ptr = &i;
A pointer variable can also use to indirectly access the value of the variable whose address stored in it. It is using the dereference operator (*).
User-Defined Types
As the name suggests, these data types are created by users using one or more basic types in combination, and other derived and user-defined types.
Structure, union, enum type definitions help to define user-defined types.
Structure
A structure is a collection of related data items which can be of different types, having a single UNIT name. The data items enclosed within a structure are known as its members. Defining structure is a two-step process: First, you define a template or a blueprint that describes the new type, and then you declare 3 variables of this new type.
The syntax is | For example, |
struct struct_name { datatypel-member1; datatypel-member2; ……….. datatypel-membern; } | struct employee { char name[25]; int empid; double salary; } |
Once the structure has defined, its members can be accessed using a dot operator ( . ). For example, e1.empid represents the empid of e1.
Union
Unions consist of one or more members which may be of different data types just like structures. However, unlike structures where each member is assigned a unique storage area, in the union, all the members share the same storage area within the computer’s memory. In union, the compiler allocates only sufficient storage space for the largest of the members in a union, and other members use the same storage area. The syntax is
The syntax is | For example, |
union tagname { datatypel-member1; datatypel-member2; ……….. datatypel-membern; } | union item { int a; float b; char c; } |
After declaring a union, you can define union variables, so to define a variable of item type, write
union item t;
Although the union contains many members of different types, it can handle only one member at a time. To access a union member, again use the dot operator (.), as we have done while discussing structure.
Enumerated Data Types
C provides a special kind of user-defined data type known as enumerated type explicitly designed for variables that can take a small set of possible values. The programmer lists the values that a variable of enumerated data type can take.
Now let us consider a statement,
enum day_of_week {sun,mon,tue,wed,thu,fri,sat};
The enum keyword used here indicates that we are talking about enumerated type. It is followed by identifier day_of_week which is a tag by which enumerated type will know. It followed by a possible set of values separated by commas, enclosed in curly braces. These set of values are called enumerators of enumeration constants.
Once the enumeration type is defined, the variables of this type can be defined as follows,
day_of_week day1,day2;
Now the variables day1, day2 which are of type day_of_week can be assigned any one of the possible set of values.