Upload
karmamen
View
229
Download
0
Embed Size (px)
Citation preview
8/9/2019 C Course - Data Types
1/21
Data Types
8/9/2019 C Course - Data Types
2/21
Common definitions ofintegral types
ImplicitImplicitspecifierspecifier(s)(s)
ExplicitExplicitspecifierspecifier
NumberNumberof bitsof bits RangeRange
UnambiguousUnambiguoustypetype(C99 names(C99 namesfrom stdint.h)from stdint.h)
signed char signed char 8 - 27 .. 27-1 int8_t
unsigned char unsigned char 8 0.. 28 - 1 uint8_t
char char 8 None
short signed short int 16 - 215 .. 215 - 1 int16_t
unsigned short unsigned short int 16 0 .. 216 - 1 uint16_t
int signed int 16 or 32 - 231 .. 231 - 1 int16_t orint32_t
unsigned unsigned int 16 or 32 0 .. 232 - 1 uint16_t oruint32_t
long signed long int 32 or 64 - 231 .. 231 - 1 int32_t orint64_t
unsigned long unsigned long int 32 or 64 0 .. 232 - 1 uint32_t oruint64_t
long long signed long long int 64 - 263 .. 263 - 1 int64_t
unsigned long long unsigned long long int 64 0 .. 264 - 1 uint64_t
8/9/2019 C Course - Data Types
3/21
Unambiguous types
Following definitions are already defined in stdint.h header:
typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned short uint16_t;
typedef signed short int16_t;
typedef unsigned long uint32_t;
typedef signed long int32_t;
They should be used in place of the basic types.
8/9/2019 C Course - Data Types
4/21
typedef vs. #defineIn order to define new, unambiguous types #define or typedef can be used
#define INT_PTR int*
typedef int *int_ptr;
When used, it looks like following
INT_PTR ptr1, ptr2;
int_ptr ptr3, ptr4;
WARNINGWARNING: When you expand #define line you get the following
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 .
8/9/2019 C Course - Data Types
5/21
Does your compiler defaultsto signed or unsigned char?
The C and C++ standards allows the
character type char to be signed or unsigned,depending on the platform and compiler.
x86 GNU/Linux and Microsoft Windows, use
PowerPC and ARM processors typically useunsigned char
This can lead to unexpected results whenporting programs between platforms whichhave different defaults for the type of char.
8/9/2019 C Course - Data Types
6/21
Signed or unsigned char ?
char c = 255;
if (c > 128)
{
printf ("char is unsigned (c = %d)\n", c);}
else
{
printf ("char is signed (c = %d)\n", c);}
return 0;
8/9/2019 C Course - Data Types
7/21
How to deal with existingcode?
For existing programs which assume that char is
signed or unsigned, GCC provides the options: -fsigned-char
-funsigned-char
.
Using these options, previous example codecompiles cleanly when char is unsigned:
$ gcc –o signed -Wall -funsigned-char signed.c
$ ./signed
char is unsigned (c = 255)
8/9/2019 C Course - Data Types
8/21
How to deal with existingcode?
When compiling with the -fsigned-char the value
255 wraps around to -1, and should give warning:
$ gcc –o signed -Wall -fsigned-char signed.c
signed.c: In function `main':
signed.c:7: warning: comparison is always false due tolimited range of data type
$ ./signed
char is signed (c = -1)
The warning message is one symptom of code whichassumes a definition of char which is different from theactual type.
8/9/2019 C Course - Data Types
9/21
8/9/2019 C Course - Data Types
10/21
enum example Represent values across a series of
named constants
The first constant is assigned valuezero if value is not explicitly assigned
enum Days
{
Sunda = 1
#defines are often used to create aseries of named constants
#define Sunday 1
#define Monday 2
#define Tuesday 3
#define Wednesday 4
Monday,Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
};
Each subsequent value is incrementedby one over the previous constant.
#define Thursday 5
#define Friday 6
#define Saturday 7
8/9/2019 C Course - Data Types
11/21
What is the enum’s size ?
The compiler is free to choose the actual type
used based on the enumeration constantsdefined, so: it can choose a smaller type if it can represent the
.
if you need enumeration constants that don't fitinto an int you will need to use compiler-specificextensions to do so.
An enum is only guaranteed to be largeenough to hold int values if needed
8/9/2019 C Course - Data Types
12/21
Unions A union is a structured type that aggregates a fixed set of labeled
objects (members), possibly of different types, into a singleobject.
Difference to the struct is that in union each data member beginsat the same location in memory.
'
member.typedef union _my_union
{
unsigned int d1;
unsigned short d2;unsigned char d3[3];
}my_union;
8/9/2019 C Course - Data Types
13/21
Type conversion Use of different types of data within C programs creates a need for data
type conversions
Type conversion could be: Implicit
Assignment – automatic conversion when assigning value of variable of onetype to a variable of different type, e.g. assigning value of int variable to a
Function call – automatic conversion of function arguments, e.g. chars areautomatically converted to ints (if arguments are defined as ints).
Returned values – automatic conversion of function return value, e.g. if afunction was declared to return a double and the return statement has aninteger expression, the integer value is automatically converted to a double.
Arithmetic conversions – While preparing arithmetic or logical operations
and if two operands are not of the same type, the compiler may convert one orboth to a common type before the operation is performed.
Explicit
Typecasting – when you explicitly force a conversion from one type toanother using a cast operation.
8/9/2019 C Course - Data Types
14/21
Type PromotionsType promotion is one case of implicit type conversion, wherethe 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 forthe conversion.:
(unsigned) char and (unsigned) short are widened to an int
all other arithmetic types are unchanged by the integral promotion
Wherever an int or an unsigned int may be used in anexpression, an instance of the narrower integral type (char,
short) may also be used.
Float Promotions
Type float is promoted to double
8/9/2019 C Course - Data Types
15/21
Arithmetic conversionsIf both operands are of an integral type, integer division is used, elsereal division is used. For example:
double half = 1/2;
Result: half = 0 Why ?
Because 1 and 2 are integer constants.To fix this, change at least one of them to a real constant.
double half = 1.0/2;
Also, if both operands are integer variables and real division is desired, castone of the variables to double (or float).
int x = 5, y = 2;
double d = ((double) x)/y;
8/9/2019 C Course - Data Types
16/21
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 otheroperand is converted to type double.
If the above two conditions are not met and either operand is of type float, the otheroperand 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:
If either operand is of type unsigned long, the other operand is converted totype unsigned long.
If the above condition is not met and either operand is of type long and the other oftype unsigned int, both operands are converted to type unsigned long.
If the above two conditions are not met, and either operand is of type long, the otheroperand is converted to type long.
If the above three conditions are not met, and either operand is of type unsigned int,the other operand is converted to type unsigned int.
If none of the above conditions are met, both operands are converted to type int.
8/9/2019 C Course - Data Types
17/21
(Non)Safe conversions Non-safe conversions
Loss of value: Conversion to a type where the magnitude of thevalue cannot be represented (e.g. uint32_t > 255 to uint8_t)
Loss of sign: Conversion from a signed type to an unsignedtype resulting in loss of sign (e.g. int32_t to uint32_t)
integer type with consequent loss of precision (e.g.float toint)
Safe conversions
Conversion of an integral value to a wider type of the samesignedness (e.g. uint8_t to uint32_t)
Conversion of a floating type to a wider floating type (e.g.floatto double)
8/9/2019 C Course - Data Types
18/21
What to avoid to be safe ?
Avoid implicit conversions: between signed and unsigned types between integer and floating types
of function arguments of function return expressions
8/9/2019 C Course - Data Types
19/21
Pointer type conversions
Pointers can be classified as:
pointer to object pointer to function
pointer to void
8/9/2019 C Course - Data Types
20/21
Pointer cast A cast should not be performed
between a pointer type and an integral type.
The size of integral type may not be adequate to store pointer value.
Sometimes, it may be unavoidable, e.g. when addressing memory mappedregisters 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 astricter alignment (which will be discussed later)uint8_t p1[4];
uint32_t *p2;
p2 = (uint32_t *)p1; /* incompatibile alignment */
A cast shall not be performed if removes any const or volatilequalification.
8/9/2019 C Course - Data Types
21/21
Pointer converisons Valid conversions are following:
A pointer to void to a pointer to an object of any type and vice versa.
constant 0 to pointer (the only integer that can be safely converted to ptr)
A null pointer to a particular pointer type is converted automatically in thecase of assignment or comparison
Invalid conversions are following without an explicit cast - pointer to an object of any type to a pointer to an
object of a different type
without an explicit cast - a pointer to a function of one type to a pointer toa function of a different type
even with an explicit cast - a function pointer to an object pointer or apointer to void, or vice-versa.