Overview of the C Programming Language by flv13903

VIEWS: 89 PAGES: 139

									  52.223 Low Level Programming
        Lecturer: Duncan Smeed


Overview of the C Programming Language

                 Part 1

                            Nature of C

    The C programming language has acquired the
     reputation for being a mysterious and messy language
     that promotes bad programming habits.

    Part of the problem is that C gives special meanings to
     many punctuation characters, such as asterisks, plus
     signs, braces and angle brackets.

    Once a programmer has learnt the C language, these
     symbols look quite commonplace, but there is no
     denying that a typical C program can be intimidating
     to the uninitiated.


52223_05/2
       Overview of the C Programming Language - Part 1

                 Trust the programmer

    The other, more serious, complaint levelled against C
     concern the relative dearth of rules.

    Other programming languages have very strict rules to
     protect programmers from making accidental blunders.

    The C language was designed by experienced
     programmers for experienced programmers. The
     compiler, therefore, assumes little about what the
     programmer does or does not intend to do. This can be
     summed up by the C tenet:

                   "Trust the programmer"



52223_05/3
      Overview of the C Programming Language - Part 1

                 …Trust the programmer

    C programmers have tremendous liberty to write
     unusual code.

    In may instances, this freedom allows programmers to
     write useful programs that would be difficult to write
     in other languages.

    However, the freedom can be, and is, abused by
     inexperienced programmers who delight in writing
     needlessly tricky code.

    C is a powerful language, but it requires self-restraint
     and discipline.


52223_05/4
       Overview of the C Programming Language - Part 1

                        …Trust the programmer

     
“...there is a huge difference between good and
      working programs. A good program not only works,
      but is easy to read and maintain. Despite what some
      people claim, it is very possible to write good
      programs in C.           Unfortunately, many C
      programmers are content to write programs that
      merely work.”


              Excerpted from C: A Software Engineering Approach

                           by Darnell and Margolis




52223_05/5
               Overview of the C Programming Language - Part 1

                  The Background of C

    C was originally designed for and implemented on the
     Unix operating system on the DEC PDP-11, by Dennis
     Ritchie.

    Unix, the C compiler, and virtually all Unix
     applications programs are written in C.

    C is not tied to any particular hardware or system,
     however, and it is easy(!) to write programs that will
     run without change on any machine that supports C.





52223_05/6
       Overview of the C Programming Language - Part 1

                 …The Background of C

    C is a general purpose programming language which
     features economy of expression, modern control flow
     and data structures, and a rich set of operators.

    C is not a 'very high level' language, nor a 'big' one,
     and is not specialised to any particular area of
     application.

    Its absence of restrictions and its generality make it
     more convenient and effective for many tasks than
     supposedly more powerful languages.





52223_05/7
       Overview of the C Programming Language - Part 1

                 …The Background of C

    C has been closely associated with the Unix system.

    It is, however, available on a large number of
     machines under a variety of operating systems; and 

    although it has been called a "systems programming
     language" because it is useful for writing operating
     systems, it has been used equally well to write
     numerical, text-processing, and database programs.





52223_05/8
      Overview of the C Programming Language - Part 1

                  …The Background of C

    C is a relatively "low level" language which means
     that it deals with the same sort of objects that most
     computers do, namely characters, numbers and
     addresses. These may be combined and moved about
     with the usual arithmetic and logical operators
     implemented by actual machines.

    C provides no operations to deal directly with
     composite objects such as character strings, sets, lists,
     or arrays considered as a whole.

    C also provides no input-output facilities such as
     READ or WRITE. Such high-level mechanisms must
     be provided by explicitly called functions.

52223_05/9
        Overview of the C Programming Language - Part 1

                 …The Background of C

    The absence of such features keep the language down
     to modest dimensions so that it can be described
     easily, and learned quickly.

    A compiler for C can be simple and compact and are
     easily written with, typically, 80% of the code
     common to existing ones. This provides a high degree
     of language mobility.





52223_05/10
     Overview of the C Programming Language - Part 1

                 …The Background of C

    Because the data types and control structures provided
     by C are supported directly by most existing
     computers, the run-time library required to implement
     self-contained programs is tiny.

    Of course, each implementation provides a
     comprehensive, compatible, library of functions to
     carry out I/O, string handling, and storage allocation
     operations, but since they are called only explicitly,
     they can be avoided if required; they can also be
     written portably in C itself.




52223_05/11
      Overview of the C Programming Language - Part 1

                  …The Background of C

    C programs tend to be efficient enough that there is no
     compulsion to write assembly language instead.

    The most obvious example of this is Unix itself, the
     kernel of which is written almost entirely in C.

    Of the 13000 lines of system code in early versions of
     Unix, only about 800 lines at the very lowest level
     were in assembler. 

    Since C is independent of any particular machine
     architecture it is possible, with a little care, to write
     "portable" programs that can be run without change on
     a variety of hardware.


52223_05/12
       Overview of the C Programming Language - Part 1

               C as a Programming Language

    Many of the most important ideas of C stem from the
     considerably older language BCPL.

    Although it shares several characteristic features with
     BCPL, C is in no sense a dialect of it. BCPL was a
     "typeless" language: the only data type is the machine
     word, and access to other kinds of objects is by special
     operators or function calls.

    In C, the fundamental data objects are characters,
     integers of several sizes, and floating point numbers.
     In addition there is a hierarchy of derived data types
     created with pointers, arrays, structures, unions and
     functions.

52223_05/13
      Overview of the C Programming Language - Part 1

               C Flow-Control Constructions

    C provides the fundamental flow-control constructions
     required for well-structured programs:

      •  statement grouping;

      •  decision making (if);

      •  looping with the termination test at the top (while,
         for) or at the bottom (do);

      •  and selecting one of a set of possible cases (switch).





52223_05/14
       Overview of the C Programming Language - Part 1

               C Call By ‘Value’ & Call By ‘Reference’

    C provides pointers and the ability to do address
     arithmetic.

    The arguments to functions are passed by copying the
     value (call by value) of the argument, and it is
     impossible to change the actual argument in the caller.

    However, call be reference can be achieved by
     passing a pointer explicitly, and the function may
     change the object to which the pointer 'points'.

    Array names are passed as the location (address) of the
     array origin, so array arguments are effectively call by
     reference.


52223_05/15
           Overview of the C Programming Language - Part 1

                             C Variables

    Any function may be called recursively, and its local
     variables are typically "automatic" - created anew with
     each invocation.

    Functions may be compiled separately.

    Variables may be (a) internal to a function, (b) external
     but known only within a single source file, or (c)
     completely global.

    Internal (local) variables may be placed in registers for
     efficiency, but the register declaration is only a hint to
     the compiler and cannot specify actual registers.



52223_05/16
       Overview of the C Programming Language - Part 1

               Summary of C language structure

    Notes

     •  letter case is NOT ignored by the compiler.

     •  a newline (carriage return) in the C source is
        equivalent to a space, it does not indicate the end of
        a statement except in the case of pre-processor
        directives.





52223_05/17
        Overview of the C Programming Language - Part 1

               Strings and Character Constants

    Strings are normally terminated by a null character,
     i.e. the value 0.

    A string literal (constant) is specified between double
     quotes, e.g. "this is a string". The compiler appends
     the null byte to the end of a string literal.

    A character literal is specified between single quotes,
     e.g. 'A'. No null is appended. Character literals are
     integers.





52223_05/18
        Overview of the C Programming Language - Part 1

                        Control Characters

    Control characters are entered in literals following a
     backslash character (\), as follows:

               newline
                         \n

               tab
                             \t

               backspace
                       \b

               formfeed
                        \f

               backslash
                       \\

               single quote
                    \'

               double quote
                    \"

               null
                            \0

               other control chars
             \N (where N is
                                                octal no.)

52223_05/19
          Overview of the C Programming Language - Part 1

               Integer and Floating Point Constants

  Integer Constants

               nnn
      decimal constant, e.g. 123

               0nnn
     octal constant, e.g. 037

               0xnnn
    hexadecimal constant, e.g.
                         0x1a3

               nnnL
     a long decimal constant


   Floating Point Constants

   FP constants are always double precision. Examples:

      1.23, 1., .23, 1.23e4, 1.23E4, 3e4


52223_05/20
            Overview of the C Programming Language - Part 1

                           Comments

    /* This is a comment */

    They may appear wherever a space or newline is
     allowed.

    Comments are not allowed to nest (caveat: some
     compilers allow nesting). So:

    
someVar = 1;        /* some comment */

     /* someVar = 1; */ /* still legal */

     /* but this attempt to comment out ...

     someVar = 1;        /* some comment */

     ...is illegal in most compilers.    */




52223_05/21
    Overview of the C Programming Language - Part 1

                                 Identifiers

    An identifier is a sequence of letters and digits; the first
     character of which must be a letter.

    The underscore, _ , counts as a letter.

    UPPER and lower case letters are different.

    To conform to the C standard, a compiler must treat at
     least the first 31 characters as significant in the names
     of functions and global variables (i.e. identifiers with
     external linkage), and at least the first 63 characters in
     all other identifiers.

        •  External identifiers, which are used by various assemblers
           and linker/loaders, may be more restricted.



52223_05/22
          Overview of the C Programming Language - Part 1

                             Variable Types
    The sizes of the following variable types are
     implementation dependent. Typical values (in bits) for
     ANSI C are given:

               Type
  Size
                             Use

        char
           8
               ASCII characters - may be signed

        short
         16
               Same as int

        int
           32
               2's complement (signed) integer

        unsigned int
 32
                unsigned integer

        long
          32
               2's complement (signed) integer

        float
         32
               Floating point number

        double
        64
               Floating point number



52223_05/23
           Overview of the C Programming Language - Part 1

                              Storage Classes

    Definitions outside of a function are external
     definitions. There are two classes:

        extern
   global to all files (default)

        static
   local to this file, but global to all functions in this file


   Within a function:

        auto
          local to the function, lost on exit (default)

        static
        local to the function, but not lost on exit

        extern
        declares a variable that is to be found in an external
                       definition

        register
      Similar to auto, but hints to the compiler that the variable
                       is heavily used and should be held in a register



52223_05/24
            Overview of the C Programming Language - Part 1

                    Program Structure

    A C program is a series of external definitions and pre-
     processor directives.

    External definitions are storage definitions and
     function definitions.

    The executable part of the program is made up of the
     functions, which may call each other, passing
     parameters as required.

    There must be one function whose name is main. It is
     this function that is called when the program is run.
     Functions cannot be defined within functions.


52223_05/25
      Overview of the C Programming Language - Part 1

                        The First C Program

               #include 
<stdio.h>


               int main()

               {

                   
printf("Hello, world\n");

                   
return (0);

               }





52223_05/26
           Overview of the C Programming Language - Part 1

                          Function Definition

  A function definition has three parts:

        a)     the function declaration

        b)     the parameter declarations

        c)     the function body - a compound statement


  /* Declare the function max that returns an int...                        */

  int max(int a,int b,int c)

  /* ...with the parameters a, b, and c of type int                         */

  {              /* start of the compound statement                         */

      int m;     /* auto storage decl'n (local var.)                        */

      m = (a>b) ? a : b;      /* m = max of a,b                             */

      return ((m>c) ? m : c); /* return max of m,c                          */

  }              /* end compound statement                                  */



52223_05/27
             Overview of the C Programming Language - Part 1

                 Compound Statement

  A compound statement may be used wherever a simple
  statement is permitted. It has two parts:

       a)  storage declarations and definitions (optional)

       b)  executable statements

  The compound statement is enclosed in braces {curly
  brackets such as these}.





52223_05/28
      Overview of the C Programming Language - Part 1

                      Simple Statement

  A simple statement has the form:

     label: statement;

  The label is optional - it's only use is the target of a goto
  ({over}use of which is to be strongly discouraged). A
  label takes the same form as an identifier.





52223_05/29
       Overview of the C Programming Language - Part 1

                 Pointers and Addresses

  An identifier may be declared as a pointer to a particular
  type of data.      This is frequently used in string
  manipulation, using a pointer to type char, and in
  buffered files, using a pointer to type FILE. Example
  declarations:

  char *a;   /* a declared to be a pointer to char */

  int *b[5]; /* b declared as an array of 5 pointers

                to int */ 





52223_05/30
      Overview of the C Programming Language - Part 1

                    Address Operator                       &
    The address operator & yields the address of its
     operand.

    If the operand x has the type T, then the expression &x
     has the type ‘pointer to T’.

    The operand of the address operator must have an
     addressable location in memory. I.e. the operand must
     designate either a function or an object (i.e. an lvalue)
     that is not a bit-field, and has not been declared with
     the storage class register 




52223_05/31
       Overview of the C Programming Language - Part 1

                            Pointer Variables
  A pointer variable contains the address of a storage element. The
  address of a variable can be put in a pointer:

  int     x;    /*   defines an integer                                    */

  int     *p;   /*   defines a pointer to int                              */

  p =     &x;   /*   place address of x in p                               */

  x =     *p;   /*   places the value pointed at by p in x                 */


  Pointers can have integers added or subtracted, which moves them
  by that number of storage elements. E.g., adding 5 to a pointer to
  int moves it forward by 5 integer 'elements' - 20 bytes in the case
  where an int is 32-bits in size.


  A pointer can have the constant value 0 (null) assigned to it. It is
  then a null pointer and is guaranteed to be different to any pointer
  to an actual value.

52223_05/32
            Overview of the C Programming Language - Part 1

                              main()
    Every executable program must contain a special
     function called main(), which is where program
     execution begins. For example, to invoke max(), you
     could write:

       int main()

       {

           int maximum;

           maximum = max(3,4,5);

           /* rest of main() ... */

       }




52223_05/33
     Overview of the C Programming Language - Part 1

                            printf()
    The printf() function is the most versatile
     runtime routine for display output.

    This function can take any number of arguments, the
     first of which - the format string - is special as it
     specifies how many data arguments are to follow and
     how they are to be formatted.

    The format string is enclosed in double quotes, and
     may contain text and format specifiers.





52223_05/34
      Overview of the C Programming Language - Part 1

                     printf() Format Specifier
    A format specifier is a special character sequence that
     begins with a percent sign (%) and indicates how to
     write a single data item. For example:

  printf("The maximum of %d %d & %d is %d\n”,\

          3,4,5,max(3,4,5));

    The %d specifiers indicate that the data items are
     decimal integers. Other similar specifiers are:


               %c
      character data item

               %f
      floating point data item

               %s
      null-terminated character array (string)

               %o
      octal integer

               %x
      hexadecimal integer

52223_05/35
            Overview of the C Programming Language - Part 1

                                scanf()
    The scanf() function is the mirror image of printf() - it
      reads data entered form standard input (i.e. the keyboard). The
      major difference is that scanf() must have the address of a
      data item passed as the argument. For example:

          scanf("%d %d %d",&num1,&num2,&num3);

     
directs the system to read integer input and store the values in
      num1, num2 and num3. The ampersand (&) is a special
      character that yields the address of a variable.

    The best way to learn how to use printf() and scanf()
      is to experiment with them and, of course, to read complete
      descriptions of them in the manual pages or from a text book.



52223_05/36
         Overview of the C Programming Language - Part 1

                     The Preprocessor

    The preprocessor can be thought of as a separate
     program that runs before the compiler.

    The preprocessor directives begin with a hash (#) sign,
     which must be the first character on the line.

    Unlike C statements, a preprocessor directive ends
     with a newline, not a semicolon.





52223_05/37
      Overview of the C Programming Language - Part 1

                                #include
    The #include directive causes the compiler to read source
     text from another files as well as the file it is currently
     compiling. This is useful when identical information is to be
     shared by more than one source file. It has two forms:

   
#include <filename>

   
#include "filename"

    The <...> form causes the preprocessor to look in a special
     directory which contains all the system include files, such as
     header files for the runtime library - e.g. <stdio.h>.

    The "..." form causes the preprocessor to look in the directory
     containing the source file and, if it can't find it there, it'll revert
     back to the special directory.


52223_05/38
          Overview of the C Programming Language - Part 1

                             #define

    The #define directive associates a name with a
     constant (among other thing). For instance:

   
#define MAX_PAGE_WIDTH 80

     #define LOOPS 100000000

    Naming constants has two important benefits.

      •  Firstly, it enables the programmer to give a
         descriptive name to a nondescript constant thus
         making the program easier to read and understand
         (hopefully!).

      •  Secondly, they make the program easier to change!


52223_05/39
      Overview of the C Programming Language - Part 1

                References & Bibliography

    C in a Nutshell
      <http://www.oreilly.com/catalog/cinanut/>

    The C Book (online e-book)
      <http://publications.gbdirect.co.uk/c_book/>


    Standard C
      <http://www-ccs.ucsd.edu/c/>

    C: A Software Engineering Approach (print on demand?)
      <http://tinyurl.com/ay58v>





52223_05/40
       Overview of the C Programming Language - Part 1

  52.223 Low Level Programming
        Lecturer: Duncan Smeed


Overview of the C Programming Language

                 Part 2

                      Scalar Data Types

    The ability to divide data into different types is one of
     the most important features of modern programming
     languages.

    The programmer can work with integers, characters,
     floating point numbers, etc., without having to be
     concerned with the underlying representations.

    It is up to the compiler, therefore, to make sure that the
     computer handles bits and bytes in a way consistent
     with their data type.




52223_06/42
       Overview of the C Programming Language - Part 2

                       …Scalar Data Types

  The C language offers a small but useful set of data
     types:

    Arithmetic types: Integers and floating-point entities.

    Scalar types: arithmetic types plus pointers and
     enumerated types. Known as the scalar types because
     all of the values lie along a linear 'scale'.

    Aggregate types: a combination of one or more scalar
     types including:

        •  arrays, structures and unions

        •  useful for organising logically-related variables into
           physically-adjacent groups.

    Void type: neither scalar or aggregate.

52223_06/43
         Overview of the C Programming Language - Part 2

               Hierarchy of C Data Types




52223_06/44
     Overview of the C Programming Language - Part 2

               Standard Signed Integer Types

   Type
                     Synonyms


   signed char


   int
                      signed, signed int

                             short int, signed short,
   short

                             signed short int

                             long int, signed long,
   long

                             signed long int

                             long long int, signed long
   long long (C99)

                             long, signed long long int




52223_06/45
       Overview of the C Programming Language - Part 2

               Standard Unsigned Integer Types

   Type
                               Synonyms


   unsigned char


   unsigned int
                       unsigned


   unsigned short
                     unsigned short int


   unsigned long
                      unsigned long int


   unsigned long long
                 unsigned long long int





52223_06/46
        Overview of the C Programming Language - Part 2

                                  char

   Type
             Synonyms


   char
             signed char or unsigned char


    The type char is one of the standard integer types but
     can be signed or unsigned depending on the
     implementation. So,

    char, signed char and unsigned char are
     formally three different types.




52223_06/47
      Overview of the C Programming Language - Part 2

                        Floating-point Types

    The standard floating-point types for calculating with
     real numbers are as follows:

    float

          
Single precision

    double

          
Double precision

    long double

          
Extended precision





52223_06/48
            Overview of the C Programming Language - Part 2

                                  Typedefs
    Names for data types can be created with a typedef keyword.

    Syntactically, a typedef is exactly like a variable declaration
     except that the declaration is preceded by the typedef keyword. 

    Semantically, the variable name becomes a synonym for the
     data type rather than a variable that is allocated memory. E.g.:

      typedef long int DOUBLE_WORD;

    The following declarations are now identical:

      long int j;

      DOUBLE_WORD j;

    By convention, typedef names are capitalised so that they are
     not confused with variable names.


52223_06/49
         Overview of the C Programming Language - Part 2

                          Uses of Typedefs
    Typedefs are especially useful for abstracting global types that
      can be used throughout a program.

    Another use for typedefs is to compensate for differences in C
      compilers:

     
For example, some non-ANSI C compilers do not support the
      unsigned short type. Using typedefs, you can write the program
      so that it uses unsigned short if it's available, or unsigned int if
      not.

       •  ANSI-conforming:

               typedef unsigned short USHORT;

       •  non-ANSI:

               typedef unsigned int USHORT;

52223_06/50
          Overview of the C Programming Language - Part 2

    BUG ALERT - Confusing typedef with #define
    It may seem that typedef duplicates functionality provided by
      the #define directive. E.g.:
          
#define USHORT unsigned int

      which seems to serve the same effect as:
          
typedef unsigned int USHORT;

    However, for complex type declarations #define is
      inadequate. E.g.:
          
#define PTR_TO_INT int *

     
to declare two pointers to int:
          
PTR_TO_INT p1,p2;

     
which expands to:
          
int * p1, p2; /* I.e. p2 is an int */




52223_06/51
        Overview of the C Programming Language - Part 2

                       Enumeration Types
    Enumeration types are particularly useful for creating a unique
      set of values that may be associated with a variable. The
      compiler reports an error if you attempt to assign a value that's
      not part of the declared set of legal values. For example, given:

   
 
enum {red,blue,green,yellow} colour;

   
 
enum {bright,medium,dark} intensity;

     
a good compiler would issue warnings for all the type conflicts
      and misleading usages shown below:

       colour = yellow; /* OK */

       colour = bright; /* type conflict */

       colour = 1;                  /* type conflict */

       intensity=bright+medium; /*misleading */

52223_06/52
          Overview of the C Programming Language - Part 2

                      …Enumeration Types

    Constant names in an enum declaration receive a
     default integer value based on their position in the list.
     These start at zero and go up by one with each new
     name.

    The default values can be overridden by specifying
     other values. If you specify a value, all subsequent
     default values begin at one more than the last defined
     value. E.g.:

  enum {APPLE,ORANGES=8,LEMONS,GRAPES=5,MELONS};

      
is the same as:

  enum {APPLE=0,ORANGES=8,LEMONS=9,GRAPES=5,MELONS=6};


52223_06/53
         Overview of the C Programming Language - Part 2

                 The void Data Type

    The type specifier void indicates that no value is
     available.

    Variables and constants cannot be declared with this
     type.

    void can be used for the following purposes: 

      •  void in Function Declarations

      •  Expressions of type void

      •  Pointers to void 




52223_06/54
     Overview of the C Programming Language - Part 2

               void in Function Declarations
    A function with no return value has the type
     void. E.g. in the function prototype:
        
void perror( const char * );

     
This allows the compiler to detect any attempt to use
      the return value from perror as a mistake.


    The other purpose of void is to declare a generic
     pointer which is automatically cast to the correct type
     when it s assigned a pointer value (ANSI standard).




52223_06/55
       Overview of the C Programming Language - Part 2

                        CONTROL FLOW

  Recap:

    C provides the fundamental flow-control constructions
     required for well-structured programs, including:

      •  decision making (if);

      •  looping with the termination test at the top (while,
         for) or at the bottom (do);

      •  and selecting one of a set of possible cases
         (switch).





52223_06/56
       Overview of the C Programming Language - Part 2

                  Conditional Branching




    This is the most basic control feature of any language.
     In C, conditional execution is performed with the if
     and else keywords:

    If the expression is ‘true’ (non-zero), the next
     statement is executed. If the else clause is present, the
     statement following the else is executed whenever the
     if expression is ‘false’ (0).

52223_06/57
       Overview of the C Programming Language - Part 2

                     Comparison Expressions

    Typically, the expression of an if statement is a
     comparison between two values:

               <
      less than

               >
      greater than

               <=
     less than or equal

               >=
     greater than or equal

               ==
     equal to

               !=
     not equal to


     The value of a relational expression is an integer, either
      1 (true) or 0 (false). For example:
      (-1 < 0) yields 1, (0 > 1) yields 0, (0 == 0) yields 1

52223_06/58
          Overview of the C Programming Language - Part 2

               BUG ALERT - Confusing = with ==
    One of the most common mistakes made by beginners and
     experts alike is to use the assignment operator (=) instead of the
     equality operator (==). E.g.:
         
if (j = 5)

        
 do_something();

     
which should have been:
          
if (j == 5)

         
 do_something();

    Note that the first version is syntactically legal since all
      expressions yield a value. The value of the expression j=5 is
      5.    As this is non-zero, it is accepted as ‘true’ and
      do_something() is always invoked.


52223_06/59
         Overview of the C Programming Language - Part 2

                                 switch

    When there are many paths on a program, if-else branching can
     become so convoluted that it is difficult to follow. These
     situations are prime candidates for use of the switch
     statement. E.g.:
      int switch_example(char input_arg) {

          switch (input_arg) {

              case ’D': return 1;

              case ’U': return 2;

              case ’N': return 3;

              case ’C': return 4;

              default: return -1;

          } /* end of switch */

      } /* end of switch_example */

    The expression immediately after the switch keyword must
     be enclosed in parentheses and must be an integral expression.
     I.e., it can only be char, short, int or long.

52223_06/60
        Overview of the C Programming Language - Part 2

                          ...switch

    An important feature of the switch statement is that
     program flow continues from the selected case label
     until another control-flow statement or the end of the
     switch statement is reached.

    That is, the any statements following the selected case
     label are executed until a break, goto or return
     statement appears.

      For example:…





52223_06/61
      Overview of the C Programming Language - Part 2

                          ...switch

 typedef enum{

      ERR_INPUT_VAL, ERR_OPERAND, ERR_OPERATOR,

      ERR_TYPE} ERROR_SET;

 ERROR_SET error_code

 ...

 switch (error_code) {

      case ERR_INPUT_VAL:

           printf("Error: Illegal input value\n");

           break;

      ...

      case ERR_TYPE:

           printf("Error: Incompatible data\n");

           break;

      default:

           printf(”Error: Unknown error code%d\n",error_code);;

           break; /* Not strictly necessary but */

                   /* good programming practice. */

 }


52223_06/62
      Overview of the C Programming Language - Part 2

                              while



    The statement, which is often a compound
     statement, is called the body of the while loop.





52223_06/63
    Overview of the C Programming Language - Part 2

                             do...while
       do      statement

               while                (        expression                )   ;

    There are certain situation where you may need to execute the
     body at least one.        When these situations occur, the
     do...while statement should be used. For example:

   
do {

          ch = getchar();

          if (ch == ‘ ‘)

                num_of_spaces++;

          } while (ch != ‘\n’);


52223_06/64
        Overview of the C Programming Language - Part 2

                                         for
        for      (                                  ;                        ;
                      expression1                              expression2

                                     )           statement
               expression3

    The for statement is designed as shorthand for a
     particularly common looping situation

        •  when you need to initialise one or more variables before
           entering the loop, and

        •  When you need to change the values of one or more
           variables each time through the loop.



52223_06/65
           Overview of the C Programming Language - Part 2

                                        ...for
               for     (                              ;                       ;
                            expression1                         expression2

                                         )         statement
                     expression3

    The for statement operates as follows:

        1.  Firstly expression1 is evaluated - usually assignment(s);

        2.  then expression2 is evaluated. This is the conditional part
            of the statement;

        3.  if expression2 is false, program control exits the for
            statement, otherwise statement is executed;

        4.  after statement is executed, expression3 is evaluated and
            then for loops back to test expression2 again - i.e. repeats
            from step (2).

52223_06/66
               Overview of the C Programming Language - Part 2

                                    ...for
    The easiest way to understand the for statement is
     to compare it to a while statement. For example:

           for (expr1;expr2;expr3)

               statement;


           is the same as:


           expr1;

           while (expr2){

               statement;

               expr3;

           }

52223_06/67
           Overview of the C Programming Language - Part 2

                        Null Statement

    The syntax of the for loop allows the omission of not
     only the expressions within the for (...;...;...)
     but also the body of the for loop. 

    This is useful when the loop's work is being done by
     the expressions. For example:

  void skip_spaces(void) {

      int c;

      for ( c=getchar(); isspace(c); c=getchar() )

          ; /* Null statement */

      ungetc(c,stdin); /* put the non-space character */

                       /* back into the input buffer. */

  }



52223_06/68
      Overview of the C Programming Language - Part 2

                BUG ALERT - Misplaced semicolons

    A common mistake is to place a semicolon
     immediately after a control flow statement. For
     instance:

      if (j == 1);

          j = 0;


      is as:


      if (j == 1)

           ; /* Null statement */

      j = 0; /* j _always_ gets assigned 0 */



52223_06/69
          Overview of the C Programming Language - Part 2

                                  break

    As well as its use in a switch a break can be used to force
     an immediate exit from while, do and for loops. 

    In this context, break statements should be used sparingly
     since they force program control to jump discontinuously to a
     new place and too many can make a program difficult to follow.


      for (cnt=0; cnt<50; cnt++) {

          c=getchar();

          if (c==’\n')

              break;

          else

              /* process the character */

      }

52223_06/70
        Overview of the C Programming Language - Part 2

                               continue

    The continue statement provides a means for returning to the
     beginning of a loop earlier than normal.

    It is particularly useful when you want to by-pass the remainder
     of the loop for some reason. For example, the code to 'make' an
     integer from input characters providing those characters are
     numeric could be written as:


      while ((c = getchar()) != ’\n') {

          if (isdigit(c) == 0)

              continue;

          num = num * 10;

          num = num + (c - '0');

      }


52223_06/71
         Overview of the C Programming Language - Part 2

               Alternative ways to ‘make’ an integer
        for (c=getchar();isdigit(c);c=getchar()){

                num = num * 10;

                num = num + (c - '0');

            }


        /* or */

            c = getchar();

            while (isdigit(c)) {

                num = num * 10;

                num = num + (c - '0');

                c = getchar();

            }

        /* or... */


52223_06/72
           Overview of the C Programming Language - Part 2

                 Operators and Expressions
    C's rich set of operators is one of its distinguishing
     characteristics.

    An expression consists of one or more operands and zero or
     more operators. 

    There are 4 main types of expression:

      •  Constant Expressions - containing only constant values. 

      •  Integral Expressions - produce a result that has one of the
         integer types. 

      •  Float Expressions - produce a result that has one of the
         floating point types.

      •  Pointer Expressions - are expressions that evaluate to an
         address value.

52223_06/73
        Overview of the C Programming Language - Part 2

                  Constant Expression

    Contain only constant values. E.g:
       
     
      
5

       
     
      
5 * 6 + 13/3.0

       
     
      
'z'





52223_06/74
     Overview of the C Programming Language - Part 2

                   Integral Expressions

    Produce a result (after all automatic and explicit type
     conversions) that has one of the integer types. E.g.
     (where j and k are integers):
       
     
j

       
     
j/k + 3

       
     
3 + (int) 5.0/k





52223_06/75
      Overview of the C Programming Language - Part 2

                      Float Expressions

    Produce a result that has one of the floating point
     types. E.g. (where j is an int, f is a float and d is
     a double):
        
     
f

        
     
(float)j

        
     
f/d + 3

        
     
1.0/CLOCKS_PER_SEC

        
     
(double)3/4 + d





52223_06/76
      Overview of the C Programming Language - Part 2

                    Pointer Expressions

    These are expressions that evaluate to an address
     value. They include expressions containing pointer
     variables, & operator, string literals and array names. If
     p is a pointer and j is an int, the following are
     pointer expressions:
       
      
p

       
      
&j

       
      
p + 1

       
      
“a string literal”

       
      
(char *) 0x000ffff




52223_06/77
       Overview of the C Programming Language - Part 2

       Precedence and Associativity of C Operators
        Class of Operator
     Operators in that Class
         Associativity
    Precedence

       primary
                       () [] -> .
                Left-to-right
    HIGHEST

                                      Cast operator

                                         sizeof

                                     & (address of)

       unary
                       * (dereference)

                                                                 Right-to-left

                                           - +

                                       ~ ++ -- !

       multiplicative
                    * / %
                 Left-to-right

       additive
                           + -
                  Left-to-right

       shift
                           <<      >>
              Left-to-right

       relational
                  < <= > >=
                   Left-to-right

       equality
                         == !=
                  Left-to-right

       bitwise AND
                          &
                  Left-to-right

       bitwise exclusive OR
                 ^
                  Left-to-right

       bitwise inclusive OR
                 |
                  Left-to-right

       logical AND
                         &&
                  Left-to-right

       logical OR
                          ||
                  Left-to-right

       conditional
                        ? :
                  Right-to-left

                                     = += -= *=

       assignment
                /= %= >>= <<=
                 Right-to-left

                                         &= ^=

       comma
                                ,
                  Left-to-right
    LOWEST



52223_06/78
                   Overview of the C Programming Language - Part 2

       Precedence and Associativity of C Operators
        Class of Operator
     Operators in that Class
         Associativity
     Precedence

       primary
                   () [] -> .
                Left-to-right
         HIGHEST   

                                       Cast operator

                                          sizeof

                                       & (address of)

       unary
                         * (dereference)

                                                                  Right-to-left

                                            - +

                                        ~ ++ -- !

       multiplicative
                     * / %
                 Left-to-right

       additive
                               + -
               Left-to-right

       shift
                             <<         >>
          Left-to-right

       relational
                    <   <=     >    >=
         Left-to-right

       equality
                           ==    !=
              Left-to-right

       bitwise AND
                             &
                Left-to-right

       bitwise exclusive OR
                    ^
                Left-to-right

       bitwise inclusive OR
                    |
                Left-to-right

       logical AND
                             &&
               Left-to-right

       logical OR
                              ||
               Left-to-right

       conditional
                       ? :
                    Right-to-left

                                      = += -= *=

       assignment
                  /= %= >>= <<=
                Right-to-left

                                        &= ^=

       comma
                                   ,
                Left-to-right
    LOWEST





52223_06/79
                   Overview of the C Programming Language - Part 2

       Precedence and Associativity of C Operators
        Class of Operator
     Operators in that Class
         Associativity
     Precedence

       primary
                           () [] -> .
             Left-to-right
    HIGHEST

                                 Cast operator

                                    sizeof

                                 & (address of)

       unary
                   * (dereference)

                                                             Right-to-left

                                      - +

                                  ~ ++ -- !

       multiplicative
                      * / %
                Left-to-right

       additive
                                + -
              Left-to-right

       shift
                              <<         >>
         Left-to-right

       relational
                    <    <=     >    >=
        Left-to-right

       equality
                            ==    !=
             Left-to-right

       bitwise AND
                              &
               Left-to-right

       bitwise exclusive OR
                     ^
               Left-to-right

       bitwise inclusive OR
                     |
               Left-to-right

       logical AND
                              &&
              Left-to-right

       logical OR
                               ||
              Left-to-right

       conditional
                       ? :
                    Right-to-left

                                      = += -= *=

       assignment
                  /= %= >>= <<=
                Right-to-left

                                        &= ^=

       comma
                                    ,
               Left-to-right
    LOWEST

52223_06/80
                   Overview of the C Programming Language - Part 2

       Precedence and Associativity of C Operators
        Class of Operator
     Operators in that Class
          Associativity
     Precedence

       primary
                              () [] -> .
           Left-to-right
    HIGHEST

                                          Cast operator

                                             sizeof

                                          & (address of)

       unary
                            * (dereference)

                                                                   Right-to-left

                                               - +

                                           ~ ++ -- !


       multiplicative
                * / %
                    Left-to-right

       additive
                       + -
                     Left-to-right

       shift
                       <<    >>
                   Left-to-right

       relational
                       <    <=     >    >=
      Left-to-right

       equality
                               ==    !=
           Left-to-right

       bitwise AND
                                 &
             Left-to-right

       bitwise exclusive OR
                        ^
             Left-to-right

       bitwise inclusive OR
                        |
             Left-to-right

       logical AND
                                 &&
            Left-to-right

       logical OR
                                  ||
            Left-to-right

       conditional
                             ? :
               Right-to-left

                                         =     += -= *=

       assignment
                  /=       %= >>= <<=
           Right-to-left

                                              &= ^=

       comma
                                       ,
             Left-to-right
    LOWEST




52223_06/81
                   Overview of the C Programming Language - Part 2

       Precedence and Associativity of C Operators
        Class of Operator
     Operators in that Class
         Associativity
     Precedence

       primary
                        () [] -> .
                Left-to-right
    HIGHEST

                                       Cast operator

                                          sizeof

                                       & (address of)

       unary
                         * (dereference)

                                                                  Right-to-left

                                            - +

                                        ~ ++ -- !

       multiplicative
                     * / %
                 Left-to-right

       additive
                             + -
                 Left-to-right

       shift
                           <<         >>
            Left-to-right


       relational
              <     <=           > >=
     Left-to-right

       equality
                      ==           !=
       Left-to-right

       bitwise AND
                           &
                  Left-to-right

       bitwise exclusive OR
                  ^
                  Left-to-right

       bitwise inclusive OR
                  |
                  Left-to-right

       logical AND
                          &&
                  Left-to-right

       logical OR
                           ||
                  Left-to-right

       conditional
                       ? :
                    Right-to-left

                                      = += -= *=

       assignment
                  /= %= >>= <<=
                Right-to-left

                                        &= ^=

       comma
                                 ,
                  Left-to-right
    LOWEST





52223_06/82
                   Overview of the C Programming Language - Part 2

       Precedence and Associativity of C Operators
        Class of Operator
   Operators in that Class
         Associativity
     Precedence

       primary
                         () [] -> .
             Left-to-right
    HIGHEST

                                     Cast operator

                                        sizeof

                                     & (address of)

       unary
                       * (dereference)

                                                                Right-to-left

                                          - +

                                      ~ ++ -- !

       multiplicative
                   * / %
                 Left-to-right

       additive
                              + -
              Left-to-right

       shift
                            <<         >>
         Left-to-right

       relational
                  <    <=     >    >=
        Left-to-right

       equality
                          ==    !=
             Left-to-right


       bitwise AND
                            &
          Left-to-right

       bitwise XOR
                            ^
          Left-to-right

       bitwise OR
                             |
          Left-to-right

       logical AND
                            &&
              Left-to-right

       logical OR
                             ||
              Left-to-right

       conditional
                     ? :
                    Right-to-left

                                    = += -= *=

       assignment
                /= %= >>= <<=
                Right-to-left

                                      &= ^=

       comma
                                  ,
               Left-to-right
    LOWEST




52223_06/83
                 Overview of the C Programming Language - Part 2

       Precedence and Associativity of C Operators
        Class of Operator
     Operators in that Class
         Associativity
     Precedence

       primary
                           () [] -> .
             Left-to-right
    HIGHEST

                                       Cast operator

                                          sizeof

                                       & (address of)

       unary
                         * (dereference)

                                                                  Right-to-left

                                            - +

                                        ~ ++ -- !

       multiplicative
                     * / %
                 Left-to-right

       additive
                                + -
              Left-to-right

       shift
                              <<         >>
         Left-to-right

       relational
                    <    <=     >    >=
        Left-to-right

       equality
                            ==    !=
             Left-to-right

       bitwise AND
                              &
               Left-to-right

       bitwise exclusive OR
                     ^
               Left-to-right

       bitwise inclusive OR
                     |
               Left-to-right


       logical AND
                             &&
          Left-to-right

       logical OR
                              ||
          Left-to-right

       conditional
                       ? :
                    Right-to-left

                                      = += -= *=

       assignment
                  /= %= >>= <<=
                Right-to-left

                                        &= ^=

       comma
                                    ,
               Left-to-right
    LOWEST





52223_06/84
                   Overview of the C Programming Language - Part 2

       Precedence and Associativity of C Operators
        Class of Operator
     Operators in that Class
          Associativity
     Precedence

       primary
                              () [] -> .
           Left-to-right
    HIGHEST

                                          Cast operator

                                             sizeof

                                          & (address of)

       unary
                            * (dereference)

                                                                   Right-to-left

                                               - +

                                           ~ ++ -- !

       multiplicative
                        * / %
               Left-to-right

       additive
                                   + -
            Left-to-right

       shift
                                 <<         >>
       Left-to-right

       relational
                       <    <=     >    >=
      Left-to-right

       equality
                               ==    !=
           Left-to-right

       bitwise AND
                                 &
             Left-to-right

       bitwise exclusive OR
                        ^
             Left-to-right

       bitwise inclusive OR
                        |
             Left-to-right

       logical AND
                                 &&
            Left-to-right

       logical OR
                                  ||
            Left-to-right


       conditional
                            ? :
             Right-to-left

                                         =     += -= *=

       assignment
                  /=       %= >>= <<=
           Right-to-left

                                              &= ^=

       comma
                                       ,
             Left-to-right
    LOWEST





52223_06/85
                   Overview of the C Programming Language - Part 2

       Precedence and Associativity of C Operators
        Class of Operator
     Operators in that Class
         Associativity
     Precedence

       primary
                           () [] -> .
             Left-to-right
    HIGHEST

                                       Cast operator

                                          sizeof

                                       & (address of)

       unary
                         * (dereference)

                                                                  Right-to-left

                                            - +

                                        ~ ++ -- !

       multiplicative
                     * / %
                 Left-to-right

       additive
                                + -
              Left-to-right

       shift
                              <<         >>
         Left-to-right

       relational
                    <    <=     >    >=
        Left-to-right

       equality
                            ==    !=
             Left-to-right

       bitwise AND
                              &
               Left-to-right

       bitwise exclusive OR
                     ^
               Left-to-right

       bitwise inclusive OR
                     |
               Left-to-right

       logical AND
                              &&
              Left-to-right

       logical OR
                               ||
              Left-to-right

       conditional
                             ? :
              Right-to-left

                                 = += -= *=

                                 /= %= >>=
       assignment
                   <<=

                                                             Right-to-left

                                   &= ^=

       comma
                                    ,
               Left-to-right
    LOWEST


52223_06/86
                   Overview of the C Programming Language - Part 2

       Precedence and Associativity of C Operators
        Class of Operator
     Operators in that Class
         Associativity
     Precedence

       primary
                           () [] -> .
             Left-to-right
    HIGHEST

                                       Cast operator

                                          sizeof

                                       & (address of)

       unary
                         * (dereference)

                                                                  Right-to-left

                                            - +

                                        ~ ++ -- !

       mutliplicative
                     * / %
                 Left-to-right

       additive
                                + -
              Left-to-right

       shift
                              <<         >>
         Left-to-right

       relational
                    <    <=     >    >=
        Left-to-right

       equality
                            ==    !=
             Left-to-right

       bitwise AND
                              &
               Left-to-right

       bitwise exclusive OR
                     ^
               Left-to-right

       bitwise inclusive OR
                     |
               Left-to-right

       logical AND
                              &&
              Left-to-right

       logical OR
                               ||
              Left-to-right

       conditional
                       ? :
                    Right-to-left

                                      = += -= *=

       assignment
                  /= %= >>= <<=
                Right-to-left

                                        &= ^=


       comma
                                    ,
          Left-to-right
         LOWEST  



52223_06/87
                   Overview of the C Programming Language - Part 2

               Precedence and Associativity
    The properties of precedence and associativity affect how
     operands are attached to operators. Operators with higher
     precedence have their operators bound, or grouped, to them
     before operators of lower precedence.

    In cases where operators have the same precedence,
     associativity determines the order in which operands are
     grouped with operators. For example, The plus (+) and minus
     (-) operators have the same precedence and are both left-to-
     right associative:

    
a + b - c; /* Add a to b, then subtract c */

    The assignment operator (=) is right associative:

    
a = b = c; /* Assign c to b, then assign b to a */



52223_06/88
        Overview of the C Programming Language - Part 2

                      Order of Evaluation
    An important point to understand is that precedence and
     associativity have little to do with the order of evaluation. The
     order of evaluation refers to the actual order in which the
     compiler evaluates operators.

    Note that this is independent from the order in which the
     compiler groups operands to operators. For most operators, the
     compiler is free to evaluate sub-expressions in any order it
     pleases. For example:

                    (2 + 3) * 4 could generate:

                      2 + 3 and then * by 4, or

                 2 * 4 and then 3 * 4 and then add

    The order of evaluation can have a critical impact on
     expressions that contain side effects or the reorganisation of
     expressions can give rise to overflow conditions.

52223_06/89
         Overview of the C Programming Language - Part 2

       BUG ALERT - Integer Division and Remainder
    If both operands of / are positive integers any fractional part is
     truncated:

                                5/2 -> 2

                                1/3 -> 0

    If either operand is negative, however, the compiler is free to
     round the result either up or down:

                          5/-2 -> -2 or -3

                          -1/3 -> 0 or -1

    The sign of the result of a remainder operation has the same
     sign as the left operand:

                              -5%2 -> -1

                               5%-2 -> 1


52223_06/90
         Overview of the C Programming Language - Part 2

                         C Style - Bibliography

    C and C++ Style Guides
      <http://www.chris-lott.org/resources/cstyle/>…

         Recommended C Style and Coding Standards (HTML)
         …<indhill-cstyle.html>    [<http://tinyurl.com/dpv4v>]

         ‘C’ Style Guide and Programming Guidelines (PDF)
         …<Peter_CStyleGuide.pdf>    [<http://tinyurl.com/z2lxn>]

    Recommended C Style and Coding Standards (PDF)
        <http://www.literateprogramming.com/indhill-cstyle.pdf>             





52223_06/91
             Overview of the C Programming Language - Part 2

  52.223 Low Level Programming
        Lecturer: Duncan Smeed


Overview of the C Programming Language

                 Part 3

               Arithmetic Assignment Operators

    In addition to the simple assign operator =, C supports
     5 additional assignment operators that combine
     assignment with each of the arithmetic operations.
     E.g.:
         
j = j * 5;

     can be written as:
         
j *= 5;

    Why have such operators?

        •  to avoid spelling mistakes and make code easier to read and
           to write, e.g. when referencing structure and union members 

        •  compiler may produce more efficient low level code


52223_07/93
           Overview of the C Programming Language - Part 3

                 …Arithmetic Assignment Operators

    Another feature of these operators is that if the 1value
     (left hand operand) contains side effects, the side
     effects occur only once.

    Also, the assign operators have relatively low
     precedence, so:

   
       
j *= 3+4 → j *= (3+4) → j = j * (3+4)

  not
               
j = (j * 3) + 4





52223_07/94
           Overview of the C Programming Language - Part 3

               Increment and Decrement Operators

    The increment (++) and decrement (--)
     operators are unary and their operands must be
     a scalar lvalue.

    It is legal to ++ or -- pointer variables, but the
     meaning of adding (subtracting) one to a
     pointer is different from adding one to an
     arithmetic value.

    Precedence of ++ and --

        •  ++ and -- have the same precedence, but bind
           from right to left.


52223_07/95
          Overview of the C Programming Language - Part 3

                        Forms of ++ and --

    Postfix increment : a++

        •  get value of a, then increment a

    Postfix decrement : a--

        •  get value of a, then decrement a

    Prefix increment : ++a

        •  increment a, then get value of a

    Prefix decrement : --a

        •  decrement a, then get value of a





52223_07/96
           Overview of the C Programming Language - Part 3

                     BUG ALERT - Side Effects
    The ++, -- and assignment operators cause side effects. I.e. they
     yield a value but the value of the variable is also changed.

    The order in which the side effects occur is unpredictable - they
     are implementation dependent (i.e. non-portable). E.g., given:

                            x = j * j++;

      Is j evaluated first or is j++ evaluated first?

    The problem also occurs in function calls such as foo(a,a+
     +) as C does not guarantee the order in which arguments are
     evaluated.

    To prevent such side effects avoid use of an affected variable
     anywhere else when using a side effect operator. E.g.:

               x = j * j; /* unambiguous version */

               j++;       /* of the above example.*/

52223_07/97
           Overview of the C Programming Language - Part 3

                          Comma Operator
    The comma operator allows you to evaluate two or more
     distinct expressions whenever a single expression is allowed.
     The result is the value of the right most operand. I.e. :

               a,b → evaluate a, evaluate b, result is b.

    This operator is one of the few for which the order of evaluation
     is specified. The compiler must evaluate the left hand operand
     first.

    Over-use of the comma operator can lead to confusing code.
     By convention, therefore, it is used primarily in the first and last
     expressions of a for statements. Caveat : try to avoid the
     temptation of fitting as much as possible into the for
     expressions.




52223_07/98
          Overview of the C Programming Language - Part 3

                       …Comma Operator
    Over-use of the comma operator can lead to confusing code. By
     convention, therefore, it is used primarily in the first and last
     expressions of a for statements. Caveat : try to avoid the
     temptation of fitting as much as possible into the for
     expressions.


         for (c=getchar(),j=0 ; C! = EOF ;\

              c=getchar(),putchar(c),j++)

             if (j% interval == 0) printf(”\n");


      While the above is compact, it is not better since it is
      harder to read. You should be wary about using
      multiple assignments in the 3rd expression.


52223_07/99
         Overview of the C Programming Language - Part 3

                Relational Operators

    Relational operators have lower precedence
     than arithmetic operators. Thus:
     a+b*c < d/f → (a+(b*c)) < (d/f)

    Among these operators >, <, >= and <= have
     the same precedence.

    The == and != operators have lower
     precedence.

    They all have left-to-right associativity.



52223_07/100
   Overview of the C Programming Language - Part 3

                BUG ALERT - Side effects in relational
                            expressions
    Relational operators must cause the compiler to
     evaluate operands from left to right.

    Furthermore, a compiler evaluates only as much of a
     relational expression as it needs to determine the
     result.

    In many cases this means that the entire expression is
     not evaluated. E.g.:

              if (a < b) && (c == d++)




52223_07/101
           Overview of the C Programming Language - Part 3

                                 Cast Operator
    The cast operator enables you to convert a value to a different
     type. Remember that 3/2 gives 1 as a result so (float)3/2
     promotes 3 to a F-P number to ensure that the result of the
     division is not truncated.

    Another use of the cast operator is to convert function
     arguments. E.g. some runtime library functions such as
     pow( or sqrt() expect arguments that are of type double so
     if your variables are integers you need to cast them to double
     before you pass them as arguments:

                
int   j, k;

            
...

            
 
k = (int) pow(2.0, (double) j);

      Note that the cast to int prior to assignment to k is actually unnecessary as
      an automatic conversion of the RH expression of an assignment takes place.
      However, the explicit cast serves as an important documentation aid.

52223_07/102
             Overview of the C Programming Language - Part 3

                        sizeof Operator
    In general, the sizeof operator is used to find the size of
     aggregate data objects such as arrays and structures and is often
     used to aid the portability of code. It accepts two types of
     operands: an expression or a data type.

    An expression is not evaluated but sizeof returns the number
     of bytes that the result occupies in memory:

               sizeof(3 + 5) yields the size of an int

            sizeof(3.0 + 5) yields the size of a double               


    If the operand is a data type then the result is the length in bytes
     of objects of that data type:

        
sizeof(char)           
1 in all implementations

        
sizeof(short) 
2 in some implementations

        
sizeof(int)            
4 in some implementations

        
sizeof(int *) 
4 in some implementations

52223_07/103
         Overview of the C Programming Language - Part 3

                  ?: Conditional Operator
    The ?: operator is the only ternary (3 operand) operator and is
      really just shorthand for a common type of if...else expression:

   
 
            
if (x < y)

   
 
            
      
z = x;

   
 
            
else

   
 
            
      
z = y;

     
can be written as:

   
 
            
z = ((x < y) ? x : y);


    The first operand must have scalar type and the 2nd and 3rd
     operands represent the final value of the expression and these
     must be compatible according to the normal conversion rules.


52223_07/104
        Overview of the C Programming Language - Part 3

                ... ?: Conditional Operator
    This operator can make a statement difficult to read
     and so should be used carefully.

    However, there are situations where it can be used to
     good effect, particularly in printf() statements:

         printf ("...", j > 0 ? j : k);

    
This form avoids the need to generate redundant code
     by duplicating printf()s.





52223_07/105
       Overview of the C Programming Language - Part 3

                     Arrays and Pointers
    Arrays and pointers are closely related in C. 

    An array is a collection of identically-typed variables stored
     contiguously in memory.

    Subscripts into arrays begin at 0, not 1, which means that the
     highest legal subscript is one less than the array's size. 

    The syntax of an array declaration is:


          type
       specifier
                       array
                       name
                                           [             array
                                                          size
                                                                       ]

                                                   initialiser




52223_07/106
       Overview of the C Programming Language - Part 3

                            ...Arrays and Pointers
                   type
                specifier
                                    array
                                    name
                                                      [            array
                                                                    size
                                                                               ]

  Examples:
                                                  initialiser
  int daily_temp [365];

                                                       

  static int powers_of_two [8] = {1,2,4,8,16,32,64,128};

    It is incorrect to enter more initialisation values than
     there are elements in the array.

    If there are fewer initialisation values than elements,
     the remaining elements are initialised to zero. 

    When providing initial values it is permissible to omit
     the array size. For instance:

     
    static char vowels [] = {'a','e','i','o','u'};

52223_07/107
               Overview of the C Programming Language - Part 3

                Pointer Arithmetic - Addition

    C allows you to add and subtract integers to and from
     pointers. For example:
         
 p + 3

    
is legal and causes the address returned to point to 3
     objects after the object that p points to.

    Note that rather than simply adding 3 to p, the
     compiler multiplies (scales) the 3 by the size of the
     object that p points to.





52223_07/108
       Overview of the C Programming Language - Part 3

                     Pointer Arithmetic - Subtraction
    It is legal to subtract one pointer value from another, provided
     that they point to the same type of object. 

    Pointer subtraction yields an integral value that represents the
     number of objects between the two pointers. Examples:

      long      *p1, *p2; int j; char *p3;

      ...

      p2 =      p1   +   4;    /*    legal */

      j =       p2   -   p1;   /*    legal: j = 4 */

      j =       p1   -   p2;   /*    legal: j = -4 */

      p3 =      p1   -   1;    /*    illegal: different pointer types */

      j =       p3   -   p1;   /*    illegal: different pointer types */





52223_07/109
                  Overview of the C Programming Language - Part 3

                               Null Pointer
    C supports the notion of a null pointer   - a pointer that is
     guaranteed not to point to a valid object. A null pointer is any
     pointer assigned the integral value zero. E.g.:

   
 
char *p;

   
 
p = 0; /* make p a null pointer */

    In this one case - assignment of 0 - you do not need to cast the
     integral expression to the integral expression to the pointer type.

    Null pointers are particularly useful in control-flow statements
     since the zero-valued pointer evaluates to false, whereas all
     other pointer values evaluate to true. E.g.:

          while (p) { /*iterate until p is a null pointer*/

               
...

          }

52223_07/110
         Overview of the C Programming Language - Part 3

        Accessing Array Elements Through Pointers
    One way to access array elements is to enter the array name
      followed by a subscript. Another way is via pointers. Given:

   
 
          
      
short ar[4];

   
 
          
      
short *p;

   
 
          
      
p = &ar[0];

     
then

   
 
         
       
*p ≡ ar[0]

    Due to the scaled nature of pointer arithmetic

   
 
          
      
*p+3          ≡     ar[3]

  in fact

    
      
    
      
*p+e            ≡     ar[e]

52223_07/111
        Overview of the C Programming Language - Part 3

      ...Accessing Array Elements Through Pointers
    Furthermore, if an array name is not followed by a subscript
     then it is interpreted as a pointer to the initial element of the
     array. Thus:

                               ar     ≡     &ar[0]

      
Therefore:

                ar[n] is the same as *(ar + n)


    Because of this inter-relationship, pointer variables and array
     names can be used interchangeably to reference array elements.

    It is important to remember, though, that the values of pointer
     variables may change but array names cannot.


52223_07/112
         Overview of the C Programming Language - Part 3

           Differences Between Pointers and Arrays
    An array name is not a variable - it refers to the address of the
     array variable.

    You cannot change the address of variables. This means that an
     array name alone cannot appear on the LHS of an assignment
     statement. This difference between pointer and arrays is an
     important distinction to grasp. For instance:

     p = ar; /*legal: same as p=&ar[0]                         */

     ar = p; /*illegal: you may not assign*/

                   /*to an array address                       */

     &p = ar; /*illegal: you may not assign*/

                   /*to a pointer address */

     ar++;         /*illegal*/

     ar[1]=*(p+3); /*legal*/

     p++;                   /*legal*/

52223_07/113
        Overview of the C Programming Language - Part 3

                Passing Arrays as Function Arguments
    In C, an array name that appears as a function argument is
     interpreted as the address of the first element of the array. E.g.:

     
   x = func(array);                 ≡      x = func(&array[0]);

    On the receiving side, you need to declare the argument as a
     pointer to the initial element of the array. I.e.:

         func (short *ar)
                      func (short ar[])

         {
                                     {

             
...
                          or
     
...

         }
                                     }

         In terms of readability however, the 2nd version may have the
         edge since it emphasises that the object being passed is the
         base address of an array.

52223_07/114
           Overview of the C Programming Language - Part 3

            ...Passing Arrays as Function Arguments

    The choice of declaring a function argument as an
     array or a pointer has no effect on the compiler's
     operation.

    To the compiler ar simply points to a short - it is not
     an array.

    Because of the pointer-array equivalence you can still
     access ar as if it were an array.

    But you cannot find out the size of the array passed as
     the argument by using the sizeof operator on it.



52223_07/115
        Overview of the C Programming Language - Part 3

            ...Passing Arrays as Function Arguments
    Because of this inability to determine the size of an array in the
     called function, it is often a good idea to pass the size of the
     array along with the base address. This enables the called
     function to check array boundaries:

   
 
void foo (int array[], int array_size)

   
 
{

   
 
          
...

   
 
}

    You can obtain the number of elements in an array by simply
     dividing the size of the array by the size of each element:

      foo (demo, sizeof(demo)/sizeof(demo[0]));



52223_07/116
        Overview of the C Programming Language - Part 3

                                    Strings
    A very common use of array is to store strings. A string is an
     array of characters terminated by a null character - '\0'.

    A string constant (literal) is a series of characters enclosed in
     double quotes and has an array of char data type. A compiler
     automatically appends a null character to the string; this means
     it is one character longer than it appears. E.g.:

            static char str [] = "some text";

    If an array size is given it must be long enough to hold all the
     characters including the null. E.g.:

           static char str [10] = "some text";

    A char pointer can also be initialised with a literal. E.g.:

                   char *ptr = "some text";

    This is subtly different from the earlier examples as it
     creates an additional variable for the pointer.

52223_07/117
        Overview of the C Programming Language - Part 3

                    Strings vs Characters
    It is important to recognise the differences between string
     constants and character constants. I.e.:

        char ch = 'a';       /*    1 byte allocated for 'a'            */

        char *ps = "a";      /*    2 bytes allocated for...            */

                             /*    ..."a", plus ? bytes for...         */

                             /*    ...pointer ps                       */

     
It is legal to:

    
 
            
*ps = 'a';    
/* OK */

     
but not:

    
 
            
*ps = "a";    
/* Illegal */

     
Likewise:

    
 
            
ps = "a";
/* OK */

    
 
            
ps = 'a';
/* Illegal */

52223_07/118
       Overview of the C Programming Language - Part 3

            Three versions of a string copy function
   strcopierV1 (char d[], char s[]) {

       
for (int i = 0; s[i]; ++i)

       
 
d[i] = s[i];

       
d[++i] = '\0';

   }

   strcopierV2 (char *d, char *s) {

       
for (int i = 0; *(s + i); ++i)

       
 
*(d + i) = *(s + i);

       
d[++i] = '\0';

   }

   strcopierV3 (char *d, char *s) {

       
while (*d++ = *s++)

       
    ;

   }

52223_07/119
        Overview of the C Programming Language - Part 3

                   Multi-dimensional Arrays
    An array of arrays is declared with consecutive pairs of
     brackets. For instance:

                              int x[3][5]

    Such multi-dimensional arrays are stored in row-major order,
     which means that the last subscript varies fastest. E.g., given
     the above example:

   
 
           
x[0][0] 
x[0][1] 
x[0][2] ...

   
 
           
x[1][0] 
x[1][1] 
x[1][2] ...

   
 
           
...

    If you specify fewer subscripts than there are dimensions, the
     result is a pointer to the base type of the array. E.g.:

    
 
          
x[1] ≡ &x[1][0]

     
The result is a pointer to an int.

52223_07/120
         Overview of the C Programming Language - Part 3

                Initialising a Multi-dimensional Array
    When initialising a multi-dimensional array, you may enclose
     each row in braces - { and }. If there are too few initialisers, the
     extra elements in the row are initialised to zero. So:

   
 
         
static int x[3][5] = {

   
 
         
        
{1,2,3,4,5},

   
 
         
        
{6}

   
 
         
        
}

    Here, only the first two rows are initialised, the second row has
     only the first element initialised. Therefore, the array has the
     following layout: 


   
 
         
1       
2     
3      
4       
5

   
 
         
6       
0     
0      
0       
0

   
 
         
0       
0     
0      
0       
0

52223_07/121
           Overview of the C Programming Language - Part 3

                ...Initialising a Multi-dimensional Array
    The first size specification may be omitted as it can be
      determined by the number of initialisers present.

   
 
int y[][3][2] = {

   
 
            
       
{{1,1},{0,0},{1,1}},

   
 
            
       
{{0,0},{1,2},{0,1}}

   
 
            
       
}

     
results in a 2-by-3-by-2 array because there are 12 initialisers.

    Note that:

   
 
int z[][] = {1,2,3,4,5,6};

     
is illegal since the compiler has no way of knowing whether to
      create a 2-by-3 array or a 3-by-2 array.


52223_07/122
            Overview of the C Programming Language - Part 3

                BUG ALERT - Comma Operator Error

    One of the most common mistakes made by new C
     programmers is to use a comma to separate subscripts:

                      x[1,2] = 0;

    
instead of

                     x[1][2] = 0;





52223_07/123
         Overview of the C Programming Language - Part 3

  52.223 Low Level Programming
        Lecturer: Duncan Smeed


Overview of the C Programming Language

                 Part 4

                     Structures and Unions
    Arrays deal with groups of identically typed variables whereas
     structures deal with groups of mixed types (aggregates). A
     union, another aggregate type, enables you to interpret the same
     memory locations in different ways.

    The elements in a structure, called fields or members, have
     names instead of subscript values. For example:

   
 
struct vitalstat {

     
      
     
char vs_name [19], vs_ssnum [11];

     
      
     
short vs_day, vs_month, vs_year;

     
      
};

     
      
struct vitalstat vs;

    vitalstat is a tag name for a structure template. It
     represents a new, user-defined, data type. Actual variable
     declarations, such as vs, use this tag name.

52223_08/125
         Overview of the C Programming Language - Part 4

                     ...Structures and Unions
    It can sometimes be useful to declare a single structure type
     (without a tag name) when used in one place only as in:

          
struct { ... } vs;

    A tag name and variables can be declared together:

     
      
struct vitalstat {

            
     
...

            
} vs, *pvs, vsa [10]; 

    A final, preferable, method is to define a typedef name. E.g.:

     
      
typedef struct {

            
     
...

            
} VITALSTAT;

    Typically, such structure definitions are placed in a header file
     where they can be accessed by multiple source files. To declare
     a variable using this technique use:
         
VITALSTAT vs;

52223_08/126
          Overview of the C Programming Language - Part 4

                  Initialising Structures

    Structures can be initialised in the same manner as
     arrays - the list of initialisers, enclosed in braces.

    Each initialiser should agree in type with the
     corresponding field in the structure. E.g.:

   
VITALSTAT vs = {

        
"George Smith","002340671",

        
14,10,1954

      };





52223_08/127
     Overview of the C Programming Language - Part 4

                Initialising Specific Members

    The C99 standard allows the explicit association of an
     initialiser with a specific member by prefixing a
     member designator with an equal sign to the initialiser:
      VITALSTAT vs = { .vs_ssnum = "197345678",

        
              .vs_month = 10,

                       1954

       };

    An initialiser with no designator is associated with the
     first member, if it is the first initialiser, or with the
     member that follows the last member initialised.



52223_08/128
      Overview of the C Programming Language - Part 4

                Referencing Structure Members

    There are two methods of accessing structure fields,
     depending on whether you have the structure itself or a
     pointer to the structure.

    Each method uses a special operator.

    Given the structure itself, you can enter the structure
     name and field name separated by the dot (.) operator.
     E.g.:

   
 
        
vs.vs_month 
= 11;

   
 
        
vs.vs_day          
= 21;

   
 
        
vs.vs_year 
= 1988;


52223_08/129
       Overview of the C Programming Language - Part 4

                ...Referencing Structure Members

    The other way to reference a structure member is
     indirectly through a pointer to the structure. Given the
     following declaration:
         
VITALSTAT *pvs;

    To reference a member through the pointer pvs the
     right arrow operator ( >) is used:

                       pvs->vs_day

    This operator is actually shorthand for dereferencing
     the pointer and using the dot operator. I.e.:

            pvs >vs_day ≡ (*pvs).vs_day


52223_08/130
         Overview of the C Programming Language - Part 4

                                 Unions

    Unlike structure members the members of a union all
     share the same location in memory; i.e. all members of
     a union start at the same address.

    Thus, there can be many members, but only one
     member can contain a value at any given time.

    Unions are an easy way for programmers to use a
     location in memory in different ways. 





52223_08/131
     Overview of the C Programming Language - Part 4

                       Defining Union Types
    The definition of a union is formally the same as that
     of a structure. E.g.:

  union [tag_name] {member_declaration_list};

  Example:

        union Data {int i; double x; char s[16]};

          
An object of this type can store an integer, a floating-point
           number, or a short string. Example:

        union Data var, myData[100];

          
Defines var as an object of type union Data, and
           myData as an array of 100 elements of type union
           Data.

    A union is at least as big as its largest member. So:

  sizeof(var) yields 16, sizeof(myData) yields 1600

52223_08/132
          Overview of the C Programming Language - Part 4

                     Initialising Unions

    Unions can be initialised in the same manner as
     structures - with an initialisation list.

    However, this list can contain only one initialiser.

    As for structures, C99 allows the use of a member
     designator to override the default - the first - member
     and specify which member of the union is being
     initialised. E.g.:
     union Data var1 = {77},

                         var2 = {.s="Hello"},

                         myData[100] = {{.d=0.5},

                                                {1}};

52223_08/133
     Overview of the C Programming Language - Part 4

                  Referencing Union Members

    Union member access is the same as structure
     member access.

    However, when the value of a union member is
     changed all members of the union are modified.

    The programmer is responsible for making sure that
     the contents of a union object are interpreted
     correctly. E.g., the following code uses a union to
     illustrate the storage of a double value in memory:
            
var.d = 1.25;

            
for (int i = sizeof(double)-1; i >= 0; --i)

            
 printf("%02X ",(unsigned char)var.s[i]);





52223_08/134
          Overview of the C Programming Language - Part 4

                              Bit-Fields

    Members of structures or unions can also be bit-fields.

    A bit-field is an integer variable of specific bit width.

    Bit-fields may be packed into a single machine word
     giving very compact storage of small units of data.

    Advantage over bitwise operators: handling of bits by
     name.

    The declaration of a bit-field has the form:

        type [member_name] : width ;





52223_08/135
     Overview of the C Programming Language - Part 4

                      Syntax of Bit-Fields

                type [member_name] : width ;

  type

   
An integer type such as int, signed int, unsigned int.

  member_name

   
The name of the bit-field, which is optional. Nameless
    bit-fields serve only as padding to align subsequent
    bit-fields to a certain position in a machine word.

  width

   
The number of bits in the bit-field. A constant integer
    expression whose value is non-negative; must be less
    than or equal to the bit-width of the specified type. 

52223_08/136
        Overview of the C Programming Language - Part 4

                Example of the use of Bit-Fields

    The following example may result in the structure
     struct Date being packed into a 32-bit word:
      struct Date {

         
unsigned int           day           
:     5;

         
unsigned int           month         
:     4;

         
signed int             year          
:     22;

         
_Bool                  isDST         
:     1;

      }

    An object of type struct Date can be initialised in
     the normal way:
      struct Date birthday = {14,10,1954};


52223_08/137
        Overview of the C Programming Language - Part 4

                Restrictions on the use of Bit-Fields

    Unlike other structure members, bit-fields generally do
     not occupy an addressable location in memory.

    Thus you cannot apply the address operator (&) or the
     offsetof macro to a bit-field.

    Also, arrays of bit-fields cannot be declared.





52223_08/138
          Overview of the C Programming Language - Part 4

                    offsetof Macro
    ANSI C provides a method of determining the byte
     offset of any non-bit-field structure member. The
     macro takes two arguments: the type of the structure
     and the member name:
         
offsetof(type,member_name)
     and expands to an integral byte offset of type size_t
     as defined in the stddef.h header file.





52223_08/139
     Overview of the C Programming Language - Part 4


								
To top