Download - A C++ Crash Course Part I

Transcript
Page 1: A C++ Crash Course Part I

A C++ Crash CoursePart I

UW Association for Computing Machinery

http://www.cs.washington.edu/orgs/acm/tutorials

[email protected]

Questions & Feedback to Hannah C. Tang (hctang) and Albert J. Wong (awong)

Page 2: A C++ Crash Course Part I

What We’ll Cover

• C/C++ fundamentals– Functions– Primitive data types

• The stack – Arrays (working model)– Pointers

• A practice program

• C-style types– Typedefs– Structs

• Arrays (whole story)

• More C++-isms– C++-style vs Java-style

references– C++ gotchas

Page 3: A C++ Crash Course Part I

What We’re NOT Covering

• Topics related to C++ classes– Multiple files– The preprocessor

• C++ classes– Inheritance and dynamic dispatch

• Memory management– The heap– Destructors

• Advanced topics– Modifiers: const, static, and extern– Operator overloading– Templates

Page 4: A C++ Crash Course Part I

Goals of Java

Java– Simple– Consistent– Huge OO Focus– Cross platform via a virtual machine– Originally for embedded systems

Java, C, and C++, have different design goals.

Page 5: A C++ Crash Course Part I

Goals of C and C++

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 it’s a totally different language

C and C++ are popular because they have met, with reasonable success, their goals.

Page 6: A C++ Crash Course Part I

A simple program snippet

public void printSum(void)

{

int x, y;

// … get user input …

int sum = x + y;

// … print sum …

}

void printSum(void)

{

int x, y;

// … get user input …

int sum = x + y;

// … print sum …

}

Page 7: A C++ Crash Course Part I

The simple program – Java versionclass Calculator { public void printSum(void) { int x, y;

// … get user input …

int sum = x + y;

// … print sum … }}

class App { public static void main(String[] args) { Calculator c = new Calculator; c.printSum(); }}

App

Calculator

printSum()

Page 8: A C++ Crash Course Part I

The simple program – C++ version

void printSum(void) { int x, y;

// … get user input …

int sum = x + y;

// … print sum …}

int main(int argc, const char * argv[]) { printSum(); return 0;}

class Calculator { public void printSum(void) { int x, y;

// … get user input …

int sum = x + y;

// … print sum … }}

class App { public static void main(String[] args) { Calculator c = new Calculator; c.printSum(); }}

Page 9: A C++ Crash Course Part I

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

• C is completely procedural

• C++ mixes object-oriented and procedural programming

Page 10: A C++ Crash Course Part I

Discussion Point I

• 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

• Come up with your own example

Which of these programs can be written procedurally? Object-orientedly?

Page 11: A C++ Crash Course Part I

Function Syntax and Semantics

• <ReturnType> can be any type except an array• Class-scoped methods and free-floating

functions are basically the same, except …

<ReturnType> functionName( … <parameter list> … );

int calculatePower(int base, int exponent);

Page 12: A C++ Crash Course Part I

Parameter Passing in Java – Part I

class Example {

public void moveToDiagonal(Point p) { p.setY(p.getX()); }

public static void main( String[] args ) { Point pt; pt = new Point(3, 4); moveToDiagonal(pt); // What are the coordinates of pt now? }}

Page 13: A C++ Crash Course Part I

In Java, everything is a reference

Point pt;pt = new Point(3, 4)

pt

x: 3y: 4

x: 3y: 3

moveToDiagonal(Point p) { p.setY(p.getX());}

p

In Java, modifying a method parameter means modifying the original instance

Page 14: A C++ Crash Course Part I

… almost everything is a reference

Java atomic types:• int• double• boolean• etc …

C++ atomic types:• int• double• bool• etc …

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

Page 15: A C++ Crash Course Part I

C/C++ Function Parameters

• In C++, all function parameters are passed by copy – even if they’re not of atomic type

• Why?– First, a brief detour …

Page 16: A C++ Crash Course Part I

Detour: Functions & Memory

• Every function needs a place to store its local variables. Collectively, this storage is called the stack

• This storage (memory aka “RAM”), is a series of storage spaces and their numerical addresses

• Instead of using raw addresses, we use variables to attach a name to an address

• All of the data/variables for a particular function call are located in a stack frame

Memory location

void aFunc(int x, int y) { double d1, d2; int i;}

x

y

d2

d1

i

Page 17: A C++ Crash Course Part I

Detour: Functions & Memory (cont)• When a function is called, a new

stack frame is set aside • Parameters and return values are

passed by copy (ie, they’re copied into and out of the stack frame)

• When a function finishes, its stack frame is reclaimed

void aFunc(int x, int y) { double d1 = x + y;}int main(int argc, const char * argv[]) {

int x = 7;aFunc(1, 2);aFunc(2, 3);return 0;

}

x

y

d1

x 7

aFunc

main

Page 18: A C++ Crash Course Part I

C/C++ Function Parameters (cont.)

• In C++, all function parameters are passed by copy – even if they’re not of atomic type

• Why?– In C++, all variables exist on the stack by default– In C++, parameters are copied into the callee’s stack

frame– We’ll talk about Java parameter passing later (when

we talk compare C++ and Java references)

Page 19: A C++ Crash Course Part I

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); }}

Page 20: A C++ Crash Course Part I

Arrays

• 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[0] or myArray

myArray[1]

myArray[2]

myArray[3]

myArray[4]

myArray[5]

<ArrayType> arrayName[ numElements ]

Page 21: A C++ Crash Course Part I

Arrays as function parameters

• Arrays are not passed by copy. Instead, the address of the first element is passed to the function– Note how array parameters and non-

parameter arrays behave identically

<ReturnType> funcName( ArrayType arrName[ ] )

int sumOfArray( int values[], int numValues )

Page 22: A C++ Crash Course Part I

Discussion Point III

• Why are arrays not passed by copy? – Hint: the size of a stack frame is computed

long before the program is run (specifically, at compile time)

Page 23: A C++ Crash Course Part I

Pointers

n(4096)

y(4100)

x(4104)

Storage spaceAddress

Variable name

What if we had variables that contained addresses?They could contain addresses of anything!

We could use these variables in functions to modify the caller’s data

(we could implement Java’s parameter-

passing semantics!)

Page 24: A C++ Crash Course Part I

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”

n(4096)

y(4100)

x(4104)

4096

7

Page 25: A C++ Crash Course Part I

Pointer SyntaxDeclaring Pointers

Declaring a pointer: <Type> * ptrName;

“ptrName is a variable which contains the address of something of type <Type>”

For example:int * nPtr1, * nPtr2;void aFunc( int aParam, int * ptrParam);

Using Pointers

Dereferencing a pointer:*ptrName“Go to the address contained in the variable ptrName”

Getting the address of a variable:&aVar“Get the address of aVar”

For example:aFunc(myInt, &anotherInt);anInt = *myPtr * 4;*dinner = 100;

Page 26: A C++ Crash Course Part I

Pointers: Putting it all together

The code

int * p;

int q;

p = &q

*p = 5;

Box Diagrams

“p’s type is int pointer. q’s type is int.”

“Assign 5 to where p points (which is q).”

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.

5pp (8200) 8196

q (8196) 5q

Page 27: A C++ Crash Course Part I

Pointers: Putting it all together (cont.)

The code

void doubleIt(int x, int * p)

{

*p = 2 * x;

}

int main(int argc, const char * argv[])

{

int a = 16;

doubleIt(9, &a);

return 0;

}

Box diagram Memory Layout

9x

p (8200)

x (8196)

16a

main

doubleIt

p

a (8192)

16

9

8192

main

doubleIt

Page 28: A C++ Crash Course Part I

Pointer Arithmetic

Pointers are numbers, so you can do math on them!

200

9

8192p

(8200)

b (8196)

a (8192)

int * p = &a;

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)

200

300

8192p

(8200)

b (8196)

a (8192)16

9

8192p

(8200)

b (8196)

a (8192)

*p = 200;

*(p+1) = 300;

Page 29: A C++ Crash Course Part I

Pointers and Arrays

Pointers and arrays are (almost) interchangeable

myArray[3](8196)

myArray[4](9000)

int myArray[5];

int * p = myArray;

Given:

These are equivalent:• *p• myArray[0]• *(p+0)• *myArray• p[0]• 0[p]

myArray[2](8192)

myArray[1](8188)

myArray[0](8184)

p(8180)

8184

Page 30: A C++ Crash Course Part I

Discussion Point IV

• How do pointers and arrays differ?– Hint: how are pointers implemented in

memory? Arrays?

Page 31: A C++ Crash Course Part I

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 user’s values which are greater than

the average

• Get up and stretch again!

Page 32: A C++ Crash Course Part I

Pointer Problems

• Pointers can refer to other variables, but:– Create an additional variable– Have an ugly syntax– –

Page 33: A C++ Crash Course Part I

Function Pointers

• 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

<ReturnType> (*ptrName)(arg type list );

Function pointers are not scary. They are useful!

Page 34: A C++ Crash Course Part I

Function Pointers - example

void foo(int i, char b);void bar(int i, char b);

int main(void) {void (*p)(int,char);

p = foo;p(1, ‘c’); // equivalent to foo(1, ’c’);

p = bar;p(2, ‘b’); // equivalent to bar(2, ‘b’);(*p)(2, ‘b’); // Exactly the same

return 0;}

Page 35: A C++ Crash Course Part I

References

References are an additional name to an existing memory location

9x

ref

Pointer:

9xref

Reference:

If we wanted something called “ref” to refer to a variable x:

Page 36: A C++ Crash Course Part I

Properties of ReferencesReference 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?

Page 37: A C++ Crash Course Part I

Reference SyntaxReferences

Declaring a reference: <Type> & refName =

referee;

Usage:int n;int & referee = n;void aFunc( int aParam, int & ptrParam);

aFunc(1, n);

PointersDeclaring a pointer: <Type> * ptrName;

Usage:int n;int * nPtr1 = &n;void aFunc( int aParam, int * ptrParam);

aFunc(1, &n);

Page 38: A C++ Crash Course Part I

Discussion Point V

• What are the differences between Java references and C++ references? What about Java references and C++ pointers?

Page 39: A C++ Crash Course Part I

C-style struct

A struct is used to group related data itemsstruct student {

int id;char name[80;]

};

• 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

Note that the it is optional to name a struct

Page 40: A C++ Crash Course Part I

struct SyntaxDeclaring 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;

Access struct fields

Accessing a field in a struct:foo.field1;

“gets field1 from the instance foo of struct Foo”

Pointers syntax and structsThe * has lower precedence than the ‘.’ :

*foo_ptr.field1; means

*(foo_ptr.field1);Which won’t compile

Accessing a field in a struct pointer: (*foo_ptr).field1;foo_ptr->field1;

Page 41: A C++ Crash Course Part I

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 option’s value + 1• All enumeration values are in the same namespace

Note that the it is optional to name an enum

Page 42: A C++ Crash Course Part I

enum SyntaxDeclaring 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 breakenum Color {

RED,GREED,BLUE,NumberOfColors

};

Page 43: A C++ Crash Course Part I

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.

Note that the it is optional to name a union

Page 44: A C++ Crash Course Part I

union SyntaxDeclaring 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.• Don’t use to “save space.”

Proper use guidelines:• Ensure you have another method

of knowing which field is currently valid.

Page 45: A C++ Crash Course Part I

Typedef

Typedef is used to create an alias to a type

• byte now represents an unsigned char

• Both definitions of mybyte are equivalent to the compiler.

• The second definition is preferred as it gives more info

typedef unsigned char byte;

byte mybyte;

unsigned char mybyte;

Page 46: A C++ Crash Course Part I

Typedef – common uses• Abstraction

– The user may easily change the type used to represent a variable.

• 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

Page 47: A C++ Crash Course Part I

Typedefs – structs/enums/unionsPeople 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.

struct List { int data;struct List *next;

};

Page 48: A C++ Crash Course Part I

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?

Page 49: A C++ Crash Course Part I

C++ “Gotcha” I

Don’t use exceptions unless you know what you’re doing!

• Uncaught C++ exceptions do not produce a stack trace.• C++ does not automatically reclaim new’d resources

(more in a later tutorial)

void someFunc(void) { throw “Exception!";}int main(int argc, const char * argv[]) { someFunc(); return 0;}

$ ./myProgAborted$

Page 50: A C++ Crash Course Part I

C++ “Gotcha” II

double * aFunc(void) { double d; return &d;}int main(int argc, const char * argv[]) {double * pd = aFunc();

*pd = 3.14;return 0;

}

Don’t return pointers (or references) to local variables!

Boom! (maybe)

Page 51: A C++ Crash Course Part I

C++ “Gotcha” III

Uninitialized pointers are bad!

int * i;

if( someCondition ) {…i = new int;

} else if( anotherCondition ) {…i = new int;

}

*i = someVariable;

Does the phrase “null pointer exception”

sound familiar?

Page 52: A C++ Crash Course Part I

C++ “Gotcha” IV

Never use an array without knowing its size

• C++ arrays do not know their own size.– Always pass a size

variable with the array– Always check the

bounds manually (C++ won’t do it for you!)

int myArray[5];

myArray[0] = 85;myArray[1] = 10;myArray[2] = 2;myArray[3] = 45;myArray[4] = 393;

myArray[5] = 9;myArray[-1] = 4;

No Error! Undefined Behavior!

Page 53: A C++ Crash Course Part I

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?

Page 54: A C++ Crash Course Part I

Acknowledgements & References

– Books:– Essential C++ (C++ In-Depth Series), Stanley B. Lippman, 1999, 304

pgs.

– The C++ Primer, 3rd edition, Stanley B. Lippman, 1998, 1237 pgs.

– Effective C++, 2nd edition, Scott Meyers, 1997, 304 pgs.

– The C++ Language, 2nd Edition, Bjarne Stroustrup, 2000, 1019 pgs.

– Thinking in C++, 2nd Edition, Bruce Eckel, 2000, 814 pgs. Also available online (for free): http://mindview.net/Books/TICPP/ThinkingInCPP2e.html

• Nathan Ratliff– Version 1 of the C++ tutorial

• Doug Zongker– Version 1 of the handouts

• Hannah C. Tang & Albert J. Wong– Wrote, proofread, and presented the current version of the tutorial and

handouts

Page 55: A C++ Crash Course Part I

It’s basically over now

The next few slides are here for completeness. You do not need to know most of the following info.

The stuff on array, the majority of C developers probably do not know this following info.

If you are not comfortable with the material on pointers and arrays presented previously, just skip the next slides.

If you are terminally curious, keep going.

Page 56: A C++ Crash Course Part I

Arrays (the whole story)Arrays are not pointers. They are not first

class types either.• Arrays know their size!• Arrays forget their size after they get passed to a function!• You CANNOT return arrays of any type

int foo(int ar[ ]) {printf(“%d\n”, sizeof(ar));

}

int main(void) {int ar[10];printf(“%d\n”,sizeof(ar));foo(ar);return 0;

}

The output of this, assuming a 4-byte int would be:

404

Page 57: A C++ Crash Course Part I

Pointers to Arraysint (*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

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

16

8184

8184p

(8200)

p2 (8196)

&a[2] (8192)

485

122

&a[1] (8188)

&a[0] (8184)