Professional Documents
Culture Documents
Part I
Questions & Feedback to Hannah C. Tang (hctang) and Albert J. Wong (awong)
C-style types
Typedefs Structs
The stack
Arrays (working model) Pointers
A practice program
C++ classes
Inheritance and dynamic dispatch
Memory management
The heap Destructors
Advanced topics
Modifiers: const, static, and extern Operator overloading Templates
Goals of Java
Java, C, and C++, have different design goals. Java
Simple Consistent Huge OO Focus Cross platform via a virtual machine Originally for embedded systems
C
Low level No Runtime Type info Easy implementation
C++
Originally to add some OO functionality to C Attempt to be a higher-level language Now its a totally different language
App
Calculator
class App { public static void main(String[] args) { Calculator c = new Calculator; c.printSum(); } }
Procedural Programming
Functions are free-floating methods disassociated from any class Functions declarations can be separate from function implementations
The declaration provides the signature, which specifies the name, return type, and parameter list of the function
Discussion Point I
Which of these programs can be written procedurally? Object-orientedly? HelloWorld A traffic simulator
Must simulate cars, roads, and the interactions between these entities
A calculator
Accepts two numbers, then calculates the sum or difference, depending on a user-selected operator
An mp3 player
Accepts a list of files, and plays them in the specified order. Needs to support skins
<ReturnType> can be any type except an array Class-scoped methods and free-floating functions are basically the same, except
pt
Point pt; pt = new Point(3, 4)
p
moveToDiagonal(Point p) { p.setY(p.getX()); }
In Java, modifying an atomically-typed parameter did NOT modify the original instance. In Java, atomic types are passed by copy. The same semantics hold for C++ atomic types
int y)
d1 y x x
7 main aFunc
Discussion Point II
Examine the code fragment below.
Draw the stack frame(s) for some sample input. If you see any bugs, what are they? How would the program behave?
void sillyRecursiveFunction(int i) { if(i == 0) { return; } else { sillyRecursiveFunction(i 1); } }
Arrays
<ArrayType> arrayName[ numElements ]
Arrays are contiguous memory locations, and its name refers only to the address of the first element Indexing into an array is the same as adding an offset to the address of the first element When declaring an array, its size must be known at compile-time
myArray[5] myArray[4] myArray[3] myArray[2] myArray[1] myArray[0] or myArray
Arrays are not passed by copy. Instead, the address of the first element is passed to the function
Note how array parameters and nonparameter arrays behave identically
Pointers
What if we had variables that contained addresses? They could contain addresses of anything!
We could use these variables in functions to modify the callers data (we could implement Javas parameterpassing semantics!)
x (4104) y (4100)
Variable name
n (4096)
Address
Storage space
Pointers: vocabulary
A pointer is a variable which contains addresses of other variables Accessing the data at the contained address is called dereferencing a pointer or following a pointer
4096
Pointer Syntax
Declaring Pointers
Declaring a pointer: <Type> * ptrName;
Using Pointers
Dereferencing a pointer: *ptrName Go to the address contained in the ptrName is a variable which variable ptrName contains the address of something of type <Type> Getting the address of a variable: &aVar Get the address of aVar
For example: int * nPtr1, * nPtr2; void aFunc( int aParam, int * ptrParam);
Memory Layout p contains the address of an int. q contains an int. Go to the address that p contains, and place a 5 there.
p (8200) 8196
main void doubleIt(int x, int * p) 16 a { *p = 2 * x; } int main(int argc, const char * argv[]) doubleIt { int a = 16; x 9 doubleIt(9, &a); return 0; p }
Pointer Arithmetic
Pointers are numbers, so you can do math on them!
int * p = &a;
p (8200) b (8196) a (8192)
*p = 200;
p (8200) b (8196) a (8192)
*(p+1) = 300;
p (8200) b (8196) a (8192)
8192 9 16
8192 9 200
Pointer p refers to an int, so adding 1 to p increments the address by the size of one int. The C/C++ expression for this is sizeof(int)
8184
Discussion Point IV
How do pointers and arrays differ?
Hint: how are pointers implemented in memory? Arrays?
Exercise
Get up and stretch! Do the worksheet exercise Then, write a program to do the following:
Read some numbers from the user (up to a max number of numbers) Calculate the average value of those numbers Print the users values which are greater than the average
Pointer Problems
Pointers can refer to other variables, but:
Create an additional variable Have an ugly syntax
Function Pointers
<ReturnType> (*ptrName)(arg type list ); Functions are pieces of code in memory Pointers can point to functions. This syntax is U-G-L-Y (the ugliest in C) Notice that the name of the variable appears in the middle of the statement! You do not have to dereference a function pointer Function pointers are not scary. They are useful!
p = bar; p(2, b); // equivalent to bar(2, b); (*p)(2, b); // Exactly the same return 0; }
References
References are an additional name to an existing memory location
If we wanted something called ref to refer to a variable x:
Pointer: x 9 Reference: x ref 9
ref
Properties of References
Reference properties:
Cannot be reassigned Must be assigned a referee at construction
Therefore:
References cannot be NULL You cannot make an array of references. Given what you know about references, can you explain where these properties come from?
Reference Syntax
References
Declaring a reference: <Type> & refName = referee; Usage: int n; int & referee = n; void aFunc( int aParam, int & ptrParam); aFunc(1, n);
Pointers
Declaring a pointer: <Type> * ptrName;
Usage: int n; int * nPtr1 = &n; void aFunc( int aParam, int * ptrParam); aFunc(1, &n);
Discussion Point V
What are the differences between Java references and C++ references? What about Java references and C++ pointers?
C-style struct
A struct is used to group related data items
struct student { int id; char name[80;] };
Note that the it is optional to name a struct
To the programmer
id and name are now related struct student creates a convenient grouping
To the compiler
Id and name have a fixed ordering (not offset) in memory Struct student is a first-class type that can be passed to functions
struct Syntax
Declaring a Struct
Declaring a struct: struct [optional name] { <type> field1; <type> field2; } [instance list]; Examples: struct Foo { int field1; char field2; } foo,*foo_ptr; struct Foo foo2; struct { int a; } blah;
enum
An enum creates an enumerated type; they are options with an associated value
enum PrimaryColors { RED = 0, GREEN, BLUE };
By default, the first option is given the value 0 You can assign an option any integer Subsequent options have the previous options value + 1 All enumeration values are in the same namespace
enum Syntax
Declaring an enum
Declaring a enum: enum [optional name] { OptionName [= int], OptionName [= int], } [instance list]; Example of an enum: enum Color { RED, GREEN, BLUE } color, *color_ptr; enum Color c; void drawCircle (enum Color c);
Enum quirks
Problems with Enums: Frail abstraction Treated as integers Can be assigned invalid values Flat namespace Proper use guidelines: Avoid breaking abstraction Mangle name of enum into option name (so ColorRed instead of Red) Here is one sanctioned abstraction break enum Color { RED, GREED, BLUE, NumberOfColors };
union
An union creates an union type; all fields share the same memory location
union Argument { int intVal; double doubleVal; char charVal; };
Changing intVal changes doulbeVal and charVal! Can be used to create constrained-type containers Usually used in conjunction with an enum that says which field is currently valid.
union Syntax
Declaring an enum
Declaring a enum: union [optional name] { <type> name1; <type> name2; } [instance list]; Example of a union: union Argument { int value; char *string; } arg1, *ptr; union Argument arg2; arg1.value = 3;
arg2.string = NULL;
Union quirks
Problems with Enums: Only assume that the last field written two is valid. Dont use to save space. Proper use guidelines: Ensure you have another method of knowing which field is currently valid.
Typedef
Typedef is used to create an alias to a type
typedef unsigned char unsigned char mybyte; byte mybyte; byte;
Both definitions of mybyte are equivalent to the compiler. The second definition is preferred as it gives more info
Clarification
More informative names for a type be given Variables that use the same type in different ways can be separated easily
Convenience
Type names can get very long People like structs to look like real types Some type names (like function pointers or array pointers) are really hard to read/write
Typedefs structs/enums/unions
People often make a typedef of an anonymous struct, enum, or union
typedef struct { int id; char name[80]; } Student; Student st; struct Student { int id; char name[80]; }; struct Student st;
These are almost the same. However, anonymous structs cannot refer to themselves.
Discussion Point VI
What advantages do named structs/unions have over anonymous ones? Are enums different?
How would you try to pass anonymous structs, enums, or unions to a function? Can you?
C++ Gotcha I
Dont use exceptions unless you know what youre doing!
Uncaught C++ exceptions do not produce a stack trace. C++ does not automatically reclaim newd resources (more in a later tutorial)
void someFunc(void) { throw Exception!"; } int main(int argc, const char * argv[]) { someFunc(); return 0; } $ ./myProg Aborted $
C++ Gotcha II
Dont return pointers (or references) to local variables!
double * aFunc(void) { double d; return &d; } int main(int argc, const char * argv[]) { double * pd = aFunc(); *pd = 3.14; return 0; } Boom! (maybe)
C++ Gotcha IV
Never use an array without knowing its size
int myArray[5];
= = = = =
myArray[5] = 9; myArray[-1] = 4;
No Error! Undefined Behavior!
What We Covered
The procedural programming paradigm Functions and parameter passing The C/C++ memory model Part I (the stack)
Pointers Arrays C++-style References
C type constructs
Structs, enums, unions, typedefs
Any questions?
Nathan Ratliff
Version 1 of the C++ tutorial
Doug Zongker
Version 1 of the handouts
Pointers to Arrays
int (*ar)[3] vs. int *ar[3]
The first is a pointer to an array of 3 integers. The second is a array of 3 elements, where each element is an int-pointer. This is how multidimensional arrays work p
int a[3]; int *p = a; p+1 == 8188 int (*p2)[3] = &a; p2+1 == 8196 (*p2)[0] == p2[0][0] == 122 (*(p2+1))[0] == p2[1][0] == p2 == 8184 (8200) p2 (8196) &a[2] (8192) &a[1] (8188) &a[0] (8184)