Escolar Documentos
Profissional Documentos
Cultura Documentos
Common definitions of
integral types
Implicit
specifier(s)
specifier
(s)
Explicit
specifier
Number Range
of bits
signed char
unsigned char
char
short
unsigned short
signed char
unsigned char
char
signed short int
unsigned short int
int
signed int
16 or 32
- 231 .. 231 - 1
unsigned
unsigned int
16 or 32
0 .. 232 - 1
long
32 or 64
- 231 .. 231 - 1
unsigned long
32 or 64
0 .. 232 - 1
long long
unsigned long long
8
8
8
16
16
64
64
- 27 .. 27-1
0.. 28 - 1
- 215 .. 215 - 1
0 .. 216 - 1
- 263 .. 263 - 1
0 .. 264 - 1
Unambiguous
type
(C99 names
from stdint.h)
int8_t
uint8_t
None
int16_t
uint16_t
int16_t or
int32_t
uint16_t or
uint32_t
int32_t or
int64_t
uint32_t or
uint64_t
int64_t
uint64_t
Unambiguous types
Following definitions are already defined in stdint.h header:
typedef unsigned char
typedef
signed char
uint8_t;
int8_t;
uint32_t;
int32_t;
WARNING: When you expand #define line you get the following
WARNING
int *
ptr1, ptr2;
It defines ptr2 as integer type and not a pointer to integer as it was expected.
So, when possible, use typedef instead of #define .
-fsigned-char
-funsigned-char
Floating point types are used to store real values, or to be more precise,
to store close approximation of real values.
According to the precision of the reals we have following types:
Type
Sign
Significant
Exponent
Total bits
float
23
32
double
52
11
64
enum example
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
1
2
3
4
5
6
7
Unions
Type conversion
Use of different types of data within C programs creates a need for data
type conversions
Type conversion could be:
Implicit
Explicit
Type Promotions
Type promotion is one case of implicit type conversion, where
the compiler automatically expands the binary representation of
objects of integer or floating-point types. There are:
Integral Promotions
The narrower types are widened by following value preserving rules for
the conversion.:
Float Promotions
Arithmetic conversions
If both operands are of an integral type, integer division is used, else
real division is used. For example:
double half = 1/2;
Result: half = 0
Why ?
Arithmetic conversions
If either operand is of type long double, the other operand is converted to type long
double.
If the above condition is not met and either operand is of type double, the other
operand is converted to type double.
If the above two conditions are not met and either operand is of type float, the other
operand is converted to type float.
If the above three conditions are not met (none of the operands are of floating types),
then integral conversions are performed on the operands as follows:
(Non)Safe conversions
Non-safe conversions
Loss of value: Conversion to a type where the magnitude of the
value cannot be represented (e.g. uint32_t > 255 to uint8_t)
Loss of sign: Conversion from a signed type to an unsigned
type resulting in loss of sign (e.g. int32_t to uint32_t)
Loss of precision: Conversion from a floating point type to an
integer type with consequent loss of precision (e.g. float to
int)
Safe conversions
Conversion of an integral value to a wider type of the same
signedness (e.g. uint8_t to uint32_t)
Conversion of a floating type to a wider floating type (e.g. float
to double)
pointer to object
pointer to function
pointer to void
the null pointer
Pointer cast
The size of integral type may not be adequate to store pointer value.
Sometimes, it may be unavoidable, e.g. when addressing memory mapped
registers or other hardware specific features.
#define CPU_REG_1 (*(volatile unsigned long*)(0x81001000))
Conversions of this type may be invalid if the new pointer type requires a
stricter alignment (which will be discussed later)
uint8_t p1[4];
uint32_t *p2;
p2 = (uint32_t *)p1; /* incompatibile alignment */
Pointer converisons