Download presentation
Presentation is loading. Please wait.
Published byPeter Townsend Modified over 9 years ago
1
C++ crash course Class 7 more operators, expressions, statements
2
Agenda More operators! – getting values from combining operands Expressions – strings of tokens that return a value Statements – a line of code in C++
3
Assignment Operators Assignment operators An assignment is when we put a value in a variable Left-hand operand must be a non-const lvalue int i, j, ival; const int ci = i; // alright; initializing 1024 = ival; // bad i + j = ival; // bad ci = ival; // bad
4
Assignment Operators Array names are nonmodifiable: you can use subscript and dereference, but you can’t change the array itself int ia[10]; ia[0] = 0; // OK *ia = 0; // OK ia = ???; // bad!
5
Assignment Operator Result of an assignment is the left-hand operand; type is the type of the left-hand operand ival = 0; // result: type int value 0 ival = 3.14159; // result: type int value 3 What happens here? int i = 10, j = 5; i = j = 4;
6
Assignment Operator Result of an assignment is the left-hand operand; type is the type of the left-hand operand ival = 0; // result: type int value 0 ival = 3.14159; // result: type int value 3 What happens here? int i = 10, j = 5; i = j = 4;// assignment is right-associative
7
Assignment Operators Assignment is right-associative; other binary operators are left associative Result of the rightmost assignment is assigned going left int ival; int *pval; ival = pval = 0; // error: can’t assign the val of a pointer to an int string s1, s2; s1 = s2 = “OK”; // alright; “OK” the char * literal gets converted to a string
8
Assignment Operators Assignment has low precedence (happens last) int i = get_value(); while(i != 42) { i = get_value(); } How can we do this in one line?
9
Assignment Operators int i; while ((i = get_value()) != 42) { // do something } Without the parentheses, what happens? while (i = get_value() != 42) { // do something weird... }
10
Assignment Operators That means BE CAREFUL whether you are using the comparison operator == or the assignment operator =! if (i = 42) if (i == 42) What’s the difference?
11
Assignment Operators What are i and d after each assignment? int i; double d; d = i = 3.5; i = d = 3.5;
12
Assignment Operators What’s the difference here? if (42 = i) //... if (i = 42) //...
13
Compound Assignment Operators += -= *= /= %= // arithmetic operators (there are also bitwise operators, but we’re not going to talk about those) a = a op b; is the same as op= But the left-hand operand gets evaluated only once – mostly this doesn’t matter, except when it does (we might see cases of this later)
14
Assignment Operators This is illegal. Why? double dval; int ival; int *pi; dval = ival = pi = 0;
15
Assignment Operators These are legal, but they’re not going to do what you might expect them to... What should’ve been written? a)if (ptr = retrieve_pointer() != 0) b)if (ival = 1024) c)ival += ival + 1;
16
Assignment Operators Increment and decrement ++, -- int i = 0, j; j = ++i; // prefix j = i++; // postfix Note: prefix operator does less work! (Why?)
17
Assignment Operators Combining dereference and increment... vector ::iterator iter = ivec.begin(); while (iter != ivec.end()) cout << *iter++ << endl; // iterator postfix increment What gets printed out? Why?
18
Assignment Operators *iter++ : precedence of postfix increment is higher than the dereference operator *iter++ is the same as *(iter++)
19
Assignment Operators Even though it’s a little confusing, experienced C++ programmers are more likely to use this kind of expression (*iter++) – so if you see C++ code, this is probably what you’ll see!
20
Assignment Operators What would change if the while loop was written like so? vector ::iterator iter = ivec.begin(); while(iter != ivec.end()) cout << *++iter << endl;
21
Arrow Operator You’ve seen the dot operator... item1.same_isbn(item2); // run the same_isbn function of item1 anim1.same_animal(anim2); // run the same_animal function of anim1
22
Arrow Operator What if instead of having an explicit Animal_type, we instead have a pointer? Animal_type *ap = &anim1; (*ap).same_animal(anim2); But you have to be careful – what does this do? *ap.same_animal(anim2);
23
Arrow Operator Thus we have the arrow operator -> ap->same_animal(anim2); It’s just syntactic sugar, but makes it much easier not to make mistakes!
24
Arrow Operator Let’s write code: Define a vector of pointers to strings Read the vector, printing each string and its corresponding size
25
Arrow Operator Assume iter is a vector ::iterator Which of the following are legal? What do they do? a)*iter++; b)*iter.empty(); c)++*iter; d)(*iter)++; e)iter->empty(); f)iter++->empty();
26
Conditional Operator Ternary operator – takes 3 arguments cond ? expr1 : expr2; equivalent to if(cond) { expr1; } else { expr2; }
27
Conditional Operator int i = 10, j = 20, k = 30; int maxVal = i > j ? i : j; What’s maxVal after this?
28
Conditional Operator It’s a useful convention, but don’t abuse it int max = i > j ? i > k ? i : k : j > k ? j : k; What does the above do?
29
Conditional Operator Equivalent to this... int max = i; if (j > max) max = j; if (k > max) max = k;
30
Conditional Operator Fairly low precedence In an output expression: cout << (i < j ? i : j); // works as expected cout << (i < j) ? i : j; // prints 1 or 0 – why? cout << i < j ? i : j; // error – why?
31
Conditional Operator Writing code: Prompt the user for a pair of numbers, say which is smaller
32
Conditional Operator Write code Process elements in a vector, replacing any value that’s odd with twice its value
33
sizeof Operator Returns a value of type size_t Size in bytes of an object or type name – how much space it’s taking up in memory sizeof (type name); sizeof (expr); sizeof expr; (Remember when I said that doing ptr++ will cause it to move forward by a certain amount in memory?)
34
sizeof Operator Can be used in multiple ways... Animal_type anim, *pa; sizeof(Animal_type); sizeof anim; sizeof *pa;
35
sizeof Operator Evaluating sizeof expr does not evaluate the expression sizeof *p; // will work even if p is a null pointer or invalid address!
36
sizeof Operator Result of sizeof depends on the type involved – sizeof char or an expression of type char is 1 – sizeof a reference type returns the size of the memory necessary to contain an object of the referenced type – sizeof a pointer returns the size needed to hold a pointer; to obtain the size of the object, the pointer must be dereferenced – sizeof an array is equivalent to taking sizeof the element type, times the number of elements in the array
37
sizeof Operator We can figure out the number of elements in an array this way! – (since there’s no array.size()) How?
38
sizeof Operator What’s the output of this program going to be? [[ size of an int: 4 bytes; size of an int *: 8 bytes ]] int x[10];int *p = x; cout << sizeof(x) / sizeof(*x) << endl; cout << sizeof(p) / sizeof(*p) << endl;
39
Compound Expressions An expression with two or more operators is a compound expression Must understand how precedence and associativity work in order to evaluate expressions Precedence doesn’t necessarily specify order of evaluation, but it does determine what the answer will be
40
Precedence We saw this yesterday: – How does this get evaluated? 6 + 3 * 4 / 2 + 2; Parentheses can override precedence ((6 + ((3 * 4) / 2) + 2) vs ((6 + 3) * 4) / 2 + 2
41
Associativity Specifies how to group operators at the same precedence level Assignment is right associative Arithmetic is left associative
42
Associativity Parenthesize these: ival = jval = kval = lval; ival * jval / kval * lval;
43
Precedence When you know what the precedence is, it’s okay not to parenthesize – when you’re not sure, parenthesizing can help make sure that the program does what you want it to Helpful in debugging: getting a weird result? Add parentheses around the things you thought were getting evaluated first You can also look up the precedence for all the operators, but unless you’re an expert C++ programmer, it’s unlikely that you’ll be able to remember all of them Useful to know for any programming language
44
new and delete Has to do with allocating memory We talked about this with dynamic arrays We can also use it for single objects int i;// named, unitialized int int *pi = new int; // pi points to a dynamically allocated, unnamed, uninitialized int
45
new and delete We need to initialize dynamically allocated objects too, even if they’re not named int i(1024); int *pi = new int(1024); string s(10, ‘9’); string *ps = new string(10, ‘9’); Must use direct-initialization syntax, rather than copy- initialization, to initialize dynamically allocated objects
46
new and delete Without an explicit initializer, a dynamically allocated object is initialized in the same way as a variable inside a function If there’s a default constructor, uses that; if it’s built-in, it’s uninitialized After each line, which is / are initialized? string *ps = new string; int *pi = new int;
47
new and delete We can also value-initialize a dynamically allocated object Default constructor, or basic type to 0 string *ps = new string(); int *pi = new int(); cls *pc = new cls();
48
new and delete So that’s new......why do we have delete? Back in the day using new too many times could easily exhaust all your memory, causing a bad_alloc exception In order not to have our memory used up, we should free it using the delete expression delete pi; This will ONLY WORK for dynamically allocated variables; for all others it’s illegal – the behavior is undefined
49
new and delete int i; int *pi = &i; string str = “dwarves”; double *pd = new double(33); Which of these is safe? delete str; delete pi; delete pd;
50
new and delete int i; int *pi = &i; string str = “dwarves”; double *pd = new double(33); Which of these is safe? delete str; delete pi; // Watch out: some compilers will accept this even though it’s illegal! delete pd;
51
new and delete Once you delete a pointer to an object, you’ve deleted the object, but the pointer still hangs around, pointing to that spot in memory Called a dangling pointer Watch out for these! – Best to set any pointers you’ve deleted to 0 (null pointer)
52
new and delete Which of these are okay? Which are illegal / error-producing? a)vector svec(10); b)vector *pvec1 = new vector (10); c)vector **pvec2 = new vector [10]; d)vector *pv1 = &svec; e)vector *pv2 = pvec1; f)delete svec; g)delete pvec1; h)delete [] pvec2; i)delete pv1; j)delete pv2;
53
Type Conversions We discussed these a little bit yesterday: typecasting Types of operands determine whether an expression is legal – if the types are related in C++, then there’s a conversion int ival = 0; ival = 3.541 + 3; // compiles, sometimes gives warning
54
Type Conversions C++ has a set of conversions that make the operands the same before doing the arithmetic These conversions are done automatically by the compiler, called implicit type conversions Built-in conversions preserve precision if possible
55
Type Conversions When is an implicit type conversion going to occur? – Expressions with mixed-type operands: int ival; double dval; ival >= dval; // ival converted to double – Expression used as a condition goes to bool int ival; if (ival) while (cin) – An expression used to initialize or assign to a variable is converted to the type of the variable int ival = 3.14; int *ip; ip = 0;
56
Type Conversions Simplest conversion: integral promotions char, signed char, unsigned char, short, and unsigned short can all get promoted to int If the values don’t fit, promoted to unsigned int For bools: false -> 0 true -> 1
57
Type Conversions Pointer conversions When we use an array, the array is converted to a pointer to the first element: int ia[10]; int * ip = ia;
58
Type Conversions Enumeration conversions: // point2d is 2, point2w is 3, point3d is 3, point3w is 4 enum Points { point2d = 2, point2w, point3d = 3, point3w }; const size_t array_size = 1024; int chunk_size = array_size * point2w; int array_3d = array_size * point3d;
59
Type Conversions What conversions are happening here? float fval; double dval; int ival; a)if (fval) b)dval = fval + ival; c)dval + ival + cval;
60
Type Conversions We can also explicitly cast one type to another This is necessary sometimes, but dangerous – part of memory is suddenly being re-interpreted! Really useful in terms of arithmetic, which is pretty much the only time you’ll need it How can we make integer division work?
Similar presentations
© 2024 SlidePlayer.com Inc.
All rights reserved.