CSE 374 Programming concepts and tools
Summer 2024 Instructor: Audrey Seo
Announcements
Grades posted on Canvas:
HW6 is out -- implementing T9
This is week 7! Just 3 more weeks :)
Last week
This week/Today
Monday: Testing
Wednesday: Variable Types and Storage
Friday: Memory Architecture
Today: Intro to C++
Wednesday: C++ Classes
Friday: C++ Class Details
C++ Intro
Why C++?
How to Think About C++
6
Set of styles and ways to use C++
Set of styles and ways to use C
Good styles and robust engineering practices
Or…
7
In the hands of a disciplined programmer, C++ is a powerful tool
But if you’re not so disciplined about how you use C++…
Hello World in C
8
#include <stdio.h> // for printf()
#include <stdlib.h> // for EXIT_SUCCESS
int main(int argc, char** argv) {
printf("Hello, World!\n");
return EXIT_SUCCESS;
}
helloworld.c
gcc -Wall -g -std=c11 -o hello helloworld.c
Hello World in C++
Looks simple enough…
*.cpp is also a common file extension for C++ files, but we’ll use .cc in this class
9
#include <iostream> // for cout, endl
#include <cstdlib> // for EXIT_SUCCESS
int main(int argc, char** argv) {
std::cout << "Hello, World!" << std::endl;
return EXIT_SUCCESS;
}
g++ -Wall -g -std=c++17 -o helloworld helloworld.cc
helloworld.cc
Hello World in C vs. C++
10
#include <iostream> // for cout, endl
#include <cstdlib> // for EXIT_SUCCESS
int main(int argc, char** argv) {
std::cout << "Hello, World!" << std::endl;
return EXIT_SUCCESS;
}
helloworld.cc
#include <stdio.h> // for printf()
#include <stdlib.h> // for EXIT_SUCCESS
int main(int argc, char** argv) {
printf("Hello, World!\n");
return EXIT_SUCCESS;
}
helloworld.c
Example: Hello World in C++
Hello World in C++
iostream is part of the C++ standard library
12
#include <iostream>
#include <cstdlib>
int main(int argc, char** argv) {
std::cout << "Hello, World!" << std::endl;
return EXIT_SUCCESS;
}
helloworld.cc
Hello World in C++
cstdlib is the C standard library’s stdlib.h
13
#include <iostream>
#include <cstdlib>
int main(int argc, char** argv) {
std::cout << "Hello, World!" << std::endl;
return EXIT_SUCCESS;
}
helloworld.cc
Hello World in C++
std::cout is the “cout” object instance declared by iostream, living within the “std” namespace
14
helloworld.cc
#include <iostream>
#include <cstdlib>
int main(int argc, char** argv) {
std::cout << "Hello, World!" << std::endl;
return EXIT_SUCCESS;
}
Hello World in C++
C++ has a stronger distinction between objects and primitive types
15
#include <iostream>
#include <cstdlib>
int main(int argc, char** argv) {
std::cout << "Hello, World!" << std::endl;
return EXIT_SUCCESS;
}
helloworld.cc
Hello World in C++
“<<” is an operator defined by the C++ language
16
#include <iostream>
#include <cstdlib>
int main(int argc, char** argv) {
std::cout << "Hello, World!" << std::endl;
return EXIT_SUCCESS;
}
helloworld.cc
Hello World in C++
ostream has many different methods to handle <<
17
#include <iostream>
#include <cstdlib>
int main(int argc, char** argv) {
std::cout << "Hello, World!" << std::endl;
return EXIT_SUCCESS;
}
helloworld.cc
ostream object
still a char*
Hello World in C++
The ostream class’ member functions that handle << return a reference to themselves
18
#include <iostream>
#include <cstdlib>
int main(int argc, char** argv) {
std::cout << "Hello, World!" << std::endl;
return EXIT_SUCCESS;
}
helloworld.cc
This is equivalent to:
std::cout << “Hello,world!”;
std:cout << std::endl;
Hello World in C++
Next, another member function on std::cout is invoked to handle << with RHS std::endl
19
#include <iostream>
#include <cstdlib>
int main(int argc, char** argv) {
std::cout << "Hello, World!" << std::endl;
return EXIT_SUCCESS;
}
helloworld.cc
Wow…
You should be surprised and scared at this point
20
#include <iostream>
#include <cstdlib>
int main(int argc, char** argv) {
std::cout << "Hello, World!" << std::endl;
return EXIT_SUCCESS;
}
helloworld.cc
Questions?
Let’s Refine It a Bit
C++’s standard library has a std::string class
22
#include <iostream> // for cout, endl
#include <cstdlib> // for EXIT_SUCCESS
#include <string> // for string
using namespace std;
int main(int argc, char** argv) {
string hello("Hello, World!");
cout << hello << endl;
return EXIT_SUCCESS;
}
helloworld2.cc
Let’s Refine It a Bit
The using keyword introduces a namespace (or part of) into the current region
23
#include <iostream> // for cout, endl
#include <cstdlib> // for EXIT_SUCCESS
#include <string> // for string
using namespace std;
int main(int argc, char** argv) {
string hello("Hello, World!");
cout << hello << endl;
return EXIT_SUCCESS;
}
helloworld2.cc
Let’s Refine It a Bit
Benefits of
24
#include <iostream> // for cout, endl
#include <cstdlib> // for EXIT_SUCCESS
#include <string> // for string
using namespace std;
int main(int argc, char** argv) {
string hello("Hello, World!");
cout << hello << endl;
return EXIT_SUCCESS;
}
helloworld2.cc
using namespace std;
Let’s Refine It a Bit
Here we are instantiating a std::string object on the stack (an ordinary local variable)
25
#include <iostream> // for cout, endl
#include <cstdlib> // for EXIT_SUCCESS
#include <string> // for string
using namespace std;
int main(int argc, char** argv) {
string hello("Hello, World!");
cout << hello << endl;
return EXIT_SUCCESS;
}
helloworld2.cc
Let’s Refine It a Bit
The C++ string library also overloads the << operator
26
#include <iostream> // for cout, endl
#include <cstdlib> // for EXIT_SUCCESS
#include <string> // for string
using namespace std;
int main(int argc, char** argv) {
string hello("Hello, World!");
cout << hello << endl;
return EXIT_SUCCESS;
}
helloworld2.cc
String Concatenation
The string class overloads the “+” operator
27
#include <iostream> // for cout, endl
#include <cstdlib> // for EXIT_SUCCESS
#include <string> // for string
using namespace std;
int main(int argc, char** argv) {
string hello("Hello");
hello = hello + ", World!";
cout << hello << endl;
return EXIT_SUCCESS;
}
concat.cc
String Assignment
The string class overloads the “=” operator
28
#include <iostream> // for cout, endl
#include <cstdlib> // for EXIT_SUCCESS
#include <string> // for string
using namespace std;
int main(int argc, char** argv) {
string hello("Hello");
hello = hello + ", World!";
cout << hello << endl;
return EXIT_SUCCESS;
}
concat.cc
String Manipulation
This statement is complex!
29
int main(int argc, char** argv) {
string hello("Hello");
hello = hello + ", World!";
cout << hello << endl;
return EXIT_SUCCESS;
}
concat.cc
hello.operator=(hello.operator+(", World!"));
Operators are just member functions
C and C++
C is (roughly) a subset of C++
30
#include <cstdio> // for printf
#include <cstdlib> // for EXIT_SUCCESS
int main(int argc, char** argv) {
printf("Hello from C!\n");
return EXIT_SUCCESS;
}
helloworld3.cc
Reading
std::cin is an object instance of class istream
31
#include <iostream> // for cout, endl
#include <cstdlib> // for EXIT_SUCCESS
using namespace std;
int main(int argc, char** argv) {
int num;
cout << "Type a number: ";
cin >> num;
cout << "You typed: " << num << endl;
return EXIT_SUCCESS;
}
echonum.cc
Demo: echonum.cc
Questions?
C++ References
Review: Pointer
A pointer is a variable containing an address
35
int main(int argc, char** argv) {
int x = 5, y = 10;
int* z = &x;
*z += 1;
x += 1;
z = &y;
*z += 1;
return EXIT_SUCCESS;
}
pointer.cc
x | 5 |
y | 10 |
z | |
Note: Arrow points to next instruction.
Review: Pointer
A pointer is a variable containing an address
36
int main(int argc, char** argv) {
int x = 5, y = 10;
int* z = &x;
*z += 1;
x += 1;
z = &y;
*z += 1;
return EXIT_SUCCESS;
}
pointer.cc
x | 5 |
y | 10 |
z | 0x7fff…a4 |
Review: Pointer
A pointer is a variable containing an address
37
int main(int argc, char** argv) {
int x = 5, y = 10;
int* z = &x;
*z += 1; // sets x to 6
x += 1;
z = &y;
*z += 1;
return EXIT_SUCCESS;
}
pointer.cc
x | 6 |
y | 10 |
z | 0x7fff…a4 |
Review: Pointer
A pointer is a variable containing an address
38
int main(int argc, char** argv) {
int x = 5, y = 10;
int* z = &x;
*z += 1; // sets x to 6
x += 1; // sets x (and *z) to 7
z = &y;
*z += 1;
return EXIT_SUCCESS;
}
pointer.cc
x | 7 |
y | 10 |
z | 0x7fff…a4 |
Review: Pointer
A pointer is a variable containing an address
39
int main(int argc, char** argv) {
int x = 5, y = 10;
int* z = &x;
*z += 1; // sets x to 6
x += 1; // sets x (and *z) to 7
z = &y;
*z += 1;
return EXIT_SUCCESS;
}
pointer.cc
x | 7 |
y | 10 |
z | 0x7fff…a0 |
Review: Pointer
A pointer is a variable containing an address
40
int main(int argc, char** argv) {
int x = 5, y = 10;
int* z = &x;
*z += 1; // sets x to 5 + 1 = 6
x += 1; // sets x (and *z) to 6 + 1 = 7
z = &y;
*z += 1; // sets y to 10 + 1 = 11
return EXIT_SUCCESS;
}
pointer.cc
x | 7 |
y | 11 |
z | 0x7fff…a0 |
References
A reference is an alias for another variable
41
int main(int argc, char** argv) {
int x = 5, y = 10;
int& z = x;
z += 1;
x += 1;
z = y;
z += 1;
return EXIT_SUCCESS;
}
reference.cc
x | 5 |
y | 10 |
When we use '&' in a type declaration, it is a reference.
&var is still “address of var”
References
A reference is an alias for another variable
42
int main(int argc, char** argv) {
int x = 5, y = 10;
int& z = x; // binds the name "z" to x
z += 1;
x += 1;
z = y;
z += 1;
return EXIT_SUCCESS;
}
reference.cc
x, z | 5 |
y | 10 |
References
A reference is an alias for another variable
43
int main(int argc, char** argv) {
int x = 5, y = 10;
int& z = x; // binds the name "z" to x
z += 1; // sets z (and x) to 6
x += 1;
z = y;
z += 1;
return EXIT_SUCCESS;
}
reference.cc
x, z | 6 |
y | 10 |
References
A reference is an alias for another variable
44
int main(int argc, char** argv) {
int x = 5, y = 10;
int& z = x; // binds the name "z" to x
z += 1; // sets z (and x) to 6
x += 1; // sets x (and z) to 7
z = y;
z += 1;
return EXIT_SUCCESS;
}
reference.cc
x, z | 7 |
y | 10 |
References
A reference is an alias for another variable
45
int main(int argc, char** argv) {
int x = 5, y = 10;
int& z = x; // binds the name "z" to x
z += 1; // sets z (and x) to 6
x += 1; // sets x (and z) to 7
z = y; Normal assignment
z += 1;
return EXIT_SUCCESS;
}
reference.cc
x, z | 7 |
y | 10 |
There is no way to rebind a reference to refer to a different object. Because there is no way to rebind a reference, references must be initialized.
References
A reference is an alias for another variable
46
int main(int argc, char** argv) {
int x = 5, y = 10;
int& z = x; // binds the name "z" to x
z += 1; // sets z (and x) to 6
x += 1; // sets x (and z) to 7
z = y; // sets z (and x) to the value of y
z += 1;
return EXIT_SUCCESS;
}
reference.cc
x, z | 10 |
y | 10 |
References
A reference is an alias for another variable
47
int main(int argc, char** argv) {
int x = 5, y = 10;
int& z = x; // binds the name "z" to x
z += 1; // sets z (and x) to 6
x += 1; // sets x (and z) to 7
z = y; // sets z (and x) to the value of y
z += 1; // sets z (and x) to 11
return EXIT_SUCCESS;
}
reference.cc
x, z | 11 |
y | 10 |
Some Symbols Have Multiple Meanings
& and * are used as both an operator in an expression and as part of a declaration. The context in which a symbol is used determines what the symbol means:
int i = 42;
int& r = i; // & follows a type and is part of a declaration; r is a reference
int* p; // * follows a type and is part of a declaration; p is a pointer
p = &i; // & is used in an expression as the address-of operator
*p = i; // * is used in an expression as the dereference operator
int& r2 = *p; // & is part of the declaration; * is the dereference operator
In declarations, & and * are used to form compound types. In expressions, these same
symbols are used to denote an operator.
Questions?
Pass-By-Reference
C++ allows you to use real pass-by-reference
50
void swap(int& x, int& y) {
int tmp = x;
x = y;
y = tmp;
}
int main(int argc, char** argv) {
int a = 5, b = 10;
swap(a, b);
cout << "a: " << a << "; b: " << b << endl;
return EXIT_SUCCESS;
}
passbyreference.cc
(main) a | 5 |
(main) b | 10 |
Pass-By-Reference
C++ allows you to use real pass-by-reference
51
void swap(int& x, int& y) {
int tmp = x;
x = y;
y = tmp;
}
int main(int argc, char** argv) {
int a = 5, b = 10;
swap(a, b);
cout << "a: " << a << "; b: " << b << endl;
return EXIT_SUCCESS;
}
passbyreference.cc
(main) a | 5 |
(main) b | 10 |
Parameters are attached to variables provided by caller
Pass-By-Reference
C++ allows you to use real pass-by-reference
52
void swap(int& x, int& y) {
int tmp = x;
x = y;
y = tmp;
}
int main(int argc, char** argv) {
int a = 5, b = 10;
swap(a, b);
cout << "a: " << a << "; b: " << b << endl;
return EXIT_SUCCESS;
}
passbyreference.cc
(main) a (swap) x | 5 |
(main) b (swap) y | 10 |
(swap) tmp | |
Pass-By-Reference
C++ allows you to use real pass-by-reference
53
void swap(int& x, int& y) {
int tmp = x;
x = y;
y = tmp;
}
int main(int argc, char** argv) {
int a = 5, b = 10;
swap(a, b);
cout << "a: " << a << "; b: " << b << endl;
return EXIT_SUCCESS;
}
passbyreference.cc
(main) a (swap) x | 5 |
(main) b (swap) y | 10 |
(swap) tmp | 5 |
Pass-By-Reference
C++ allows you to use real pass-by-reference
54
void swap(int& x, int& y) {
int tmp = x;
x = y;
y = tmp;
}
int main(int argc, char** argv) {
int a = 5, b = 10;
swap(a, b);
cout << "a: " << a << "; b: " << b << endl;
return EXIT_SUCCESS;
}
passbyreference.cc
(main) a (swap) x | 10 |
(main) b (swap) y | 10 |
(swap) tmp | 5 |
Pass-By-Reference
C++ allows you to use real pass-by-reference
55
void swap(int& x, int& y) {
int tmp = x;
x = y;
y = tmp;
}
int main(int argc, char** argv) {
int a = 5, b = 10;
swap(a, b);
cout << "a: " << a << "; b: " << b << endl;
return EXIT_SUCCESS;
}
passbyreference.cc
(main) a (swap) x | 10 |
(main) b (swap) y | 5 |
(swap) tmp | 5 |
Pass-By-Reference
C++ allows you to use real pass-by-reference
56
void swap(int& x, int& y) {
int tmp = x;
x = y;
y = tmp;
}
int main(int argc, char** argv) {
int a = 5, b = 10;
swap(a, b);
cout << "a: " << a << "; b: " << b << endl;
return EXIT_SUCCESS;
}
passbyreference.cc
(main) a | 10 |
(main) b | 5 |
Best Practices
Programmers accustomed to programming in C often use pointer parameters to access objects outside a function. In C++, programmers generally use reference parameters instead.
Questions?
Exercise (pollev.com/cse374summer)
What will happen when we run this?
59
void foo(int& x, int* y, int z) {
z = *y;
x += 2;
y = &x;
}
int main(int argc, char** argv) {
int a = 1;
int b = 2;
int& c = a;
foo(a, &b, c);
std::cout << "(" << a << ", " << b
<< ", " << c << ")" << std::endl;
return EXIT_SUCCESS;
}
Poll Question Explained
62
void foo(int& x, int* y, int z) {
z = *y;
x += 2;
y = &x;
}
int main(int argc, char** argv) {
int a = 1;
int b = 2;
int& c = a;
foo(a, &b, c);
std::cout << "(" << a << ", " << b
<< ", " << c << ")" << std::endl;
return EXIT_SUCCESS;
}
a, c
1
b
2
Poll Question Explained
63
void foo(int& x, int* y, int z) {
z = *y;
x += 2;
y = &x;
}
int main(int argc, char** argv) {
int a = 1;
int b = 2;
int& c = a;
foo(a, &b, c);
std::cout << "(" << a << ", " << b
<< ", " << c << ")" << std::endl;
return EXIT_SUCCESS;
}
(main) a, c
(foo) x
1
b
2
y
z
1
b
2
Poll Question Explained
64
void foo(int& x, int* y, int z) {
z = *y;
x += 2;
y = &x;
}
int main(int argc, char** argv) {
int a = 1;
int b = 2;
int& c = a;
foo(a, &b, c);
std::cout << "(" << a << ", " << b
<< ", " << c << ")" << std::endl;
return EXIT_SUCCESS;
}
(main) a, c
(foo) x
1
b
2
y
z
2
b
2
Poll Question Explained
65
void foo(int& x, int* y, int z) {
z = *y;
x += 2;
y = &x;
}
int main(int argc, char** argv) {
int a = 1;
int b = 2;
int& c = a;
foo(a, &b, c);
std::cout << "(" << a << ", " << b
<< ", " << c << ")" << std::endl;
return EXIT_SUCCESS;
}
(main) a, c
(foo) x
3
b
2
y
z
2
b
2
Poll Question Explained
66
void foo(int& x, int* y, int z) {
z = *y;
x += 2;
y = &x;
}
int main(int argc, char** argv) {
int a = 1;
int b = 2;
int& c = a;
foo(a, &b, c);
std::cout << "(" << a << ", " << b
<< ", " << c << ")" << std::endl;
return EXIT_SUCCESS;
}
(main) a, c
(foo) x
3
b
2
y
z
2
b
2
Poll Question Explained
67
void foo(int& x, int* y, int z) {
z = *y;
x += 2;
y = &x;
}
int main(int argc, char** argv) {
int a = 1;
int b = 2;
int& c = a;
foo(a, &b, c);
std::cout << "(" << a << ", " << b
<< ", " << c << ")" << std::endl;
return EXIT_SUCCESS;
}
a, c
3
b
2
b
2
Aside: C++ Primer
It’s hard to learn the “why is it done this way” from reference docs, and even harder to learn from random stuff on the web
HW6: T9 Implementation
Last week on CSE 374…
You were writing tests for T9!
T9 uses a data structure called tries
Now, you’ll be implementing T9 to create a whole autocomplete command line application
What you’ll need to do for HW6*
What you’ll do:
Requirements:
Total Points: 65
*This is just the gist, more information on the website (which is the ground source of truth for homework specs)!
The T9 Application
Ex15 due Wednesday, HW6 due Sunday!
Ex15 is due before the beginning of the next lecture
HW6 due Sunday 11.59pm!