How Java Programmers Can Become Dangerous in C in One Evening - PowerPoint PPT Presentation


PPT – How Java Programmers Can Become Dangerous in C in One Evening PowerPoint presentation | free to view - id: 6ad00-MDA1O


The Adobe Flash plugin is needed to view this content

Get the plugin now

View by Category
About This Presentation

How Java Programmers Can Become Dangerous in C in One Evening


This set of s is not at all intended to be an exhaustive ... 'Java is C without the guns, knives and clubs.' James Gosling, creator of Java ' ... – PowerPoint PPT presentation

Number of Views:62
Avg rating:3.0/5.0
Slides: 55
Provided by: D2131


Write a Comment
User Comments (0)
Transcript and Presenter's Notes

Title: How Java Programmers Can Become Dangerous in C in One Evening

How Java Programmers CanBecome Dangerous in C
in One Evening
  • CS405
  • Operating Systems
  • Dennis R. Martin

Some Caveats
  • This set of slides is not at all intended to be
    an exhaustive treatment of C
  • It is, at best, a brief introduction
  • It will, however, help one learn some of the
    rudiments of C, how it is similar to and
    different from Java, and how it can be used to
    write simple programs
  • The reader will need to get and use a good IDE,
    which, it is to be hoped, will handle the tedium
    and mystery of compiling and building C source
  • This tutorial does not teach about compilers,
    makefiles, or IDEs, but it does list some that
    are available on the web, many for free, and many
    quite functional
  • It is also highly recommended that a person get
    one or several good books on C -- they are easy
    to find, and several are listed in the slides
    some are even free
  • They will be absolutely necessary, in order to
    find answers to some or your many questions
  • Because, although I will try to help you get
    started, this set of slides cannot supply all the
  • The best I can do is try to teach you enough to
    become DANGEROUS
  • Good luck

A Little History
  • C was developed in the early 1980s by people
    at ATTs Bell Labs, some of whom had also helped
    developed C
  • Wanted an OO language that would appeal to the
    large following of C
  • Retain as much of C syntax as possible for
    backwards compatibility
  • Retain Cs speed, power, flexibility
  • This means, however, C, like C, has little
    protection for the unwary or clumsy
  • Javas development in early 1990s was quite
  • Originally developed for imbedded applications
  • No pre-existing body of code no compatibility
    issues / considerations
  • Performance less important than developer
  • Simplicity, transportability, safety,
    correctness, documentation, rich libraries
  • A couple quotes
  • Java is C without the guns, knives and
    clubs. James Gosling, creator of Java
  • Java was built as a simple-to-learn subset of
    C for set-top boxes and drooling AOL users.
  • Now, boys and girls, its time to play in
    the big leagues. -- Unnamed website tutorial

Primitive Data Types
  • Primitive data types are similar to Java
  • int, double, float, char, bool (not boolean)
  • Also sometime qualified as short, long, signed,
    or unsigned
  • Classic C strings are arrays of chars the
    chars can also be treated as one-byte ints (with
    a null terminator), so can do arithmetic on them
  • No unicode here
  • Can also change these strings easily copy,
    truncate, concatenate, etc.
  • Can declare constants with the keyword const
    like const int DEFAULTSIZE 20
  • const values and variables cannot be changed
  • const methods cannot change any data inside of
  • C supports the same two styles of comments that
    Java does

General Syntax
  • For the most part, assignment, expressions,
    semicolons, brackets, operators, etc. are similar
    to Java
  • Flow of control
  • if else and switch statements similar
  • Conditionals evaluated for both boolean and
    arithmetic values
  • 0 is treated as false, !0 is treated as true
  • Can also write if(!empty()) instead of
    if(empty() false) or if(entriesLeftToDo)
    instead of if(entriesLeftToDo gt 0)
  • Also, beware if(ab) is legal syntax in C
    (but probably not what you intended i.e., it
    performs assignment, not a conditional check)
  • Solution, put constant on left if(5x) not
    if(x5), since if(5x) will fail
  • Iteration
  • for, while, do while are all similar to usage
    in Java

Simple Terminal I/O
  • Simple I/O is quite a bit simpler in C than in
  • C I/O is based on streams, and when the
    iostreams library is included, one can simply
    write cout ltlt Hi yall ltlt endl instead
    of System.out.println(Hello there, boys and
  • Concatenation in a cout statement is with
    additional ltlts, as in cout ltlt This is the
    value of x ltlt x ltlt and y ltlt y ltlt endl
  • cout is overloaded, so it knows how to print /
    display each primitive data type
  • To read data entered from the kbd (or even from a
    file), use cin gtgt cout ltlt Enter 1, 2, or 3
    // Print the prompt cin gtgt x // Read the
  • This seems an order of magnitude simpler than
    reading from the kbd in Java, although it will
    throw an exception if the type is incorrect (must
    catch and handle)
  • C also supports standard C I/O commands,
    formatting, etc.
  • And as in C, I/O uses stdin, stdout, stderr
    (called cin, cout, and cerr )

Life Outside of Classes
  • With Java, everything must be in a class but
    not so with C
  • This is for compatibility with C, not really to
    promote the use of global functions, data, etc.
  • Globals are just as ugly in C as in Java
  • (But can create them if needed, using the static
  • The following, however, is a perfectly legal C
  • include ltiostreamgt
  • include ltstdlib.hgt
  • using namespace std
  • int main()
  • cout ltlt "Hello all you out there!" ltlt endl
  • return 0

C Classes
  • Both C and Java use classes as an abstraction
  • For encapsulation hiding data and method
  • Usually, the class definition is separated from
    the implementation
  • A header file -- .h or .hpp extension
    implementation in .c, .cc or .cpp file
  • The header file only contains the definition of
    the class, the class variables, and the
    signatures of the methods
  • It can also contain code for inline methods, but
    wont discuss those here
  • The signatures of the methods (prototypes) must
    all be declared before the methods can be defined
    even if not using classes
  • In C, a user of your class (a client) only need
    look at the header file to understand the
    interfaces and how to use the class he/she
    should never need to look at your implementation
    code (in the .c/.cc/.cpp file)
  • In that sense, the header file also provides some
    of the documentation value of simple Javadoc

Header Files and Includes
  • To allow one class to use another class, it must
    include that class
  • include is similar to (but not exactly like)
    Javas import
  • There is no concept of a package in C, so the
    programmer must include the individual classes
    (actually, header files)
  • Both .cpp and .hpp classes can and often should
    include header files
  • At least the implementation of a class must
    include its own header file
  • Two different types of syntax, one for libraries
    and one for class files include
    ltiostreamgt // standard library include
    myclass.hpp // individual class
  • Note no semicolon after an include statement
  • Header files also contain other information
    often best place for them
  • Includes, type definitions, constants,etc.
    include joesClass.hpp define PAGESIZE
    512 const int FRAMESIZE 512 enum
    schedAlgorithmtype FCFS, SJF, RR

Class Levels of Protection
  • Defined in the class definition file (header
  • Similar to, but slightly different from Java
  • Apply to individual methods and data, not the
  • public anyone can see the data and methods (if
    include the class)
  • protected this class and derived classes can
    see data and methods
  • private only this class can see data and
  • There is no package type of visibility, but there
    is something similar
  • Java classes in the same package can see both
    public and protected data/methods
  • Java derived classes can always see protected
    data/methods, even if they are in different
  • In C class can name another class as a friend
    class friend myBuddyClass // Right after
    class header
  • Your friends can see your protected and private

Defining A Class in the Header File
  • class circle
  • public
  • circle(int a, int b, int rad) // Ctor
  • int getX() // Member functions
  • int getY() // or methods
  • int getRadius() //
  • void setX(int newVal) //
  • void setY(int newVal) //
  • void setRadius(int newVal) //
  • private
  • int x // Data members
  • int y
  • int radius
  • // Headers go before each method describing
    everything about it
  • // pre/post conditions, parms, what it does, etc.
  • // (but there is nothing like javadoc to help
    automate this for you)

Implementing a Class in the .cpp File
  • include circle.hpp
  • circlecircle(int a, int b, int r) // Ctor
  • x a
  • y b
  • radius r
  • int circlegetX() // Implementation of
  • return x
  • int circlegetX()
  • return y
  • int circlegetRadius()
  • return radius
  • void circlesetX(int newVal)
  • x newVal

  • Concepts of inheritance, containment, etc. are
    similar to Java
  • Subclasses inherit all data and methods from
  • However, subclasses cannot see or use private
    methods and data
  • Of course, subclasses can add data and methods,
  • Can also overload methods, provide
    implementations of virtual functions, etc.
  • But do not strengthen preconditions or weaken
  • Definition syntax looks like this
  • class shape class circle public shape
  • public public
  • shape(int a, int b) circle(int a, int b,
    int rad)
  • int getX() int getRadius()
  • int getY() void setRadius(int newVal)
  • void setX(int newVal)
  • void setY(int newVal) private
  • int radius
  • private
  • int x

Constructors and Destructors
  • Constructors in C are similar to ctors in Java
  • Perform class initialization
  • May be overloaded
  • Run in order from base class through derived
  • Java, of course, does not use explicit
    destructors C does
  • Java performs garbage collection, a major
    function of dtors, automatically
  • Java objects can have a finalize() method to
    close files and perform cleanup (sometime), in
    addition to garbage collection
  • Destructors are more important in C
  • Must make sure all allocated storage is released,
    plus do other cleanup
  • Run in order from derived classes up through base
  • Are more predictable in how they behave than
    Javas finalize()
  • When a C dtor runs, the object is truly
  • finalize() can run any time after object is no
    longer used

Creating Non-primitive Objects
  • In Java, the only way to create non-primitive
    objects is with new circle smileyFace new
  • In C, objects can be created on the stack,
    just like primitive data types (int, char, bool,
    etc.) circle smileyFace(1,2,3)
  • C objects can also be created with new, but
    then storage is allocated from the heap, and a
    pointer to the object is returned circle
    smileyFace new circle(1,2,3)
  • The two types of objects must invoke their
    methods differently
  • smileyFace.setRadius(5) // The 1st actual
    object smileyFace-gtsetRadius(5) // The 2nd
    ptr to object
  • More on pointers and storage allocation (and
    deallocation) later

Simple File I/O
  • Also based on streams must include ltfstreamgt
  • ifstream is for input ofstream is for output
  • To copy data from one file to another, do
    something like the following
  • include ltfstreamgt //
    Assume already have filenames
  • // in
    infileName, outfileName
  • ifstream infile // Declare files
  • ofstream outfile
  •, iosin) // Open input
  • if( // Handle error
  • cerr ltlt Unable to open input file ltlt
    infileName ltlt endl
  • exit(1)
  • // Then open output file
  •, iosout) // Do
    similar validation
  • char c
  • while(infile.get(c)) // Copy file a char at a
  • outfile.put(c) // Will fail at EOF
  • infile.close() // And close both files
  • outfile.close()

Simple File I/O Delimiters
  • If have a series of ints separated by blanks, or
    each on a separate line, can read the file into
    an array like this
  • This is all an order of magnitude simpler than
    the same thing in Java
  • include ltfstreamgt
  • // assume already have filenames
  • int myarraysomeLargeNumber // Create array to
    read ints into
  • ifstream infile // Declare the file
  •, iosin) // Open it
  • if( // Handle error
  • cerr ltlt Unable to open input file ltlt
    infileName ltlt endl
  • exit(1)
  • int x
  • int numElements 0
  • while(infile gtgt x) // Just use right shift to
    read int
  • myarraynumElements x // Will skip white
    space and fail when EOF
  • infile.close() // Close file
  • return numElements

  • Java has no pointers for several reasons
  • Pointers are a major source of confusion and bugs
    in C and C
  • Pointers would/could have required users to be
    more responsible for storage management, rather
    than rely on Javas garbage collection
  • Pointers could be used to circumvent Javas
    runtime security checks
  • Instead, Java uses references (not to be confused
    with C references), which are like safe
    pointers managed by the system
  • This means Java does not support or allow such
    things as
  • Pointer arithmetic
  • Casting object or array references to integers
    (or vice versa)
  • Computing the size of primitive object types in
    number of bytes
  • Direct manipulation of pointers or memory
    addresses of any sort
  • Of course, C allows all of those things, and
    more, so you need to learn to understand and use

What Are Pointers, Anyway?
  • A pointer is the memory address of an object,
    data, code, etc.
  • In C, either a primitive type or an object can
    be instantiated without using new
  • In Java, all non-primitive data must be
    instantiated with new
  • When a primitive type or an object is
    instantiated without using new, like this
    myObject objectInstance it is created on the
    processs stack
  • Then the object methods are invoked using the
    dot syntax, like this objectInstance.setData(x)
    // Using the REAL object
  • When a primitive type or an object is created
    with new, it is allocated from the heap, and new
    returns a pointer to the data/object, like this
    int x new int or myObject objectInstance
    new myObject
  • Then the object methods are invoked using
    pointer syntax, like this objectInstance-gtsetDa
    ta(x) // Using a POINTER to object

What Do and Mean?
  • Both and have double meanings, when used
    with pointers
  • In a declaration, the indicates that the
    variable is a pointer to the type, not the type
    itself, as in char mystring
  • However, the is also used immediately before
    a pointer variable to dereference it to
    retrieve the value/object the pointer is pointing
    at, not the value of the pointer itself
  • If int a and int x, then x a is
    illegal, but x a is valid
  • Never dereference an uninitialized ptr, a NULL
    ptr, a deleted ptr, or a dangling ptr
  • The is used to get the pointer to data or an
    object, like this x
  • So, if int a and int x, then a x copies
    xs pointer to a
  • int intptr
  • int myint, yourint
  • myint 1
  • intptr myint // intptr points to myint
  • yourint intptr // dereference intptr and
  • // assign value to yourint

But What Else Does Mean?
  • The is also used to indicate a variable is a
    reference to an object
  • It can be thought of as a special kind of pointer
  • A reference is like an alias for an object
    another name/symbol for it
  • A reference must be initialized when created
    (like a constant)
  • All operations applied to the reference act on
    the object being referenced
  • Primary use of a reference is as an argument or
    return type for a function, especially when
    applied to user-defined classes
  • Ordinarily parameters are passed by value i.e.,
    a copy is passed so that if the method changes
    its copy of the data, the original is not changed
  • To change the original data or object itself,
    must pass the method a reference or ptr
  • Advantage of using a reference, is that do not
    have to use pointer notation within the function,
    and do not have to do anything special on the
    invocation of method
  • Can declare a reference const if want to
    guarantee it is not changed by mistake
  • i.e., wish to use the object, but make sure the
    reference to it is not changed
  • This is why we care
  • Must use ptrs or refs to pass objects/data to

Examples Parms with and
  • Swap function using Pointers
  • swap(x,y) // method invoked somewhere in
  • void swap(int val1, int val2) // swap
    function by value (ptr)
  • int tmp val2 // i.e., the ptr was value
  • val2 val1
  • val1 tmp
  • Swap function using References
  • swap(x,y) // method invoked somewhere in main
  • void swap(int val1, int val2) // swap
    function by reference
  • int tmp val2 ///////////////////////////////
  • val1 tmp //
  • // void swap(int val1, int val2)
  • // int tmp val2
  • // val2 val1
  • // val1 tmp

But Arrays Are Different
  • In many ways C arrays look and act like Java
  • Arrays are zero-based, and individual elements
    are referenced like this
  • int myArray20
  • for(int i 0 i lt 20 i)
  • myArrayi i
  • However, C does not check array bounds like
    Java does.
  • If you try to go off either end of the array, C
    will accommodate you
  • If you try to read garbage off either end of the
    array, or if you try to write over memory outside
    of the array, C will cheerfully let you and
    will not even warn you
  • You must learn to take care of yourself(Look
    before you cross the street your mother is not
    holding your hand)

Other Differences In Arrays
  • When an array is instantiated, the variable
    actually holds a pointer to the first element in
    the array, and the array name without the
    brackets, can be used like a pointer
  • int myArray20
  • myArray0 5
  • cout ltlt myArray // Will print out 5
  • The size of an array must be declared when the
    array is created on the stack, as in this syntax
    int intArray10
  • If the size of the array will not be known until
    runtime, the array can be declared with new, like
  • int intArray new intsize
  • // OR
  • int intArray
  • intArray new intsize
  • Note that new always returns a ptr
  • It is even possible to do something like this (a
    C-ism) int intArray
    // Allocate ptr intArray (int)
    calloc(10, sizeof(int)) // Allocate array
  • intArray5 17 //
    And use it

Pointer Arithmetic and Arrays
  • Pointers to arrays are smart
  • Since a pointer to an array points to the 0th
    element of the array, when an array pointer is
    incremented or decremented, it is incremented or
    decremented by the size of an element in the
  • This means it is possible to walk through an
    array like this
  • int aSIZE // Create an array
  • int i a // i is a pointer to the 0th
  • int limit a SIZE // and a ptr to the last
    element 1
  • while(i lt limit) // Loop through the array
    using ptrs
  • cout ltlt i // Dereference each element and prt
  • i // bump ptr to next element
  • // can do same thing with floats, objects, etc.
  • Can also refer to 5th element of array by
    something like
  • x (a4)

Arrays as Parameters
  • The ptr to the array is also automatically passed
    on a function call
  • int myArray new intsize
  • // fill array here
  • sort(myArray, size)
  • void sort(int a, int length)
  • // could also code as void sort(int a, int
  • // perform sort here includes code something
  • // for (int i 0 i lt length i )
  • // if(ai lt ai1) . . . etc.
  • However, arrays are not self-defining, so a
    method cannot tell the length of an array from
    its pointer
  • This can make passing array ptrs somewhat
    dangerous (for the clumsy or unwary) must
    always pass a length, too
  • If a smart, safe array is needed, then use the
    vector class from the standard template library

Multi-Dimensional Arrays
  • In Java, a 10x10 array of ints can be created
    like this
  • int twoDimArray new int1010
  • In C, the new is not required, although it
    could be used with ptrs
  • int twoDimArray1010 // Dimensions must be
  • int twoDimArray new int1010 // All
    dimensions except
  • // first must be constants
  • Arrays are allocated in row-major order (one row
    after another, in order, in memory) -- they can
    be initialized when instantiated any of these
  • int a43 int a int a43
    // OR EVEN
  • 0,1,2, 0,1,2,
    0,1,2,3,4,5,6, // LIKE THIS
  • 3,4,5, 3,4,5,
    7,8,9,10,11 int a
  • 6,7,8, 6,7,8,
  • 9,10,11 9,10,11

  • 8,9,10,11
  • Since multidimensional arrays are treated like
    one large block of storage, one can also access
    a2,2 above by a8
  • Can have as many dimensions as you want or need
    (not limited to 2 or 3)

Arrays of Pointers
  • Besides arrays of primitive data types or arrays
    of objects, one can also have arrays of pointers
    to other data types or objects
  • This is especially useful if the array elements
    are anything more than primitive types and / or
    if the array elements could be different sizes
    (e.g., an array of strings of different lengths)
  • Also, for sparse arrays of large objects, the
    storage for the objects would not have to be
    allocated until the array element was filled
  • Happens in OSs all the time it is much cheaper
    to copy ptrs around than to copy large objects
  • Arrays of pointers could be declared either of
    these two ways
  • pcb PCBptrMAXPCBs // On the stack - or
  • pcb PCBptr new pbcMAXPCBs // On the
  • Of course multiple levels of indirection are
  • This can be quite useful and common in operating
    system data structures / objects
  • Pointers to pointers are dereferenced just like
    ordinary pointers, etc.

Memory Management
  • Like Java, C allocates storage off the heap
    with new
  • In Java, all non-primitive data types have to be
    allocated with new, and primitive data types
    cannot be allocated with new
  • int myFavoriteInt but myObject
    myFavoriteObject new myObject
  • In C, any data type can be allocated either
    with new or without new
  • The difference is
  • When new is used, it allocates the data/object
    off the heap and returns a pointer to it i.e.,
    the variable name actually refers to a pointer to
    the object
  • When new is not used, the data/object are
    allocated on the stack, and the variable name
    refers to the actual object
  • Both of these affect the way the data/object is
    handled, used as a parameter, etc.
  • int myFavoriteInt // These refer to the
  • myObject myFavoriteObject // actual data or
  • int myFavoriteInt new int // These refer to
  • myObject myFavoriteObject new myObject // to
    the data or object

Memory Management Theres More
  • Objects created on the stack (without new) are
    destroyed automatically when they go out of scope
  • Do not try to destroy these explicitly, unless
    you want to crash your program.
  • However, objects created with new (from the heap)
    must be destroyed explicitly, or they live
    forever, even after the program that created them
    is gone
  • This is called a memory leak memory leaks are
    bad they can eventually tie up significant
    amounts of memory on the system and cause big
  • So, any data / object created with new MUST also
    be destroyed with delete
  • This can become complex when objects are created
    and destroyed in different places in the code
    (especially if created / destroyed by different
  • It can also become challenging in complex
    objects, made up of other complex objects, all of
    which were also created by new

Using delete
  • Any data/object should be deallocated in the same
    block it is allocated, if possible must also
    consider and handle abnormal exits, exceptions,
  • One important function of the destructor is to
    make sure that all storage allocated for an
    object is deallocated (especially true for
    composite objects)
  • For example, in something like a queue,
    implemented by a linked list, made up of a number
    of nodes, each of which were allocated with new,
    the dtor must
  • queue() //dtor
  • while(head ! NULL)
  • dequeue()
  • // dequeue method
  • void dequeue() // Would return actual data
  • // get valueToReturn from node
  • queueNode nodeToDequeue headptr
  • headptr headptr-gtgetNextPtr()
  • delete nodeToDequeue // Here deallocate the
  • --numElements
  • return valueToReturn

new and delete With Arrays of Objects
  • When the operators new and delete are used with
    arrays of objects, interesting things will happen
  • myType mine new myType100 creates an array
    of 100 identical objects of myType, all created
    by the default ctor or a ctor with no parms
  • It returns a pointer to the array, which is also
    a ptr to the first object in the array
  • The objects could each then be initialized one at
    a time.
  • To create an array of individual (not identical)
    objects, create an array of pointers to the
    object type, and then invoke new for each pointer
    (however, must use different syntax with this
    array, since it is an array of pointers)
  • myType mine new myType100
  • for(int i 0 i lt 100 i)
  • minei new myType(myparms)
  • When deleting an array of objects, delete
    myarray will just delete the first element of
    the array, and leave the others alone (causing a
    memory leak)
  • To delete the entire array, use this syntax
    delete myarray
  • To delete the array of pointers and the objects
    they are pointing at
  • for(int i 0 i lt 100 i) // First delete the
  • delete myarrayi // one at a time
  • delete myarray // Then delete the array

C Strings Are Arrays of chars
  • Original C (and C) had no string class, like
    Java does
  • C/C strings are arrays of chars, terminated
    with a NULL (\0)
  • However, unlike Java strings, C strings can be
    altered, copied, or changed as much as you want.
  • Often strings are referred to with chars, and
    the actual strings allocated with news
  • Strings can also be initialized with constants
  • char months Jan, Feb, Mar, Apr,
  • May, Jun, Jul, Aug,
  • Sep, Oct, Nov, Dec
  • Since these are char arrays, they cannot be
    concatenated with , copied with , or compared
  • Must use strcat(), strcmp(), strcpy(), strlen()

Strings in the C Standard Library
  • Newer versions of C have a string type,
    include ltstringgt similar to Java strings, but
    with several differences
  • C strings store ASCII characters, not Unicode
  • C strings can be modified, Java strings cant
  • C strings can be concatenated only with other
    strings, not with arbitrary objects. The plus
    sign, , is used for concatenation.
  • Strings can be compared using normal relational
    operators, like ! lt gt lt gt
  • Actually more convenient than using equals() and
    compareTo() in Java
  • // This little example doesnt do much useful,
    but shows
  • // several useful functions in action
  • string s1(abc) // Initialization
  • string s2 abc // Initialization
  • if(s1 s2) // Comparison
  • int k s1.size() // size() function
  • for(int i 0 i lt k i)
  • s2i s2ii // Assignment
  • cout ltlt s1 s2 ltlt endl // Concatenation,

  • In some ways, C templates are similar to Java
    container classes
  • They define a group of abstract classes that may
    be instantiated as containing a data type or
  • They provide many useful functions, depending on
    the container type
  • The templates include things like vector, list,
    stack, queue, deque, map, set, etc.
  • They are described in books on the STL (Standard
    Template Library) or on the standard C library
    (which contains many more classes/types)
  • Example vector it is like an array, but use
    like this
  • vector ltintgt v(10) // Declare vector of ints
  • for(int i 0i lt 10 i)
  • vi i // access elements like an array
  • cout ltlt v.size() // vs size is 10 is
  • v.resize(v.size()2) // extend or truncate
    with resize()
  • vector ltintgt v2 v // assign entire vector
  • if(v v2) // compare entire vector
    with , etc.
  • vector ltchargt mymethod() // can return vector
    from method
  • void myMethod(vector a) // can pass as parm
    either by value
  • void otherMethod(vector b) // or reference

Libraries and Utility Functions
  • Unlike Java, most C utilities do not exist in
    separate packages, classes, or namespaces
  • Instead, C, like C, uses libraries of global
    functions to provide those services
  • The libraries are header files, which are
    included in a program to make the functions
    available for use
  • Some of the most commonly used libraries are
  • include ltstdio.hgt -- Cs standard I/O library
    (Cs is iostreams)
  • C-type console and file I/O and I/O formatting
  • include ltmath.hgt -- the C math library
  • Trigometric functions, exponentials, powers,
    roots, etc.
  • include ltstring.hgt -- the C string library
  • Copies, appends, compares, searches, tokenizes,
    etc. standard C/C strings
  • For documentation of libraries (and other
    functions) consult a good C book, check your
    IDEs help, or look at man (short for manual)
    pages, invoked from a command line like this
    man cos

  • Exception handling in C looks similar to Java,
    except that it is not quite so neat
  • Exceptions are monitored within a try block
  • Following the try block, are one or more
    catch() blocks
  • There is no finally in C, as there is in
    Java all cleanup must occur in the catch blocks
  • try
  • // code goes here
  • catch(oneKindOfException) and handle it
  • catch(anotherKindOfException) and handle it
  • // all others fall through to higher level
    exception handlers
  • There is no Exception class in C like there
    is in Java
  • Some classes have their standard sets of
    exceptions, but really, anything can be an
    exception, and it does not even have to be
  • throw(Oh, mgosh!!!) // Is perfectly legal
  • As with other exceptions, this line simply
    transfers control to the next higher level
    exception handler, with the exception as an
  • If that handler is not monitoring for this
    specific exception, then the exception continues
    to bubble up through higher level exception
  • If it is never handled, the default exception
    handler will abort the program
  • Exception handlers can also throw the same or a
    different exception to higher level handlers (so
    the exception can change while being handled)

Some Simple Data Structures
  • See accompanying code for examples of
  • Stacks
  • Queues
  • Linked lists
  • Memory management
  • Parameter passing
  • Arrays of pointers to variable-length strings
  • And more

A Brief C Bibliography
  • Use these for starters
  • Stroustrup, Bjarne. The C Programming
    Language, 3rd ed. Addison-Wesley, 2000.
  • Budd, Timothy. C for Java Programmers.
    Addison-Wesley, 1999.
  • Lippman, Stanley B. C Primer, 4th ed.
    Addison-Wesley, 2005.
  • Prata, Stephen. C Primer Plus Teach Yourself
    Object-Oriented Programming, 5th ed., 2004.
  • Dietel, H.M. and P.J. Dietel. C How to
    Program, 5th ed. Prentice-Hall, 2005.
  • Cline, Marshall and Greg Lomow. C FAQs, 2nd
    ed. Addison-Wesley, 1998
  • Many free electronic books are available online
  • Lists many books and other free things
  • Eckel, Bruce. Thinking In C, 2nd ed., 2003.
    http// (use the index)
  • He also has a Thinking in Java, Thinking in
    Enterprise Java, Thinking in Patterns, Thinking
    in Python, etc.
  • This is quite good a C/C reference also
    includes templates, strings, etc.
  • Standard Template Library reference online
  • Quick reference site and other ebooks
  • Examples of more advanced books
  • Myers, Scott. Effective C 50 Specific Ways
    to Improve Your Programs and Designs, 3rd ed.
    Addison-Wesley, 2005.
  • Also by the same author, More Effective C,
    Effective STL

Some Potential IDEs and Resources
  • List of free C compilers (also free online doc,
    books, etc.)
  • http//
  • Site has lists of free compilers for many
    languages, plus lots, lots, lots more
  • Eclipse is also quite good for Java,
    (http//, and recently has become
    much easier to use for C
  • The C environment requires installing either
    MinGW or Cygwin.
  • Directions are on the class web pages
  • In the past, I have used the Dev-C compiler,
    because it is very simple to set up and use, and
    is based on the GNU compilers I have v4.992
  • http// or
  • This site also contains a list of other free
    compilers of all types
  • Much good info in the forum, too
  • For debugging, compile with compiler options g3
    O0 (tools-gtcompiler options-gtcompiler)
  • If you want a standalone editor, to use with a
    standalone compiler that you already have, or
    with Java, I like JEdit (http//

Some Useful Links from the Dev-C Forum
  • Good link to a LARGE number of online books and
    tutorials http//
    ng.htmlAnother link with a lot of compilers
    interpreters and other resources (and tutorials)
    with downloadable programs, many of which are Dev
    utorials.htm(Posted by Zero Valintine)http//ww
    comp.lang.c Frequently Asked Questionshttp//ww
    Programming Tutorialshttp//
    m/tutorial.htmlTed Jensen's Tutorial on
    Pointers and Arrays in Chttp//
    jensen/ptr/GNU Manuals Online (GCC, Make,
    GlibC, etc)http//
    quick reference site (Quick reference cards and
    ndexe.htmlIncompatibilities Between ISO C and
    ISO Chttp//
    C Referencehttp//
    Language Tutorialhttp//
    utorial/index.htmlC FAQ LITEhttp//www.paras (Tutorials,

Microsoft Developer Network (MSDN, The source
for WinAPI)http//www.msdn.comMicrosoft
Platform SDK Download and Updatehttp//www.micro
rDoos (Win32 GUI programming, C)http// theForger's (Win32 GUI
Programming, C)http//
quently Asked Questions about Win32
ae/CodeNote/WinAPIfaq.htmlBeej's Guide to
Network Programminghttp//
beej/guide/net/Winsock Programmer's
FAQhttp// Art of
Assembly and High Level Assembly
(HLA)http// Assembly
Language by Dr. Paul A. Carter (HOT)http//www, The Netwide
programming example/homeworkhttp//sourceforge.n
Forgers Win32 Tutorial http//
A Few Extra Things
The Preprocessor / Macro Processor
  • Before the real compiler begins to compile your
    code, a preprocessor makes a pass through the
  • The preprocessor performs simple text
    substitutions, according to preprocessor
    commands, which begin with a
  • C used the preprocessor heavily, and although
    Cs goal is to rely on it less, there are still
    some scenarios where it is quite helpful or
  • You have seen some of them before. The total
    list looks like this
  • include statements
  • define statements
  • Conditional compilation
  • Avoiding circular includes
  • Forward declarations

include statements
  • An include statement allows you to include the
    contents of one file in another (typically what
    is being included is a header file)
  • If the name is enclosed in lt gt brackets, the
    preprocessor will search for the file in a
    standard list of directories (the standard search
    path, similar to a classpath)
  • If the name is enclosed in quotes , the
    preprocessor will search the current directory,
    plus the standard search path
  • include ltstdio.hgt // An old C file uses .h
  • include ltiostreamgt // A C library no .h
  • include myClass.h // User file uses .h, .hh,
    or .hpp
  • Some reasons to include a file are
  • When creating an instance of a class
  • When invoking a member function on an instance of
    a class
  • When accessing a public instance variable of an
    instance of a class
  • When accessing a static function or member of an
    instance of a class
  • When defining methods for a class (i.e.
    myclass.c must include myclass.h)
  • When the class being declared is a subclass of
    the class

define statements
  • Directs the processor to do text substitution
    (note no semicolon)
  • define TRUE 1 // Declares C style constants
  • define FALSE 0 // In C write const int FALSE
  • define DEBUG // Defines a symbol to be used
  • Can be used to create macros and define complex
  • Can be quite powerful, but also error prone
  • Common in C, but considered bad style in C --
    try to use objects instead
  • Example define min(a,b) (((a) lt (b)) ? (a)
  • Later, in the code, the programmer can write
    min(i,4) which is expanded in the code to (((i)
    lt (4)) ? (i) (4))
  • At runtime evaluates to i or 4, whichever is less
    provides min() function
  • Also, since is expanded by preprocessor, it is
    inlined no function call
  • Macros or constants can also be undefined with

Conditional Compilation
  • In C it is possible to define a symbol, either
    with a define or often on the invocation line of
    the compiler ( with DDEBUG, etc)
  • Whether or not that symbol is defined can trigger
    whether a section of code will be compiled or
    not, using ifdef, ifndef, else, endif
  • This provides conditional compilation, depending
    on what is defined, which allows code that
    supports different platforms to be combined in
    the same file, and the correct code be compiled
    according to which platform is defined. It also
    allows debug code to be turned on and off.
  • define FOR_MICROSOFT define DEBUG
  • ifdef FOR_MICROSOFT ifdef DEBUG
  • // grungy gorp goes here // debug code
  • endif // goes here
  • ifdef FOR_LINUX endif
  • // better stuff goes here // normal
  • endif // goes here

Avoiding Circular Includes
  • In general, things cannot be defined twice in C
  • This means files cannot include each other
  • That could happen by mistake in large, complex
    projects with many includes could even result
    in infinite recursion or compile failures
  • Use conditional compilation to avoid the problem,
    like this
  • // In myclass.h, at the very beginning put this
  • ifndef myclass_Header
  • define myclass_Header
  • // All of the class definition in the header
    file goes here
  • endif // Put as the last line of the file or
    have bad problems
  • The first time the file is included,
    myclass_Header will be undefined, so the
    preprocessor will define it and the class
  • The next time the file is read, myclass_Header
    will already be defined, so the body of the
    header file will be skipped

Forward Declares
  • But what if one class NEEDS to know about another
    class, and that second class also NEEDS to know
    about the first class ???
  • How can they include one another and still avoid
    circular includes?
  • The answer is, they dont necessarily NEED to
    include one another
  • All they need is a forward declaration, if all
    they do is refer to the class (e.g., declare a
    ptr or variable of its type, which is usually the
  • That is done with a line like this in the header
    file, before the actual class declaration begins
  • class myOtherClass // The class I need to refer
  • class thisClass
  • // body of thisClass declaration goes here
  • In general, use forward declarations in header
    files and includes in .c files, for simplicity
    and to speed up compilation

Copy ctors
  • If a class needs a destructor, it also need a
    copy ctor and operator
  • A copy ctor is called automatically when an
    object is created based on another object, and
    needs to be initialized as a copy of the existing
  • The original object is passed as a parameter
  • myObjectmyObject(const myObject o) // is the
  • myObject o1 //
  • myObject o2 o1 // This
    requires copy ctor
  • If a copy ctor is not defined, a default one will
    be generated and used
  • This often is bad, because it just produces a
    bit-wise copy (shallow copy)
  • That means ptrs, etc. are just copied from one
    object to another, creating duplicate ptrs, which
    can lead to trouble later, when the object is
  • A copy ctor should be defined, which will build a
    completely new object (deep copy)
  • Copy the values of all non-ptr data members
  • For ptr data members, create new data objects and
    copy the old ones into them (recursively, if

Operator overloading - operator
  • In C one object can be copied into another with
    the operator
  • instance2 instance1
  • By default, however, this is just a bit-wise,
    shallow copy, resulting in problems similar to
    those resulting from using the default copy ctor
  • To avoid those problems, the operator can be
    overloaded to provide a deep copy myObject
    myObjectoperator(const myObject o)
  • Then, when instance2 instance1 is written, the
    operator function will be called, and the object
    will be copied correctly
  • operator is different from a copy ctor in three
    important ways
  • The object being assigned to has already been
    initialized therefore, if it contains ptrs, the
    storage must first be freed up to prevent memory
  • It is legal syntax to assign a variable into
    itself, e.g., v1 v1 therefore, the operator
    code must check for this case and do nothing
  • The operator function must return a value

Overloading Other Operators
  • operator
  • Provide a comparison of the contents of two
    instances of a class/object (similar to .equals()
    in Java)
  • Otherwise, there will be just a bitwise
    comparison need deep comparison
  • bool myObjectoperator(const myObject o) //
    member function
  • // then can write if(obj1 obj2) //
    OR as free function
  • bool operator(const myObject o1, const
    myObject o2) // free fnct
  • operatorltlt
  • Allow an object to format and print itself into
    an ostream (similar to .toString() in Java)
  • Must be defined as a free function (because
    output is an ostream), not as a member function
    of the class
  • ostream operatorltlt(ostream out, const myObject
    o) /code here?
  • // then can later write cout ltlt myObject
  • Can also overload other operators, such as , -,
    , , ,
  • The compiler only provides a default function for
    operator (assignment), if others are needed,
    they must be coded

Unions and Structs
  • unions and structs are non-OO carryovers from C
  • In some ways, they are like simple, dumb objects,
    with no methods
  • They are just containers for data structures
    for records in a file
  • A struct defines a type that contains several
    pieces of data
  • That data type can later be used to declare
    variables of that type
  • struct Address struct Student
  • char street20 int ID
  • char city20 bool graduated
  • int zip Address addr
  • Student s1, s2 // Declared two variables of
    type Student
  • 12345 // Accesses/sets the field
  • In general, use simple objects, not structs
    although you may see them

More on Unions
  • structs are often used to map the format of
    records in large files
  • In such situations, space is often at a premium
  • Since the records must all be the same size,
    space is often wasted
  • And it is desirable to waste as little space as
  • unions provide a way to save space by remapping
    bytes within a struct, depending on how the
    struct and union are being used
  • The code must know how the union is being used
    (explicitly / implicitly)
  • struct symbolTableEntry
  • char name
  • char type
  • union
  • char stringVal // used if type s
  • int intVal // used if type i
  • Can also access members of structs / unions with
    ptr notation
  • symbolEntryTable e e-gttype s

Additional Potential Topics
  • The this pointer
  • casts, and accessing superclasses
  • Inlining
  • Use of const, const correctness, and when to cast
    away constness
  • Virtual functions
  • More on inheritance and classes in general
  • Abstract base classes
  • Ptrs to functions
  • void ptrs
  • Namespaces
  • Assertions and other debugging techniques
  • Default arguments
  • Typedefs