Thursday, May 22, 2014

Wk3-Mtg2 - II-10 Pass by Reference*, II-11 Structs*, II-12 The Heap

Review: (No homework to review from last session)

However, we did recap some earlier material in preparation for starting this meeting.

II-10 Pass by Reference*

We learned a number of key points about why we pass by reference as opposed to passing by value:
  • Passing a reference to an item with always consume less memory as we are only passing a pointer to an item, not a copy of the entire item.
  • Passing a reference to an item is used as a means to point to a place for the called routine to place an answer.
  • More than one return value can be returned from a called routine when pointers are passed as parameters to the called routine, whereas there can only be a single return value from the called routine.
  • Use detection of the NULL value of a pointer to determine when nothing is currently being pointed to.
This is a short section but there is a lot here for discussion ...reviewing how parameters are passed relative to our earlier call-frame discussion helps us to understand how pointers are created automatically when passing items by reference.  Therefore, as we are learning to read C (and even Objective-C) we need pay more attention to subroutine calls to help remind ourselves what is really expected of the routine being called and how it actually gets the data it uses.

*Challenge({no-name})

This was intended to be a simple replacement of a couple of lines of code with one [code should use modf() in place of floor()].  However, it turned out to be difficult to see exactly what the change was to be and where it was to be made.  We reviewed the code that was using floor() and then together changed it to use modf() instead.  It took a bit of discussion but we did figure it out! We noticed that the use of modf() actually reduced the amount of code needed to solve this problem!

II-11 Structs*

We studied how to define structures, how to allocate variables which contain the structures and then how to access the individual elements of the structures.
struct {structName} {   // declaration
    datatype element1;
    datatype element2;
    ...  etc. ...
};

struct {structName} {variableName};   // allocation
{variableName}.element1 = value;     // assignment to element

We reviewed the use of typedef to declare new type-names so that we can use them as if they were built-in types.
typedef {oldTypeName} {newTypeName}; // declare new type
Let's use this typedef to make it easier to use structures in our code.  We can make structures look like built-in types by using a typedef.  To do so, we want to assign a name to be used in place of "struct {structName}" the statement would look like:
typedef struct {structName} {newTypeName}; // declare type to use
...which then results in assignment code that looks like:
{newTypeName}.
element1 = value;     // assignment to element
This is much more simple, right?  Right!  Let's remember to use this form in our code!

Then we talked of another means to define structure types as new built-in types.  The following shows an anonymous (no name given) structure used to declare new type:
typedef struct {   // declaration
    datatype element1;
    datatype element2:
   ... etc. ...
} {newTypeName};   // ... as new type

NOTE: This technique is more a "college-level reading" style of writing code in that we have to remember that the structure name is missing from this code.  Instead, we are temporarily defining an anonymous structure and then giving this anonymous struct a name, real quick!  If you are trying to remember the parts of the language through repetitive-use this would not be a technique that would help you learn, nor remember the parts of the language you are using!!!


*Challenge({no-name})

We went over the challenge identifying what was really needed to get the job done.  We identified what variables we had, what units we needed to work in.  Then we added the 4M math part and lastly added the display (and conversion for display) of the appropriate elements of the TM struct.

II-12 The Heap

We talked of allocating blocks of memory so we could use them across many subroutines of our code.  Not only do we allocate but we must then free the memory region after use.  We use pointer datatypes to keep track of our memory allocations.  The typical pattern is:
dataType *ptrToType = malloc(sizeof(dataType));  // allocate an instance of dataType from pool
 
// (use type instance)
 
free(ptrToType); // return memory to pool
ptrToType = NULL;   // mark as no longer pointing!
Now, let's look at the use of our new complex types when allocated from the heap!
typedef struct {
  // declaration
    datatype element1;
    datatype element2;
   ... etc. ...
} {newTypeName}; // ... as new type
newTypeName *ptrToType = malloc(sizeof(newTypeName)); // allocate an instance of type from pool
 
// use type instance
 
ptrToType->{elementName}; // use indirection to get to element within complex type
ptrToType->element2 = valueB;
free(ptrToType); // return memory to pool

ptrToType = NULL;   // mark as no longer pointing!
Lastly, we discussed the very general organization/use of memory within our system from a programmers point of view:

Operating System (os)
Application
Stack
Heap

(This is overly simple but help us remember what's involved)

We ended the session with a discussion of nearby concepts; remembering that this is always a game in that (no matter how much memory our computers have) we are still trying to keep the Heap from running into Stack (they grow towards each other) and thus avoid a bad application crash!

Homework: none identified.  Looking forward to starting in on real Objective-C! ;-)


No comments:

Post a Comment