c++ crash course
DESCRIPTION
C++ crash course. Class 4 arrays, pointers, functions. Agenda. Boolean Logic Arrays and Pointers redux Functions Class functions Constructors Finishing the bookstore. Boolean Logic. Computers deal in 1 ’ s and 0 ’ s Many times we want to make decisions in terms of logic - PowerPoint PPT PresentationTRANSCRIPT
C++ crash course
Class 4arrays, pointers, functions
Agenda
• Boolean Logic• Arrays and Pointers redux• Functions• Class functions• Constructors• Finishing the bookstore
Boolean Logic
• Computers deal in 1’s and 0’s• Many times we want to make decisions in
terms of logic
if( am_hungry AND like_apples) {eat_apple;
}
Boolean Logic• C++ (like many other languages) allows you to do this using
logical operators• These are binary operators, meaning they operate on two
operands (the quantities on either side)• Results in a bool-type expression
&& logical and|| logical or! logical not
== tests equality!= tests non-equality<, >, <=, >= comparison operators
operate on bool-type expressions only
can operate on many types
Boolean Logic
• How do we understand these operators?– Bool-expressions are either TRUE or FALSE
• &&, ||, ! all change these values
A B A && B
FALSE FALSE FALSE
FALSE TRUE FALSE
TRUE FALSE FALSE
TRUE TRUE TRUE
Boolean LogicA B A || B
FALSE FALSE FALSE
FALSE TRUE TRUE
TRUE FALSE TRUE
TRUE TRUE TRUE
A !A
FALSE TRUE
TRUE FALSE
Arrays• We started talking about these yesterday• Contiguous allocation in memory, accessed by pointers• Arrays are a compound type
– Need: type specifier, identifier, dimension (must be known at compile-time)
const unsigned buf_size = 512, max_files = 20;int staff_size = 27;const unsigned sz = get_size();
//okchar input_buffer[buf_size];string fileTable[max_files + 1];int vars[12]; // this works, but is bad practice // don’t hardcode except in consts
//baddouble salaries[staff_size];
int test_scores[get_size()];int vals[sz];
Arrays• When we initialize an array, we can provide an initialization for each element• Otherwise, arrays will be initialized as they are in vectors – default variable
initializers
const unsigned array_sz = 3;int ia[array_sz] = {0,1,2};
const unsigned array_sz2 = 5;int ia2[array_sz2] = {0,1,2};// this results in {0,1,2,0,0};
• Character arrays are special, and can be initialized with character string literals
char ca1[] = {‘C’, ‘+’, ‘+’}; // note: no null terminator!char ca2[] = {‘C’, ‘+’, ‘+’, ‘\0’}; // null terminatedchar ca3[] = “C++”; // automatically null-terminated; equivalent
// to the previous line
Arrays
• Can’t initialize arrays with other arrays!
int ia[] = {0,1,2}; // OKint ia2[](ia); // badint ia3[3]; // ok, but uninitialized elementsia3 = ia; // bad
• Arrays CANNOT get bigger once they’ve been created• Some compilers will let you do it anyway as a
compiler extension, but you’re not guaranteed this
Arrays• Operators– The size of an array is type size_t– No size function; should be set as a const somewhere
though– Subscript operator can change elements (a[n])
• Unlike in other languages, it is PERFECTLY LEGAL to access an array element outside of the size of the array!– Don’t do this: you’re messing with memory you
shouldn’t be. Always check your array size before access.
Arrays
• get_size() takes no arguments and returns an int
• Which of these are legal definitions?
unsigned buf_size = 1024;(a) int ia[buf_size];(b) int ia[get_size()];(c) ia[4 * 7 – 14];(d) char st[11] = “fundamental”;
Arrays
• Which of these definitions are illegal?
(a) int ia[7] = {0,1,1,2,3,5,8};(b) vector<int> ivec = {0,1,1,2,3,5,8};(c) int ia2[] = ia1;(d) int ia3[] = ivec;
Pointers
• Pointers can also be used for array access• We saw this yesterday– Pointers are compound types– Pointers are the iterators for arrays
• Iterators can only be used for a specific container
• Pointers can point to any kind of variable
Pointers
• * is the dereference operator– in a variable definition, this indicates that the
variable is a pointer
• & is the address-of operator– tells us the address of a variable– Remember this from references?
In a reference, instead of setting the value of a variable when it’s declared, we set its address – this is why references are bound once they’re initialized
Pointers
• We can iterate through an array like so:
const size_t array_sz = 4;
int ia[array_sz] = {0,1,2,3};for(int *ptr = ia,size_t ctr = 0;
ctr < array_sz; ptr++, ctr++) cout << *ptr;
• Why did we need the counter?
Pointers
• As mentioned, we can point to anything
vector<int> *pvec;
int *ip1, *ip2;string *pstring;double *dp;
double dp, *dp2; // only dp2 is a pointer here
Pointers
• You can also write:
string* ps1, ps2;
• …but that can be confusing, since only ps1 is getting defined as a pointer
Pointers
• As always, make sure you initialize your pointers!• Pointers only hold addresses in memory• Just like when we fail to initialize ints or other
types with no default constructor (usually basic types), pointers will try to interpret whatever’s in memory at the point it’s been assigned as the address it should be pointing to
• If you don’t know where to point your pointer, point it at 0 – that way you can find out if it’s been initialized
Pointers
• Initialization can happen in four ways:
1. Constant expression with value 02. Address of an object that is of the right type3. Address one past the end of an object4. Another pointer of the same type
Pointers
• Which of these are okay?
int ival;int zero = 0;const int c_ival = 0;
int *pi = &ival;pi = zero;pi = c_ival;pi = 0;
Pointers• If you’re using the <cstdlib> header, you can also
use NULL• contains the line
#define NULL 0
…which tells the preprocessor to interpret any place in the program that has the word NULL as being 0
• If you try to dereference a null pointer, you will get a Segmentation Fault
Pointers
• There’s also void pointers, which can hold the address for any kind of type
double obj = 3.14;double *pd = &obj;int myint = 3;
void *pv = &obj;pv = pd;pv = &myint;
Pointers
• We have pointers so we can operate on the objects they point to
string s(“hello world”);string *sp = &s;cout << *sp;
• This dereferences the pointer
Pointers
• Which of the following are legal definitions?
(a) int *ip;(b) string s, *sp = 0;(c) int i; double *dp = &i;(d) int *ip, ip2;(e) const int i=0, *p = i;(f) string *p = NULL;
Pointers• Assigning through pointers
string s1(“some value”);string s2(“another value”);
string *sp1 = &s1;string *sp2 = &s2;
*sp1 = “a new value”;cout << s1 << endl << s2 << endl;
sp1 = sp2;*sp1 = “a new value”;cout << s1 << endl << s2 << endl;
Pointers (to pointers)
• Since pointers are also objects, we can point to them too
int ival = 1024;int *pi = &ival;int **ppi = π
(Is your head exploding yet?)
Pointers
• What does this program do?
int i = 42, j = 1024;
int *p1 = &I, *p2 = &j;*p2 = *p1 * *p2;*p1 *= *p1;
Pointers and Arrays• Yesterday we looked at iterator arithmetic• Pointer arithmetic is much the same
int ia[] = {0,2,4,6,8};int *ip = ia;
ip = &ia[4];
ip = ia;int *ip2 = ip+4; // equivalent to &ia[4];
Pointers and Arrays
• We can dereference an expression
int last = *(ia + 4); // refers to the 4th value // in the array
last = *ia + 4; // adds 4 to the 0th value // in the array
Pointers and Arrays
• Subscripting an array and subscripting a pointer are effectively the same operation
int *p = &ia[2];int j = p[1]; // 1 int in front of where p isint k = p[-2]; // 2 ints behind where p is
Pointers and Arrays
• Another way to write the for loop we used earlier
const size_t arr_sz = 5;int int_arr[arr_sz] = {0,1,2,3,4};for (int *pbegin = int_arr, *pend = int_arr + arr_sz;
pbegin != pend;pbegin++)
cout << *pbegin << ‘ ‘;
Pointers
• Where is p1 after this line of code?– p1 and p2 are both int pointers somewhere in the
same array
p1 += p2 – p1;
Pointers
• We can make pointers to objects for types we create• There’s a special operator, ->, for accessing public
members of those objects• Shorthand for (*ptr).
Sales_item item1, item2;Sales_item *pitem = &item1;
pitem->same_isbn(item2);(*pitem).same_isbn(item2);
Pointers and const
• Pointers to const objects should not be able to change them
• Pointers to const objects must use the const keyword
const double mydbl = 17.0;const double mydbl2 = 43.0;double nonconst = 25;const double *cptr = &mydbl; // okcptr = &mydbl2; // also ok: the ptr isn’t const
Pointers and const
double dval = 3.14;const double *cptr = &dval;
dval = 3.14159;*cptr = 3.14159;
double *ptr = &dval;*ptr = 2.72;cout << *cptr;
Dynamic Arrays
• We said that arrays have fixed size• Not completely true; it’s possible to create
dynamically-sized arrays
int *pia = new int[10]; // array of 10 // uninitialized ints
int *pia = new int[10] (); // array of 10 // initialized ints
Dynamic Arrays
• Using the new keyword causes the allocation to occur
• When we’re done with an array created dynamically, we need to get rid of it with the delete keyword
• Otherwise it will result in a memory leak
delete [] pia;
Functions• So far the only one we’ve seen is main()• Functions are defined by a name, and a set of operands• Function prototype is the return type, name and
parameters
int gcd(int v1, int v2) {while (v2) {
int temp = v2;v2 = v1 % v2;v1 = temp;
}return v1;
}
Functions
• In order to use a function, we use the call operator, or ()
// get values from standard inputcout << “Enter two values: \n”;int i,j;cin >> i >> j;// call gcd on arguments i and j// and print their greatest common divisorcout << “gcd: “ << gcd(i,j) << endl;
Functions• The parameters (int v1 and int v2 for gcd) of the
function are initialized when the function is called• The arguments to a function become the parameters
once inside the function– Sometimes you’ll hear these used interchangeably
• The type of an argument must match its coresponding parameter
• Any parameters and any variables defined inside the function have local scope– they exist only inside the body of the function
• Must also have a return type, which says what kind of object will come out of the function
Functions• Return types can be built-in types, class types, or
compound types
bool is_present(int *, int);int count(const string &, char);Date &calendar(const char*);void process();
• Can’t return a function or an array, but can return pointers to functions and arrays
• You must specify a return type in Standard C++ (even if it’s void, or int)
Functions• Parameter lists must specify the type for every
parameter
void process() { /* … */ } // legalvoid process(void) { /* … */ } // legal
int manip(int v1, v2){ /* … */} // illegalint manip(int v1, int v2){/* … */} // legal
• Names are optional on parameters, but to use them, they must have names
Functions
• Parameters are checked at compile-time to see if the argument types match
gcd(“hello”, “world”);gcd(24312);gcd(42, 10, 0);
• All of the above cause compile-time errors
gcd(3.14, 6.29); // no error; converts doubles to ints
Functions• What’s wrong with these function definitions (if
anything)?
(a) int f() {string s;// …return s;
}(b) f2(int i) { /* … */ }(c) int calc(int v1, int v1) { /* … */ }(d) double square(double x) return x * x;
Functions• Parameters that are not references are initialized by copying the arguments• Changes to the values inside the function will not change them outside the
function
void swap(int a, int b) {int c = a;a = b;b = c;return;
}
int main() {int x = 5, y = 4;swap(x,y);cout << “The values are: “ << x << “ “ << y << endl;return 0;
}
The values are: 5 4
Functions• In order to change the values, we need to use pointers!
void swap(int *a, int *b) {int c = *a;*a = *b;*b = c;return;
}
int main() {int x = 5, y = 4;swap(&x,&y);cout << “The values are: “ << x << “ “ << y << endl;return 0;
}
The values are: 4 5
Functions• Or we can use references:
void swap(int &a, int &b) {int c = a;a = b;b = c;return;
}
int main() {int x = 5, y = 4;swap(x,y);cout << “The values are: “ << x << “ “ << y << endl;return 0;
}
The values are: 4 5
Functions
• Do not return a reference to a local variable
// Disaster: Function returns a reference to a local objectconst string &manip(const string& s) {
string ret = s;// transform ret in some wayreturn ret; // Wrong: returning a reference to a local
object!}
Class Functions• Back to Sales_item
class Sales_item {public:
// operations on Sales_item objectsdouble avg_price() const;bool same_isbn(const Sales_item &rhs) const
{ return isbn == rhs.isbn }private:
std::string isbn;unsigned units_sold;double revenue;
}
Class Functions
• Looking at same_isbn:
bool same_isbn(const Sales_item &rhs) const{ return isbn == rhs.isbn }
• Body is a block• isbn is private, but this is not an error –
private members can be accessed by class functions
Class Functions
• Member functions of a class have an extra parameter that isn’t in the parameter list
• That parameter is this – a reference to the object on which the function was called
• It’s almost as if a call gets translated like so:
total.same_isbn(trans);
Sales_item::same_isbn(&total, trans);
Constructors• We’ve talked about the default constructor…
…but what’s a constructor?• A constructor is a member function that gets run when
an object of the type is initialized– In turn, constructors should make sure that every data
member is initialized• Constructors have the same name as the class• Sales_item needs to define the default constructor,
which takes no arguments• Constructors must be public, or it is not possible to
create objects of that type!
Constructorsclass Sales_item {
public:// operations on Sales_item objectsdouble avg_price() const;bool same_isbn(const Sales_item &rhs) const
{ return isbn == rhs.isbn }
// default constructor needed to initialize basic-type members
Sales_item(): units_sold(0), revenue(0.0) {}private:
std::string isbn;unsigned units_sold;double revenue;
}
Constructors• The colon and what follows is the constructor
initialization list• List of member names, followed by the initial
value in parentheses• We don’t need to specify an initial value for isbn,
since std::string has its own default constructor (makes it the empty string)
• If we don’t explicitly define a default constructor, a synthesized default constructor will be generated for us– Sets all basic types to 0; rest use default constructor
Overloaded Functions
• You can rewrite functions so that they behave differently when used with a different parameter list
• Sales_item will use this to redefine the basic operators
Sales_item class
• We had enough yesterday to start to write the headers
• Now we can finish writing the code!
Sales_item class
• Operations:– Use addition operator + to add two Sales_items– Use input operator << to read a Sales_item– Use output operator >> to write a Sales_item– Use assignment operator = to assign one
Sales_item to another– Call same_isbn function to see if two Sales_items
are the same book
Administrivia Updates
• Exam on Tuesday– First half of the class will be review / question
session; second half will be the midterm– Covering anything we did from this week
• Project #2 due date will be moved to Wednesday 10pm– Will be released tomorrow
• HW #2 still due beginning of class Tuesday