C Course - Data Types

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.