CS31 Discussion 1E Spring 17’: week 08

TA: Bo-Jhang Ho [email protected]

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 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 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; Road map of CS31

String

Array Function Class

Variable If / else Loops Pointer!! Cheat sheet

Data type

} int *a; } a is a variable, whose 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 Memory model

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

Address Memory Contents 1000 1 byte = 8 1001 1002 1003 off on 1004 1005 1006 1007 1008 1009 A has 2 states 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 Memory model

Address Memory Contents 1000 1 byte = 8 bits 1001 1002 1003 off on 1004 1005 1006 1007 1008 1009 A bit has 2 states 1010 8 1011 A byte has 256 (=2 ) states 1012 1013 1014 1015 1016 1017 1018 1019 Memory model

Address Memory Contents 1000 1 byte = 8 bits 1001 1002 1003 off on 1004 1005 1006 1007 1008 1009 A bit has 2 states 1010 8 1011 A byte has 256 (=2 ) states 1012 1013 1014 A char takes 1 byte 1015 An int takes 4 1016 1017 A double takes 8 bytes 1018 1019 review

} Basic data types Ty p e 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 Memory model

Address Memory Contents 1000 1 byte = 8 bits 1001 1002 1003 off on 1004 1005 1006 1007 1008 1009 A bit has 2 states 1010 8 1011 A byte has 256 (=2 ) states 1012 1013 1014 1015 My has 16GB ram 1016 1017 1018 1019 Memory model

Address Memory Contents 1000 1 byte = 8 bits 1001 1002 1003 off on 1004 1005 1006 1007 1008 1009 A bit has 2 states 1010 8 1011 A byte has 256 (=2 ) states 1012 1013 1014 1015 My has 16GB ram 1016 1017 1018 = 16,000,000,000 bytes! 1019 What’s going on in the memory

Address Memory Contents 1000 int main() { 1001 int a = 5; 1002 int b = 3; 1003 double c = 3.5; int d = b - a; 1004 1005 return 0; 1006 } 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 What’s going on in the memory

Address Memory Contents 1000 int main() { a int a = 5; 5 int b = 3; double c = 3.5; int d = b - a; 1004 1005 return 0; 1006 } 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 What’s going on in the memory

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

1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 What’s going on in the memory

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

1008 c 3.5

1016 1017 1018 1019 What’s going on in the memory

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

1008 c 3.5

1016 d 2 What’s going on in the memory

Address Memory Contents 1000 int main() { 1001 int a = 5; 1002 int *b = &a; 1003 a++; 1004 *b += 2; 1005 1006 cout << a << endl; 1007 cout << *b << endl; 1008 1009 return 0; 1010 } 1011 1012 1013 1014 1015 1016 1017 1018 1019 What’s going on in the memory

Address Memory Contents 1000 int main() { a int a = 5; 5 int *b = &a;

a++; 1004 *b += 2; 1005 1006 cout << a << endl; 1007 cout << *b << endl; 1008 1009 return 0; 1010 } 1011 1012 1013 1014 1015 1016 1017 1018 1019 What’s going on in the memory

Address Memory Contents 1000 int main() { a int a = 5; 5 int *b = &a;

a++; 1004 *b += 2; 1005 1006 cout << a << endl; 1007 cout << *b << endl; 1008 1009 return 0; 1010 } 1011 1012 1013 1014 1015 1016 1017 1018 1019 What’s going on in the memory

Address Memory Contents 1000 int main() { a int a = 5; 5 int *b; // declare a pointer var b = &a; // address

1004 a++; 1005 *b += 2; 1006 1007 cout << a << endl; 1008 cout << *b << endl; 1009 1010 return 0; } 1011 1012 1013 1014 1015 1016 1017 1018 1019 What’s going on in the memory

Address Memory Contents 1000 int main() { a int a = 5; 5 int *b; // declare a pointer var b = &a; // set address

1004 a++; *b += 2; b ?? cout << a << endl; (address) cout << *b << endl;

return 0; }

1012 1013 1014 1015 1016 1017 1018 1019 What’s going on in the memory

Address Memory Contents 1000 int main() { a int a = 5; 5 int *b; // declare a pointer var b = &a; // set address

1004 a++; *b += 2; b 1000 cout << a << endl; (address) cout << *b << endl;

return 0; }

1012 1013 1014 1015 1016 1017 1018 1019 What’s going on in the memory

Address Memory Contents 1000 int main() { a int a = 5; 5 à 6 int *b; // declare a pointer var b = &a; // set address

1004 a++; *b += 2; b 1000 cout << a << endl; (address) cout << *b << endl;

return 0; }

1012 1013 1014 1015 1016 1017 1018 1019 What’s going on in the memory

Address Memory Contents 1000 int main() { a int a = 5; 6 à 8 int *b; // declare a pointer var b = &a; // set address

1004 a++; *b += 2; b 1000 cout << a << endl; (address) cout << *b << endl;

return 0; }

1012 1013 1014 1015 1016 1017 1018 1019 What’s going on in the memory

Address Memory Contents 1000 int main() { a int a = 5; 8 int *b; // declare a pointer var b = &a; // set address

1004 a++; *b += 2; b 1000 cout << a << endl; (address) cout << *b << endl;

return 0; }

1012 1013 } Output 1014 1015 } 8 1016 1017 1018 1019 What’s going on in the memory

Address Memory Contents 1000 int main() { a int a = 5; 8 int *b; // declare a pointer var b = &a; // set address

1004 a++; *b += 2; b 1000 cout << a << endl; (address) cout << *b << endl;

return 0; }

1012 1013 } Output 1014 1015 } 8 1016 8 1017 1018 1019 Using uninitialized variables is always dangerous

Address Memory Contents 1000 int main() { 1001 int a; 1002 int b = a + 3; 1003 int *c; 1004 *c = 27; 1005 1006 return 0; 1007 } 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 Using uninitialized variables is always dangerous

Address Memory Contents 1000 int main() { a int a; ?? int b = a + 3; int *c;

1004 *c = 27; 1005 1006 return 0; 1007 } 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 Using uninitialized variables is always dangerous

Address Memory Contents 1000 int main() { a int a; ?? int b = a + 3; int *c;

1004 *c = 27; b ?? return 0; } 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 Using uninitialized variables is always dangerous

Address Memory Contents 1000 int main() { a int a; ?? int b = a + 3; int *c;

1004 *c = 27; b ?? return 0; } 1008 c ?? (address)

1016 1017 1018 1019 Using uninitialized variables is always dangerous

Address Memory Contents 1000 int main() { a int a; ?? int b = a + 3; int *c;

1004 *c = 27; b ?? return 0; } 1008 c ?? } May manipulate a piece of (address) memory not belonging to this program!!

1016 1017 1018 1019 Array v.s. Pointer

Array is a special case of pointer

Pointer can be treated as an array Array in memory

Address Memory Contents 1000 int main() { 1002 int a = 3; 1004 int b[5] = {10, 20, 30, 40, 50}; 1006 int *c = &b[1]; 1008 *c = 100; 1010 1012 return 0; 1014 } 1016 1018 1020 1022 1024 1026 1028 1030 1032 1034 1036 1038 Array in memory

Address Memory Contents a 1000 int main() { 3 int a = 3; 1004 int b[5] = {10, 20, 30, 40, 50}; 1006 int *c = &b[1]; 1008 *c = 100; 1010 1012 return 0; 1014 } 1016 1018 1020 1022 1024 1026 1028 1030 1032 1034 1036 1038 Array in memory

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

1008 b[1] 20 *c = 100;

1012 b b[2] 30 return 0; } 1016 b[3] 40

1020 b[4] 50

1024 1026 1028 1030 1032 1034 1036 1038 Array in memory

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

1008 b[1] 20 *c = 100;

1012 b b[2] 30 return 0; } 1016 b[3] 40

1020 b[4] 50

1024 1026 1028 1030 1032 1034 1036 1038 Array in memory

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

1020 b[4] 50

1024 1026 1028 1030 1032 1034 1036 1038 Array in memory

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

1020 b[4] 50

1024 c ?? (address)

1032 1034 1036 1038 Array in memory

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

1020 b[4] 50

1024 c 1008 (address)

1032 1034 1036 1038 Array in memory

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

1020 b[4] 50

1024 c 1008 (address)

1032 1034 1036 1038 Time and Delta analogy

Time + Delta = Time

Delta + Delta = Delta

Delta + Time = Time

Doesn’t Time + Time = make sense! Time and Delta analogy

+ =

+ =

+ =

Doesn’t + = make sense! Time and Delta analogy

Pointer + Int = Pointer

Int + Int = Int

Int + Pointer = Pointer

Doesn’t Pointer + Pointer = make sense! Time and Delta analogy

Time - Delta = Time

Delta - Delta = Delta

Doesn’t Delta - Time = make sense! Time - Time = ?? Time and Delta analogy

Time - Delta = Time

Delta - Delta = Delta

Doesn’t Delta - Time = make sense! Time - Time = Delta Time and Delta analogy

- =

- =

Doesn’t - = make sense! - = Time and Delta analogy

Pointer - Int = Pointer

Int - Int = Int

Doesn’t Int - Pointer = make sense! Pointer - Pointer = Int Array in memory

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

1008 b[1] 20 c = c + 1; // Or, // c += 1; 1012 b b[2] 30 // c++;

1016 *c = 27; b[3] 40

1020 return 0; b[4] 50 }

1024 c 1008 (address)

1032 1034 1036 1038 Array in memory

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

1008 b[1] 20 c = c + 1; // Or, // c += 1; 1012 b b[2] 30 // c++;

1016 *c = 27; b[3] 40

1020 return 0; b[4] 50 }

1024 c 1008à 1012 } (address) What? 1008 + 1 = 1012?

1032 1034 1036 1038 Array in memory

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

1008 b[1] 20 c = c + 1; // Or, // c += 1; 1012 b b[2] 30 // c++;

1016 *c = 27; b[3] 40

1020 return 0; b[4] 50 }

1024 c 1008 à 1012 } (address) Pointer arithmetic } We should interpret as adding 1032 1034 the memory size of 1 integer 1036 1038 Array in memory

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

1008 b[1] 20 c += 2; *c = 27; 1012 b b[2] 30 return 0; 1016 } b[3] 40

1020 b[4] 50 } Array name is a pointer 1024 } b can be treated as an int* c 1004 (address)

1032 1034 1036 1038 Array in memory

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

1008 b[1] 20 c += 2; *c = 27; 1012 b b[2] 30 return 0; 1016 } b[3] 40

1020 b[4] 50 } Array name is a pointer 1024 } b can be treated as an int* c 1004à 1012 (address)

1032 1034 1036 1038 Array in memory

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

1008 b[1] 20 c += 2; *c = 27; 1012 b b[2] 30 à 27 return 0; 1016 } b[3] 40

1020 b[4] 50 } Array name is a pointer 1024 } b can be treated as an int* c 1012 (address)

1032 1034 1036 1038 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 b[-4] More about array b[-3]

Address Memory Contents b[-2] 1000 a 3 b[-1]

1004 b[0] 10 b[0]

1008 b[1] 20 b[1]

1012 b b[2] 27 b[2]

1016 b[3] 40 b[3]

1020 b[4] b[4] 50 int main() { 1024 int a = 3; b[5] int b[5] = {10, 20, 30, 40, 50}; c 1004 int *c = b; (address) b[6] cout << b[-1] << endl; 1032 b[7] 1034 return 0; 1036 } b[8] 1038

b[9] 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] Treat pointer as an array

Address Memory Contents 1000 a 3

1004 b[0] 10

1008 b[1] 20

1012 b b[2] 27 int main() { 1016 b[3] 40 int a = 3; int b[5] = {10, 20, 30, 40, 50}; 1020 b[4] 50 int *c = b + 2;

1024 cout << c[-2] << endl;

c 1012 return 0; (address) }

1032 1034 1036 1038 Treat pointer as an array

Address Memory Contents 1000 a 3

1004 b[0] 10

1008 b[1] 20

1012 b b[2] 27 c[0] int main() { 1016 b[3] 40 int a = 3; int b[5] = {10, 20, 30, 40, 50}; 1020 b[4] 50 int *c = b + 2;

1024 cout << c[-2] << endl;

c 1012 return 0; (address) }

1032 1034 1036 1038 Treat pointer as an array

Address Memory Contents 1000 a 3

1004 b[0] 10

1008 b[1] 20

1012 b b[2] 27 c[0] int main() { 1016 b[3] 40 c[1] int a = 3; int b[5] = {10, 20, 30, 40, 50}; 1020 b[4] 50 c[2] int *c = b + 2;

1024 cout << c[-2] << endl; c[3] c 1012 return 0; (address) c[4] }

1032 c[5] 1034 1036 c[6] 1038

c[7] c[-6] Treat pointer as an array

Address Memory Contents c[-4] 1000 a 3 c[-3]

1004 b[0] 10 c[-2]

1008 b[1] 20 c[-1]

1012 b b[2] 27 c[0] int main() { 1016 b[3] 40 c[1] int a = 3; int b[5] = {10, 20, 30, 40, 50}; 1020 b[4] 50 c[2] int *c = b + 2;

1024 cout << c[-2] << endl; c[3] c 1012 return 0; (address) c[4] }

1032 c[5] 1034 1036 c[6] 1038

c[7] c[-6] Treat pointer as an array

Address Memory Contents c[-4] 1000 a 3 c[-3]

1004 b[0] 10 c[-2]

1008 b[1] 20 c[-1]

1012 b b[2] 27 c[0] int main() { 1016 b[3] 40 c[1] int a = 3; int b[5] = {10, 20, 30, 40, 50}; 1020 b[4] 50 c[2] int *c = b + 2;

1024 cout << c[-2] << endl; c[3] c 1012 return 0; (address) c[4] }

1032 c[5] } 1034 It is actually a valid 1036 c[6] memory access 1038

c[7] 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) Remind a previous example 01 - Pass an array to a function

} From caller: int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; foo(arr);

} In the function: void foo(int params[10]) { … } or void foo(int params[]) { … } or void foo(int *params) { … } 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? 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; } 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; }

97 elements 26 elements Memory footprint cipher2crib trueArray Question 01

} If we declare int *ptr; and int val;, the following two usages are valid: } ptr = &val; } *ptr = val; } What is &ptr? 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; Double pointer

Address Memory Contents a 1000 int main() { 3 int a = 3; 1004 int *b = &a; 1006 int c[5] = {10, 20, 30, 40, 50}; int** d = &b; 1008 1010 return 0; 1012 } 1014 1016 1018 1020 1022 1024 1026 1028 1030 1032 1034 1036 1038 Double pointer

Address Memory Contents a 1000 int main() { 3 int a = 3; 1004 int *b = &a; int c[5] = {10, 20, 30, 40, 50}; b 1000 int** d = &b; (address) return 0; 1012 } 1014 1016 1018 1020 1022 1024 1026 1028 1030 1032 1034 1036 1038 Double pointer

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

1016 c[1] 20

1020 c c[2] 30

1024 c[3] 40

1028 c[4] 50

1032 1034 1036 1038 Double pointer

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

1016 c[1] 20

1020 c c[2] 30

1024 c[3] 40

1028 c[4] 50

1032 d 1004 (address) Question 02

} If we declare int *ptr; and int val;, the following two usages are valid: } ptr = &val; } *ptr = val; } What is *val? 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 Different levels of pointers If we have Then they have the following relations

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

ptr3 = &ptr2; ptr2 = *ptr3;

ptr2 = &ptr1; ptr1 = *ptr2;

ptr1 = &val; val = *ptr1; Address of Deference 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 Question 03

int main() { int a;

cout << &a << endl;

return 0; } Question 04

} If we declare int *ptr; and double val;, is the following code valid? } ptr = &val; 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 Array in memory

Address Memory Contents 1000 int main() { a double a = 3.5; 3.5 int *b = (int*) &a;

cout << *b << endl; 1008 b 1000 return 0; (address) }

1016 1018 1020 1022 1024 1026 1028 1030 1032 1034 1036 1038 Array in memory

Address Memory Contents 1000 int main() { a double a = 3.5; 3.5 int *b = (int*) &a;

cout << *b << endl; 1008 b 1000 return 0; (address) }

1016 1018 1020 1022 1024 1026 1028 1030 1032 1034 1036 1038 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; Checkpoint – Looping over the array

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

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

} Problem 1b probably is the most tricky question. Road map of CS31

String

Array Function Class

Variable If / else Loops Pointer!! Class

} Define a } 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 Example

// create a new data 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; }