A data object is a region of storage that contains
a value or group of values. Each value can be accessed using its identifier
or a more complex expression that refers to the object. In addition,
each object has a unique data type. The data type of an object
determines the storage allocation for that object and the interpretation
of the values during subsequent access. It is also used in any type
checking operations. Both the identifier and data type of an object
are established in the object declaration.
Data
types are often grouped into type categories that overlap, such as:
- Fundamental types versus derived types
- Fundamental data types are also known as "basic", "fundamental"
or "built-in" to the language. These include integers, floating-point
numbers, and characters. Derived types are created from the
set of basic types, and include arrays, pointers, structures, unions,
enumerations, and vectors.
- Built-in types versus user-defined types
- Built-in data types include all of the fundamental types,
plus types that refer to the addresses of basic types, such as arrays
and pointers. User-defined types are created by the user from
the set of basic types, in typedef, structure, union,
and enumeration definitions.
- Scalar types versus aggregate types
- Scalar types represent a single data value, while aggregate types
represent multiple values, of the same type or of different types.
Scalars include the arithmetic types and pointers. Aggregate types
include arrays, structures, and vectors.
The following matrix lists the supported data types
and their classification into fundamental, derived, scalar, and aggregate
types.
Table 1. C data
types| Data object |
Basic |
Derived |
Built-
in
|
User-
defined
|
Scalar |
Aggregate |
| integer types |
+ |
|
+ |
|
+ |
|
| floating-point types1 |
+ |
|
+ |
|
+ |
|
| character types |
|
|
+ |
|
+ |
|
| Booleans |
+ |
|
+ |
|
+ |
|
| void type |
+2 |
|
+ |
|
+ |
|
| pointers |
|
+ |
+ |
|
+ |
|
| arrays |
|
+ |
+ |
|
|
+ |
| structures |
|
+ |
|
+ |
|
+ |
| unions |
|
+ |
|
+ |
|
|
| enumerations |
|
+ |
|
+ |
see note3 |
|
vector types |
|
|
+ |
|
|
+ |
Note: - Although complex floating-point
types are represented internally as an array of two elements, they
behave in the same way as real floating-pointing types in terms of
alignment and arithmetic operations, and can therefore be considered
scalar types.
- The void type is really an incomplete type, as
discussed in Incomplete types.
- The C standard does not classify enumerations as
either scalar or aggregate.
Incomplete types
The following
are incomplete types:
- The void type
- Arrays of unknown size
- Arrays of elements that are of incomplete type
- Structure, union, or enumerations that have no definition
However, if an array size is specified by [*],
indicating a variable length array, the size is considered as having
been specified, and the array type is then considered a complete type.
For more information, see Variable length arrays.
The
following examples illustrate incomplete types:
void *incomplete_ptr;
struct dimension linear; /* no previous definition of dimension */
Compatible and composite types
In C, compatible types are defined as:
- two types that can be used together without modification (as in
an assignment expression)
- two types that can be substituted one for the other without modification
A composite type is constructed
from two compatible types. Determining the resultant composite
type for two compatible types is similar to following the usual binary
conversions of integral types when they are combined with some arithmetic
operators.
Obviously, two types that are identical are compatible;
their composite type is the same type. Less obvious are the rules
governing type compatibility of non-identical types, user-defined
types, type-qualified types, and so on. Type specifiers discusses
compatibility for basic and user-defined types in C.