CS31 Discussion 1E Spring 17: week 08 TA: Bo-Jhang Ho - - PowerPoint PPT Presentation

cs31 discussion 1e
SMART_READER_LITE
LIVE PREVIEW

CS31 Discussion 1E Spring 17: week 08 TA: Bo-Jhang Ho - - PowerPoint PPT Presentation

CS31 Discussion 1E Spring 17: week 08 TA: Bo-Jhang Ho bojhang@cs.ucla.edu Credit to former TA Chelsea Ju Project 5 - Map cipher to crib } Approach 1: For each pair of positions, check two letters in cipher and crib are both identical or


slide-1
SLIDE 1

CS31 Discussion 1E

Spring 17’: week 08

TA: Bo-Jhang Ho

bojhang@cs.ucla.edu

Credit to former TA Chelsea Ju

slide-2
SLIDE 2

Project 5 - Map cipher to crib

} Approach 1: For each pair of positions, check two letters

in cipher and crib are both identical or different

} For each pair of positions pos1 and pos2,

cipher[pos1] == cipher[pos2] should equal to crib[pos1] == crib[pos2] } Approach 2: Get the positions of the letter and compare

} For each position pos,

indexes1 = getAllPositions(cipher, pos, cipher[pos]) indexes2 = getAllPositions(crib, pos, crib[pos]) indexes1 should equal to indexes2

slide-3
SLIDE 3

Project 5 - Map cipher to crib

} Approach 3: Generate the mapping

} We first have a mapping array char cipher2crib[128] = {‘\0’}; } Then whenever we attempt to map letterA in cipher to letterB

in crib, we first check whether it violates the previous setup:

} Is cipher2crib[letterA] != ‘\0’?

// implies letterA has been used

} Then cipher2crib[letterA] should equal to letterB

} If no violation happens,

} cipher2crib[letterA] = letterB;

slide-4
SLIDE 4

Road map of CS31

Variable If / else Loops Pointer!! Array Function Class String

slide-5
SLIDE 5

Cheat sheet

Data type

} int *a;

} a is a variable, whose data type is int * } a stores an address of some integer

“Use as verbs”

} & - address-of operator

} &b means I want to get the memory address of variable b

} * - dereference operator

} *c means I want to retrieve the value in address c

slide-6
SLIDE 6

Memory model

Address Memory Contents

1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019

1 byte

slide-7
SLIDE 7

Memory model

Address Memory Contents

1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019

1 byte = 8 bits

  • ff
  • n

A bit has 2 states

slide-8
SLIDE 8

Memory model

Address Memory Contents

1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019

1 byte = 8 bits

  • ff
  • n

A bit has 2 states A byte has 256 (=28) states

slide-9
SLIDE 9

Memory model

Address Memory Contents

1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019

1 byte = 8 bits

  • ff
  • n

A bit has 2 states A byte has 256 (=28) states A char takes 1 byte An int takes 4 bytes A double takes 8 bytes

slide-10
SLIDE 10

Data type review

} Basic data types

Type Bytes Bits Value range char 1 8

  • 128 to 127

short 2 16

  • 32,768 to 32,767

int 4 32

  • 2,147,483,648 to 2,147,483,647

long long 8 64

  • 9 * 10^18 to 9 * 10^18

float 4 32

  • 3.4 * 10^38 to 3.4 * 10^38

double 8 64

  • 1.7 * 10^308 to 1.7 * 10^308
slide-11
SLIDE 11

Memory model

Address Memory Contents

1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019

1 byte = 8 bits

  • ff
  • n

A bit has 2 states A byte has 256 (=28) states My has 16GB ram

slide-12
SLIDE 12

Memory model

Address Memory Contents

1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019

1 byte = 8 bits

  • ff
  • n

A bit has 2 states A byte has 256 (=28) states My has 16GB ram = 16,000,000,000 bytes!

slide-13
SLIDE 13

What’s going on in the memory

int main() { int a = 5; int b = 3; double c = 3.5; int d = b - a; return 0; } Address Memory Contents

1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019

slide-14
SLIDE 14

What’s going on in the memory

int main() { int a = 5; int b = 3; double c = 3.5; int d = b - a; return 0; } Address Memory Contents

1000

5

1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019

a

slide-15
SLIDE 15

What’s going on in the memory

int main() { int a = 5; int b = 3; double c = 3.5; int d = b - a; return 0; } Address Memory Contents

1000

5

1004

3

1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019

a b

slide-16
SLIDE 16

What’s going on in the memory

int main() { int a = 5; int b = 3; double c = 3.5; int d = b - a; return 0; } Address Memory Contents

1000

5

1004

3

1008

3.5

1016 1017 1018 1019

a b c

slide-17
SLIDE 17

What’s going on in the memory

int main() { int a = 5; int b = 3; double c = 3.5; int d = b - a; return 0; } Address Memory Contents

1000

5

1004

3

1008

3.5

1016

2

a b c d

slide-18
SLIDE 18

What’s going on in the memory

int main() { int a = 5; int *b = &a; a++; *b += 2; cout << a << endl; cout << *b << endl; return 0; } Address Memory Contents

1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019

slide-19
SLIDE 19

What’s going on in the memory

int main() { int a = 5; int *b = &a; a++; *b += 2; cout << a << endl; cout << *b << endl; return 0; } Address Memory Contents

1000

5

1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019

a

slide-20
SLIDE 20

What’s going on in the memory

int main() { int a = 5; int *b = &a; a++; *b += 2; cout << a << endl; cout << *b << endl; return 0; } Address Memory Contents

1000

5

1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019

a

slide-21
SLIDE 21

What’s going on in the memory

int main() { int a = 5; int *b; // declare a pointer var b = &a; // set address a++; *b += 2; cout << a << endl; cout << *b << endl; return 0; } Address Memory Contents

1000

5

1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019

a

slide-22
SLIDE 22

What’s going on in the memory

int main() { int a = 5; int *b; // declare a pointer var b = &a; // set address a++; *b += 2; cout << a << endl; cout << *b << endl; return 0; } Address Memory Contents

1000

5

1004

??

(address)

1012 1013 1014 1015 1016 1017 1018 1019

a b

slide-23
SLIDE 23

What’s going on in the memory

int main() { int a = 5; int *b; // declare a pointer var b = &a; // set address a++; *b += 2; cout << a << endl; cout << *b << endl; return 0; } Address Memory Contents

1000

5

1004

1000

(address)

1012 1013 1014 1015 1016 1017 1018 1019

a b

slide-24
SLIDE 24

What’s going on in the memory

int main() { int a = 5; int *b; // declare a pointer var b = &a; // set address a++; *b += 2; cout << a << endl; cout << *b << endl; return 0; } Address Memory Contents

1000

6

1004

1000

(address)

1012 1013 1014 1015 1016 1017 1018 1019

a b

5 à

slide-25
SLIDE 25

What’s going on in the memory

int main() { int a = 5; int *b; // declare a pointer var b = &a; // set address a++; *b += 2; cout << a << endl; cout << *b << endl; return 0; } Address Memory Contents

1000

8

1004

1000

(address)

1012 1013 1014 1015 1016 1017 1018 1019

a b

6 à

slide-26
SLIDE 26

What’s going on in the memory

int main() { int a = 5; int *b; // declare a pointer var b = &a; // set address a++; *b += 2; cout << a << endl; cout << *b << endl; return 0; } Address Memory Contents

1000

8

1004

1000

(address)

1012 1013 1014 1015 1016 1017 1018 1019

a b

} Output

} 8

slide-27
SLIDE 27

What’s going on in the memory

int main() { int a = 5; int *b; // declare a pointer var b = &a; // set address a++; *b += 2; cout << a << endl; cout << *b << endl; return 0; } Address Memory Contents

1000

8

1004

1000

(address)

1012 1013 1014 1015 1016 1017 1018 1019

a b

} Output

} 8

8

slide-28
SLIDE 28

Using uninitialized variables is always dangerous

int main() { int a; int b = a + 3; int *c; *c = 27; return 0; } Address Memory Contents

1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019

slide-29
SLIDE 29

Using uninitialized variables is always dangerous

int main() { int a; int b = a + 3; int *c; *c = 27; return 0; } Address Memory Contents

1000

??

1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019

a

slide-30
SLIDE 30

Using uninitialized variables is always dangerous

int main() { int a; int b = a + 3; int *c; *c = 27; return 0; } Address Memory Contents

1000

??

1004

??

1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019

a b

slide-31
SLIDE 31

Using uninitialized variables is always dangerous

int main() { int a; int b = a + 3; int *c; *c = 27; return 0; } Address Memory Contents

1000

??

1004

??

1008

??

(address)

1016 1017 1018 1019

a b c

slide-32
SLIDE 32

Using uninitialized variables is always dangerous

int main() { int a; int b = a + 3; int *c; *c = 27; return 0; } Address Memory Contents

1000

??

1004

??

1008

??

(address)

1016 1017 1018 1019

a b c

} May manipulate a piece of

memory not belonging to this program!!

slide-33
SLIDE 33

Array v.s. Pointer

Array is a special case of pointer Pointer can be treated as an array

slide-34
SLIDE 34

Array in memory

int main() { int a = 3; int b[5] = {10, 20, 30, 40, 50}; int *c = &b[1]; *c = 100; return 0; } Address Memory Contents

1000 1002 1004 1006 1008 1010 1012 1014 1016 1018 1020 1022 1024 1026 1028 1030 1032 1034 1036 1038

slide-35
SLIDE 35

Array in memory

int main() { int a = 3; int b[5] = {10, 20, 30, 40, 50}; int *c = &b[1]; *c = 100; return 0; } Address Memory Contents

1000

3

1004 1006 1008 1010 1012 1014 1016 1018 1020 1022 1024 1026 1028 1030 1032 1034 1036 1038

a

slide-36
SLIDE 36

Array in memory

int main() { int a = 3; int b[5] = {10, 20, 30, 40, 50}; int *c = &b[1]; *c = 100; return 0; } Address Memory Contents

1000

3

1004

10

1008

20

1012

30

1016

40

1020

50

1024 1026 1028 1030 1032 1034 1036 1038

a

b[0] b[1] b[2] b[3] b[4]

b

slide-37
SLIDE 37

Array in memory

int main() { int a = 3; int b[5] = {10, 20, 30, 40, 50}; int *c = &b[1]; *c = 100; return 0; } Address Memory Contents

1000

3

1004

10

1008

20

1012

30

1016

40

1020

50

1024 1026 1028 1030 1032 1034 1036 1038

a

b[0] b[1] b[2] b[3] b[4]

b

slide-38
SLIDE 38

Array in memory

int main() { int a = 3; int b[5] = {10, 20, 30, 40, 50}; int *c; // declare a pointer c = &b[1]; // get address *c = 100; return 0; } Address Memory Contents

1000

3

1004

10

1008

20

1012

30

1016

40

1020

50

1024 1026 1028 1030 1032 1034 1036 1038

a

b[0] b[1] b[2] b[3] b[4]

b

slide-39
SLIDE 39

Array in memory

int main() { int a = 3; int b[5] = {10, 20, 30, 40, 50}; int *c; // declare a pointer c = &b[1]; // get address *c = 100; return 0; } Address Memory Contents

1000

3

1004

10

1008

20

1012

30

1016

40

1020

50

1024

??

(address) 1032 1034 1036 1038

a

b[0] b[1] b[2] b[3] b[4]

b c

slide-40
SLIDE 40

Array in memory

int main() { int a = 3; int b[5] = {10, 20, 30, 40, 50}; int *c; // declare a pointer c = &b[1]; // get address *c = 100; return 0; } Address Memory Contents

1000

3

1004

10

1008

20

1012

30

1016

40

1020

50

1024

1008

(address) 1032 1034 1036 1038

a

b[0] b[1] b[2] b[3] b[4]

b c

slide-41
SLIDE 41

Array in memory

int main() { int a = 3; int b[5] = {10, 20, 30, 40, 50}; int *c; // declare a pointer c = &b[1]; // get address *c = 100; return 0; } Address Memory Contents

1000

3

1004

10

1008

100

1012

30

1016

40

1020

50

1024

1008

(address) 1032 1034 1036 1038

a

b[0] b[1] b[2] b[3] b[4]

b c

20 à

slide-42
SLIDE 42

Time and Delta analogy

Time Delta Time + = Delta Delta Delta + = Delta Time Time + = Time Time

Doesn’t make sense!

+ =

slide-43
SLIDE 43

Time and Delta analogy

+ = + = + =

Doesn’t make sense!

+ =

slide-44
SLIDE 44

Time and Delta analogy

Pointer Int Pointer + = Int Int Int + = Int Pointer Pointer + = Pointer Pointer

Doesn’t make sense!

+ =

slide-45
SLIDE 45

Time and Delta analogy

Time Delta Time

  • =

Delta Delta Delta

  • =

Delta Time

  • =

Time Time

  • =

??

Doesn’t make sense!

slide-46
SLIDE 46

Time and Delta analogy

Time Delta Time

  • =

Delta Delta Delta

  • =

Delta Time

  • =

Time Time

  • =

Delta

Doesn’t make sense!

slide-47
SLIDE 47

Time and Delta analogy

= = = =

  • Doesn’t

make sense!

slide-48
SLIDE 48

Time and Delta analogy

Pointer Int Pointer

  • =

Int Int Int

  • =

Int Pointer

  • =

Pointer Pointer

  • =

Int

Doesn’t make sense!

slide-49
SLIDE 49

Array in memory

int main() { int a = 3; int b[5] = {10, 20, 30, 40, 50}; int *c = &b[1]; c = c + 1; // Or, // c += 1; // c++; *c = 27; return 0; } Address Memory Contents

1000

3

1004

10

1008

20

1012

30

1016

40

1020

50

1024

1008

(address) 1032 1034 1036 1038

a

b[0] b[1] b[2] b[3] b[4]

b c

slide-50
SLIDE 50

Array in memory

int main() { int a = 3; int b[5] = {10, 20, 30, 40, 50}; int *c = &b[1]; c = c + 1; // Or, // c += 1; // c++; *c = 27; return 0; } Address Memory Contents

1000

3

1004

10

1008

20

1012

30

1016

40

1020

50

1024

1012

(address) 1032 1034 1036 1038

a

b[0] b[1] b[2] b[3] b[4]

b c

1008à

} What? 1008 + 1 = 1012?

slide-51
SLIDE 51

Array in memory

int main() { int a = 3; int b[5] = {10, 20, 30, 40, 50}; int *c = &b[1]; c = c + 1; // Or, // c += 1; // c++; *c = 27; return 0; } Address Memory Contents

1000

3

1004

10

1008

20

1012

30

1016

40

1020

50

1024

1012

(address) 1032 1034 1036 1038

a

b[0] b[1] b[2] b[3] b[4]

b c

1008 à

} Pointer arithmetic

} We should interpret as adding

the memory size of 1 integer

slide-52
SLIDE 52

Array in memory

int main() { int a = 3; int b[5] = {10, 20, 30, 40, 50}; int *c = b; c += 2; *c = 27; return 0; } Address Memory Contents

1000

3

1004

10

1008

20

1012

30

1016

40

1020

50

1024

1004

(address) 1032 1034 1036 1038

a

b[0] b[1] b[2] b[3] b[4]

b c

} Array name is a pointer

} b can be treated as an int*

slide-53
SLIDE 53

Array in memory

int main() { int a = 3; int b[5] = {10, 20, 30, 40, 50}; int *c = b; c += 2; *c = 27; return 0; } Address Memory Contents

1000

3

1004

10

1008

20

1012

30

1016

40

1020

50

1024

1012

(address) 1032 1034 1036 1038

a

b[0] b[1] b[2] b[3] b[4]

b c

} Array name is a pointer

} b can be treated as an int*

1004à

slide-54
SLIDE 54

Array in memory

int main() { int a = 3; int b[5] = {10, 20, 30, 40, 50}; int *c = b; c += 2; *c = 27; return 0; } Address Memory Contents

1000

3

1004

10

1008

20

1012

27

1016

40

1020

50

1024

1012

(address) 1032 1034 1036 1038

a

b[0] b[1] b[2] b[3] b[4]

b c

} Array name is a pointer

} b can be treated as an int*

30 à

slide-55
SLIDE 55

More about array

} Array name can be considered as start point

} Technically, it’s the base address

} The index can be considered as the offset

slide-56
SLIDE 56

More about array

int main() { int a = 3; int b[5] = {10, 20, 30, 40, 50}; int *c = b; cout << b[-1] << endl; return 0; } Address Memory Contents

1000

3

1004

10

1008

20

1012

27

1016

40

1020

50

1024

1004

(address) 1032 1034 1036 1038

a

b[0] b[1] b[2] b[3] b[4]

b c

b[0] b[-1] b[1] b[2] b[3] b[4] b[5] b[6] b[7] b[8] b[9] b[-2] b[-3] b[-4]

slide-57
SLIDE 57

Use pointer like an array

} If x is a pointer, you can treat x as an array

} Meaning, you can have something like x[3]

slide-58
SLIDE 58

Treat pointer as an array

int main() { int a = 3; int b[5] = {10, 20, 30, 40, 50}; int *c = b + 2; cout << c[-2] << endl; return 0; } Address Memory Contents

1000

3

1004

10

1008

20

1012

27

1016

40

1020

50

1024

1012

(address) 1032 1034 1036 1038

a

b[0] b[1] b[2] b[3] b[4]

b c

slide-59
SLIDE 59

Treat pointer as an array

int main() { int a = 3; int b[5] = {10, 20, 30, 40, 50}; int *c = b + 2; cout << c[-2] << endl; return 0; } Address Memory Contents

1000

3

1004

10

1008

20

1012

27

1016

40

1020

50

1024

1012

(address) 1032 1034 1036 1038

a

b[0] b[1] b[2] b[3] b[4]

b c

c[0]

slide-60
SLIDE 60

Treat pointer as an array

int main() { int a = 3; int b[5] = {10, 20, 30, 40, 50}; int *c = b + 2; cout << c[-2] << endl; return 0; } Address Memory Contents

1000

3

1004

10

1008

20

1012

27

1016

40

1020

50

1024

1012

(address) 1032 1034 1036 1038

a

b[0] b[1] b[2] b[3] b[4]

b c

c[0] c[1] c[2] c[3] c[4] c[5] c[6] c[7]

slide-61
SLIDE 61

Treat pointer as an array

int main() { int a = 3; int b[5] = {10, 20, 30, 40, 50}; int *c = b + 2; cout << c[-2] << endl; return 0; } Address Memory Contents

1000

3

1004

10

1008

20

1012

27

1016

40

1020

50

1024

1012

(address) 1032 1034 1036 1038

a

b[0] b[1] b[2] b[3] b[4]

b c

c[-2] c[-3] c[-1] c[0] c[1] c[2] c[3] c[4] c[5] c[6] c[7] c[-4] c[-6]

slide-62
SLIDE 62

Treat pointer as an array

int main() { int a = 3; int b[5] = {10, 20, 30, 40, 50}; int *c = b + 2; cout << c[-2] << endl; return 0; } Address Memory Contents

1000

3

1004

10

1008

20

1012

27

1016

40

1020

50

1024

1012

(address) 1032 1034 1036 1038

a

b[0] b[1] b[2] b[3] b[4]

b c

c[-2] c[-3] c[-1] c[0] c[1] c[2] c[3] c[4] c[5] c[6] c[7] c[-4] c[-6]

} It is actually a valid

memory access

slide-63
SLIDE 63

Summary

} Array name is a pointer } Pointer arithmetic

} Let’s say x is a pointer, n is an integer } x + n is a pointer (memory address) after n elements of x } x - n is a pointer before n elements of x

} Treat a pointer as an array

} Again, let’s say x is a pointer, n is an integer } x[n] means to access nth element counted from x } x[n] equivalent to *(x + n)

slide-64
SLIDE 64

Remind a previous example 01 - Pass an array to a function

} From caller: } In the function:

  • r
  • r

int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; foo(arr); void foo(int params[10]) { … } void foo(int params[]) { … } void foo(int *params) { … }

slide-65
SLIDE 65

Remind a previous example 02 - Mapping of cipher and crib in project 5

} Approach 3: Generate the mapping

} We first have a mapping array char cipher2crib[128] = {‘\0’};

} Whenever we attempt to map letterA in cipher to letterB in crib: } cipher2crib[letterA] = letterB;

} But there are only 26 letters. Why do we want to have an array

with 128 elements?

} We use ascii as a key (a.k.a index) in the array } We don’t need to worry about the offset (i.e., x - ‘a’)

} Is there any solution to reduce the size to 26?

slide-66
SLIDE 66

Remind a previous example 02 - Mapping of cipher and crib in project 5

bool check(const char cipher[], const char crib[]) { // assume cipher and crib have the same length char cipher2crib[128] = {'\0'}; for (int i = 0; cipher[i] != '\0'; i++) { char letterA = cipher[i]; char letterB = crib[i]; if (cipher2crib[letterA] != '\0’ && cipher2crib[letterA] != letterB) return false; cipher2crib[letterA] = letter } return true; }

slide-67
SLIDE 67

Remind a previous example 02 - Mapping of cipher and crib in project 5

bool check(const char cipher[], const char crib[]) { // assume cipher and crib have the same length char trueArray[26] = {'\0'}; char *cipher2crib = trueArray – 'a'; for (int i = 0; cipher[i] != '\0'; i++) { char letterA = cipher[i]; char letterB = crib[i]; if (cipher2crib[letterA] != '\0’ && cipher2crib[letterA] != letterB) return false; cipher2crib[letterA] = letter } return true; }

26 elements trueArray cipher2crib

97 elements

Memory footprint

slide-68
SLIDE 68

Question 01

} If we declare int *ptr; and int val;, the

following two usages are valid:

} ptr = &val; } *ptr = val;

} What is &ptr?

slide-69
SLIDE 69

Question 01

} If we declare int *ptr; and int val;, the

following two usages are valid:

} ptr = &val; } *ptr = val;

} What is &ptr?

} &ptr means the address of ptr } The type of &ptr is int** (we call it double pointer) } For example, int** strongPtr = &ptr;

slide-70
SLIDE 70

Double pointer

int main() { int a = 3; int *b = &a; int c[5] = {10, 20, 30, 40, 50}; int** d = &b; return 0; } Address Memory Contents

1000

3

1004 1006 1008 1010 1012 1014 1016 1018 1020 1022 1024 1026 1028 1030 1032 1034 1036 1038

a

slide-71
SLIDE 71

Double pointer

int main() { int a = 3; int *b = &a; int c[5] = {10, 20, 30, 40, 50}; int** d = &b; return 0; } Address Memory Contents

1000

3

1004

1000

(address) 1012 1014 1016 1018 1020 1022 1024 1026 1028 1030 1032 1034 1036 1038

a b

slide-72
SLIDE 72

Double pointer

int main() { int a = 3; int *b = &a; int c[5] = {10, 20, 30, 40, 50}; int** d = &b; return 0; } Address Memory Contents

1000

3

1004

1000

(address) 1012

10

1016

20

1020

30

1024

40

1028

50

1032 1034 1036 1038

a b

c[0] c[1] c[2] c[3] c[4]

c

slide-73
SLIDE 73

Double pointer

int main() { int a = 3; int *b = &a; int c[5] = {10, 20, 30, 40, 50}; int** d = &b; return 0; } Address Memory Contents

1000

3

1004

1000

(address) 1012

10

1016

20

1020

30

1024

40

1028

50

1032

1004

(address)

a b

c[0] c[1] c[2] c[3] c[4]

c d

slide-74
SLIDE 74

Question 02

} If we declare int *ptr; and int val;, the

following two usages are valid:

} ptr = &val; } *ptr = val;

} What is *val?

slide-75
SLIDE 75

Question 02

} If we declare int *ptr; and int val;, the

following two usages are valid:

} ptr = &val; } *ptr = val;

} What is *val?

} It won’t compile } * operator (dereference) implies that what it stores is a

memory address

} Only pointer variables store memory address

slide-76
SLIDE 76

Different levels of pointers

If we have

int val; int* ptr1; int** ptr2; int*** ptr3; int**** ptr4; int***** ptr5;

Then they have the following relations

ptr1 = &val; ptr2 = &ptr1; ptr3 = &ptr2; ptr4 = &ptr3; ptr5 = &ptr4; val = *ptr1; ptr1 = *ptr2; ptr2 = *ptr3; ptr3 = *ptr4; ptr4 = *ptr5;

Address of Deference

slide-77
SLIDE 77

Question 03

} If we declare int *ptr;, can we hardcode an address

and assign to ptr?

} For example, ptr = 1234;

} No, it won’t compile

} For security issue } It doesn’t make sense that we can get an address beforehand } The same variable can reside in different parts of memory in

different executions

slide-78
SLIDE 78

Question 03

int main() { int a; cout << &a << endl; return 0; }

slide-79
SLIDE 79

Question 04

} If we declare int *ptr; and double val;, is the

following code valid?

} ptr = &val;

slide-80
SLIDE 80

Question 04

} If we declare int *ptr; and double val;, is the

following code valid?

} ptr = &val;

} No, it won’t compile

} Pointers are type-aware } We can cast the type: ptr = (int*) &val; } However, that means we use the way we interpret integer to

intepret a piece of memory which stores a double

slide-81
SLIDE 81

Array in memory

int main() { double a = 3.5; int *b = (int*) &a; cout << *b << endl; return 0; } Address Memory Contents

1000

3.5

1008

1000

(address) 1016 1018 1020 1022 1024 1026 1028 1030 1032 1034 1036 1038

a b

slide-82
SLIDE 82

Array in memory

int main() { double a = 3.5; int *b = (int*) &a; cout << *b << endl; return 0; } Address Memory Contents

1000

3.5

1008

1000

(address) 1016 1018 1020 1022 1024 1026 1028 1030 1032 1034 1036 1038

a b

slide-83
SLIDE 83

Question 05

} If we declare int *ptrI; and double *ptrD;,

can we have the following assignment?

} ptrI = ptrD;

} No, it won’t compile

} Pointer type doesn’t match } Though both store memory addresses, how they interpret the

memory content are different

} We can cast the type: ptrI = (int*) ptrD;

slide-84
SLIDE 84

Checkpoint – Looping over the array

double* findFirstNegativePtr(double a[], int n) { for (double* p = a; p < a + n; p++) { if (*p < 0) return p; } return nullptr; }

} Return a pointer

int findFirstNegativeIdx(double a[], int n) { for (int i = 0; i < n; i++) { if (a[i] < 0) return i; } return -1; }

} Return an index

slide-85
SLIDE 85

Project 6

} Problem 1b probably is the most tricky question.

slide-86
SLIDE 86

Road map of CS31

Variable If / else Loops Pointer!! Array Function Class String

slide-87
SLIDE 87

Class

} Define a data structure } A data structure groups different “variables” together } For example, when we describe a 2d coordinate, naturally

we use 2 numbers to represent it

} We can also say we declare a new data type

slide-88
SLIDE 88

Example

// create a new data type class Point { public: double x; double y; }; // how we use it int main() { Point p; p.x = 1.1; p.y = 2.2; Point r = p; r.y = 3.3; cout << "Point 1: " << p.x << " " << p.y << endl; cout << "Point 2: " << r.x << " " << r.y << endl; return 0; }