Download - A C++ Crash Course

Transcript
Page 1: A C++ Crash Course

A C++ Crash Course

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

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 3: A C++ Crash Course

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 4: A C++ Crash Course

The compilation Process

Preprocessor

.c .h .c .h

Compiler

Linker

executable

Libraries

Source code (text)

C/C++ code (text)

Object code (bin)

Native Executable (bin)

PreprocesserResolves #define, #include

CompilerTranslates code to Machine Language. It outputs an “object file.” This code is not executable

LinkerTakes object files and resolves references to functions and variables in different files

Page 5: A C++ Crash Course

Declarations - (bad) Example

int main(void) {int result;...

result = add(20, 3);

...return 0;

}

int add(int a, int b) {return a + b;

}

What is wrong with the following code? Will it compile in C? in C++?

Hint: It has to do with the declaration and use of add.

Page 6: A C++ Crash Course

Declaration Regions

int main(void) {int result;int add(int,int);...

result = add(20, 3);

...return 0;

}

int add(int a, int b) {return a + b;

}...

int add(int,int);

int main(void) {int result;...

result = add(20, 3);

...return 0;

}

int add(int a, int b) {return a + b;

}...

add is declared in the shaded

regions

Corrected Code 1 (local prototype)

Corrected Code 2 (global prototype)

Page 7: A C++ Crash Course

#define • #define Tag Substitution

– Replaces all following occurrences of Tag with Substitution– The Substitution may be the empty string– Does not replace Tag if it is inside quotation marks

• #define Tag(x,y,z) Substitution– Creates a Function-like macro Tag– The Substitution may refer to the parameters x, y, or z– Only items of the form Tag(x,y,z) will be replaced (Just plain Tag will be ignored)

#define MAX_SIZE 80#define GET_FIELD(a,b) a->b

int ar[MAX_SIZE];GET_FIELD(point, xCoord);GET_FIELD(“lalala", f03j?);

int ar[80];point->xCoord “lalala”->f03j?

Page 8: A C++ Crash Course

Header FilesCommon Usages:• Creates an informal module interface (No relation to

Java interfaces)• Provides documentation• Each module usually has a header file• Often include the following:

– function prototypes– struct and class declarations– typedefs– global variable declarations– Lots of (high-level) comments

• Abstracts code for optimization (less common)

Page 9: A C++ Crash Course

#include#include essentially copies and pastes the given

file into the current line

• There are two forms of #include• They differ in the order in which directories are search

for the given file• The search order is implementation defined• Here is the general pattern for different compilers:

#include <filename>• Searches the “include path,” then the current directory

#include “filename”• Searches the current directory, then the “include path”

Page 10: A C++ Crash Course

Header Guards

Wrap each header file with the lines:

#ifndef FILENAME_H

#define FILENAME_H

<header file body here>

#endif /* FILENAME_H */

Header Guards are a common C/C++ idiom

There is almost no reason to put things outside of header guards

Page 11: A C++ Crash Course

Header Filepoint2d.h

#ifndef POINT2D_H#define POINT2D_H

struct Point2D { int x; int y; };typedef struct Point2D Point2D;

/* returns the result of the vector addition of * a and b. */Point2D add(Point2D *a, Point2D *b);

/* returns the result of the vector subtraction of * b from a */Point2D sub(Point2D *a, Point2D *b);

#endif /* POINT2D_H */

Page 12: A C++ Crash Course

Classes• Roots come from C-style structs• Fairly similar to Java classes in concept.• Used to group related data and functions.• Can be used to write OO code

class Queue {public:

Queue();void enqueue(int n);int dequeue();~Queue();

private:int numElements;int capacity;int *queueData;

};

Page 13: A C++ Crash Course

Basic class Syntax

Declaring a class: class [optional name] {

[access modifier]<type> member1;<type> member2;

[access modifier]<type> member3;<type> member4;…

} [instance list];

Example: class Point2D{

private:int x;int y;

public:Point2D(int x, int

y);int getX();int getY();

} p1(2,3);

Point2D p2(1,3);Point2D *p;

Declaring a class without inheritance

Page 14: A C++ Crash Course

/* point2d.h */

#ifndef POINT2D_H#define POINT2D_H

class Point2D{private:

int x;int y;

public:Point2D(int x, int

y);int getX();int getY();

};

#endif /* POINT2D_H */

Declaring & Defining methods/* point2d.cc */

#include “point2d.h”

Point2D::Point2D(int x, int y){x = 0; y = 0;

}

int Point2D::getX(){return x;

}

int Point2D::getY(){return y;

}

Classes form a closed namespace

Page 15: A C++ Crash Course

Constructors

• Constructors have the same name as their class• Constructors may not pass off control to another

constructor• A default (zero argument) constructor is

provided when no other constructors declared• Constructors may invoke the constructors of

their super class, and of their member variables via member-wise initialization.

Constructors are functions that get called when a class is instantiated

Page 16: A C++ Crash Course

DestructorsDestructors are called when a class is deallocated

• Destructors are have no return type and have the same name as their class with a ‘~’ prepended.

• If no destructor is given, a trivial destructor, which calls the destructor for all elements is given.

Page 17: A C++ Crash Course

InheritanceInheritance is specified by a : and a list of access specifiers + class names in the class declaration

class Point2D{private:

int x;int y;

public:Point2D(int x, int

y);int getX();int getY();

};

class ColorPoint2D : public Point2D

{private:

int color;

public:ColorPoint2D(int

x, int y, int

color);int getColor();

};

Page 18: A C++ Crash Course

Inheritance continued

• Base classes can be public, protected, or private– In public inheritance, all public and protected

members are inherited– In protected inheritance, all public members from the

base class become protected– In private inheritance, all public and protected

members become private

• Java only has public inheritance• You can call any ancestor’s class method using

the scope resolution operator (::)

Page 19: A C++ Crash Course

Dynamic Memory

• Dynamically sized memory in C and C++ must be manually managed

• Dynamic memory is not necessarily much slower than static memory

• All allocated memory must be freed by the user• Do not free memory twice (double free).• Do not free memory that was allocated by you• Manual memory management allows for finer

grained control of your program• It’s not that scary, nor that hard.

Page 20: A C++ Crash Course

new, delete, delete[]

• the new operator allocates new memory, initializes it and returns a pointer to it.

• the delete operator deallocates memory allocated by new

• If you allocate a new array, you must delete it with delete[] and not delete

Improper use of delete and delete[] will cause undefined behavior!

Point2D *p = new Point;delete p;p = NULL;

int *ar = new int[50];delete[] ar;ar = NULL;

Example:

Page 21: A C++ Crash Course

malloc, calloc, realloc, free• These are C memory management functions• Do not mix them with the C++ ones! (that is, don’t

try to delete memory from malloc, etc.)• These functions return void* (pointers to anything)• They are not typesafe• They do not call initializers for the memory• There is no realloc equivalent for C++• Some low-level memory management may be

faster with these functions, but don’t bank on that.

Page 22: A C++ Crash Course

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 23: A C++ Crash Course

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 24: A C++ Crash Course

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

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

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

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 28: A C++ Crash Course

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 29: A C++ Crash Course

Function Pointers

• Functions are pieces of code in memory• Pointers can point to functions.• 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 30: A C++ Crash Course

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 31: A C++ Crash Course

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 32: A C++ Crash Course

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 33: A C++ Crash Course

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 34: A C++ Crash Course

Typedefs – structs/enums/unionsPeople often make a typedef of an

anonymous struct or enum

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 35: A C++ Crash Course

C-style IO is an acquired taste. Learn to like it.

I/O C-style

Basic functions:• printf, scanf, fprintf, fscanf, sprintf, sscanf, etc.• gets, puts, getc, putc, getchar• read, write, fread, fwrite

We will cover the basics of the “formated” family of functions (printf, scanf, etc).

For the others, read the man pages in Unix.

Page 36: A C++ Crash Course

printf(char *format_string, ...);fprintf(FILE*, char *format_string, ...);

snprintf(char* buf, size_t n, char *format_string, ...);

printf

• In C, all devices are treated like files• Three standard files are:

– stdin Often the keyboard– stdout Often the text console– stderr Often the text console

• printf(....) is fprintf(stdout, ....)• The format string is a pattern for the output; it describes how to

display the arguments to printf.• Snprintf write to the string “buf”. The variable n specifies the size of

the buffer.• printf returns the number of characters written

Page 37: A C++ Crash Course

format string

• Format strings are normal strings with embedded “conversion specifications” which are placeholders for arguments

• Conversion specifications are a ‘%’ and a letter with an optional set of arguments in between the ‘%’ and letter.

• To print a ‘%’, you need to write ‘%%’

Example:printf(“Here is a number: %d\n”, 10);

%d is the conversion specification for signed integers.

Page 38: A C++ Crash Course

Conversion Specifications

Conversion Specifications:• %d, %i -- signed integer• %u -- unsigned integer• %f -- floating point number• %c -- character• %s -- string• %x -- hexadecimal value• %p -- pointer

Converion specifications tell how to translate a data value into a string

Options:• l -- long (32-bit value)• ll -- long long (64-bit value)• n -- field width of n digits• .n -- precision of n digits• 0 -- fill unused field with 0s

There are many more! Read man pages, or Google it.

Page 39: A C++ Crash Course

C++-style IO is easier for simple stuff

I/O C++-style

Basic classes:• iostream (cout, cin, cerr)• ostringstream, istringstream

cout << “Hello World!” << endll;cout << “Boo! “ << 10 << ‘c’ << endl;cerr << “Here’s the error stream” << endl;

int n;cin >> n;

char ch;cin >> ch;

Page 40: A C++ Crash Course

...but harder for complex stuff

I/O C++-style continued...

printf(“%.3f rounded to 2 decimals is %.2f\n”, 2.325, 2.325);

…becomes…

cout << setprecision(3) << 2.325 << “ rounded to 2 decimals is “<< setprecision(2) << 2.3.25<< endl;

Page 41: A C++ Crash Course

Global Variables• Global Variables are not evil!

• Allocated at program start.

• Deallocated at program end.

• By default, initialized to bit-wise zero (do not depend on this).

• Need to understand modifiers: extern, static, and const to use properly.

• Need to understand linking to use properly.

Page 42: A C++ Crash Course

Global Variables - Gotcha

/* util.c */

int g_numCalls = 0;

void someFunc(void) {fprintf(stderr, “Num Calls to %s: %d\n”, __func__, g_numCalls);...

}

What is wrong with this code?

/* test.c */void someFunc(void);int g_numCalls = 0;

int main(void) {fprintf(stderr, “Num Calls to %s: %d\n”, __func__, g_numCalls);

someFunc(); someFunc();...

}

compile line: gcc -Wall -ansi util.c test.c -o test

Page 43: A C++ Crash Course

static

On a global variable or a functionstatic int g_someGlobalVariable;static void myFunction(void);Tells the linker not to export the variable or function. Essentially makes the identifier “file scope,” as the linker will not use it fulfill dependencies from other files.

On a local (function) variablevoid someFunc(void) {

static int array[4000];}Places the variable off the stack. This has the side-effect that it retains it value across calls. It is often used when a variable is too large to be put on the stack.

On a class member (covered when we discuss classes)

static has 3 very separate meanings

Page 44: A C++ Crash Course

Globals Variables - Gotcha (fixed)

/* util.c */

static int g_numCalls = 0;

void someFunc(void) {fprintf(stderr, “Num Calls to %s: %d\n”, __func__, g_numCalls);...

}

Static to the rescue!!!!!

/* test.c */void someFunc(void);static int g_numCalls = 0;

int main(void) {fprintf(stderr, “Num Calls to %s: %d\n”, __func__, g_numCalls);

someFunc(); someFunc();...

}

compile line: gcc -Wall -ansi util.c test.c -o test

The two variables “g_numCalls” have no relation. Think of them as private to each file.