Information and Computer Science 45C — Week 1 Integrated Reading Notes
Table of Contents
- 1. Big Picture & Learning Path
- 2. Your First Program & the Build Pipeline
- 3. Variables, Types & Initialization
- 4. Input, Output & Strings
- 5. Operators, Expressions & Primitive Data
- 6. Control Structures
- 7. Functions, Parameters & Scope
- 8. Arrays & Pointers
- 9. GoogleTest Primer
- 10. Sample Quiz 0 (Week 2)
- 11. Quick Reference Table
UCI ICS 45C: Programming in C++ (35770)
This document merges overlapping Week 1 content fromcpp4pythonandLearnCpp.com, organized in learning order.
1. Big Picture & Learning Path
The goal of Week 1 is not "learn a lot of syntax" but rather to build a complete introductory chain for C++:
- First, understand how a C++ program goes from source code to an executable
- Then, master the basic program structure:
main(), statements, comments, formatting - Next, learn variables, types, initialization, I/O, and expressions
- Build on that to cover conditionals, loops, functions, arrays, and pointers
- Finally, get introduced to the testing tool GoogleTest
Study Tips:
- Type out every example by hand — don't just read
- Predict the output first, then run to verify
- Change one small thing at a time and observe the effect
- Compile as you go — don't accumulate a pile of errors
- When stuck, first identify which layer is the problem: syntax, types, logic, or the build pipeline
Five Steps of Development:
- Define the problem — What are you solving?
- Determine solution — Design it: keep it simple, modular, error-aware
- Write the program — Code it up
- Compile — Build into an executable
- Test and debug — Verify and fix
Incremental Development (from LearnCpp 1.11):
A common beginner mistake is trying to write the entire program at once, then being overwhelmed by a flood of errors. The correct approach is incremental development:
- Add one small piece of code at a time (e.g., one function)
- Compile — make sure there are no syntax errors
- Test — verify this piece works correctly
- Once confirmed, move on to the next piece
After the program works, the job isn't done yet. The next phase is code cleanup:
- Remove or comment out temporary debugging code
- Add necessary comments
- Handle error cases (error handling)
- Format code properly and follow best practices
- Look for redundant logic that can be simplified or consolidated
💡 First make it work, then make it right. Don't aim for perfection from the start — but don't stop once it merely runs, either.
Think of Week 1 as: first learn how a program exists, then learn how it runs.
2. Your First Program & the Build Pipeline
2.1 C++ vs Python: Compiled vs Interpreted
C++ is a compiled language; Python is an interpreted language.
g++ -o myprogram myprogram.cpp
./myprogram- C++ code must be compiled before it can run
- The compilation phase catches many syntax and type errors early
- This is one reason C++ is "stricter"
2.2 A Minimal C++ Program
#include <iostream>
int main() {
std::cout << "Hello, world!\n";
return 0;
}// Output:
Hello, world!Key elements you must recognize in Week 1:
#include <iostream>— brings in the standard I/O librarymain()— the program entry point{}— code blocks;— statement terminatorreturn 0;— tells the OS the program finished successfully
2.3 main(), Statements, and Comments
A statement is the smallest independent unit of execution in C++, usually ending with ;.
int x;
x = 5;
std::cout << x; // Output: 5
return 0;Comments come in two forms:
// single-line comment
/* multi-line
comment */Good comments explain why, not just what.
2.4 Headers & Namespaces
#include <iostream>
using namespace std;#includeis a preprocessor directive<iostream>providescoutandcinusing namespace std;lets you skip writingstd::everywhere
However, explicitly writing std::cout / std::cin is preferred because:
- Better readability
- Avoids naming conflicts
- Aligns with modern C++ conventions
2.5 Compiler, Linker, Loader
The full pipeline can be understood as:
Source code (.cpp/.hpp)
-> Preprocessor
-> Compiler
-> Object file
-> Linker
-> Executable
-> Loader
-> Execution starts at main()Responsibilities:
- Preprocessor — handles
#include,#define, etc. - Compiler — checks syntax, translates
.cppinto object files - Linker — combines multiple object files and libraries into one executable
- Loader — loads the executable into memory at runtime
A library is a pre-written, reusable collection of code:
- Standard library: e.g.,
iostream,string - Third-party libraries: e.g., GoogleTest (used later)
2.6 Code Formatting & Naming
- C++ ignores most whitespace, but humans don't
- Keep brace style consistent
- Keep indentation uniform
- Use descriptive identifiers
Naming rules:
- May contain letters, digits, and underscores
- Cannot start with a digit
- Case-sensitive
- Cannot use keywords like
int,return,while
3. Variables, Types & Initialization
3.1 Objects, Variables & Static Typing
Core concepts:
- data — information
- object — a region of memory that holds a value
- variable — a named object
- identifier — the variable's name
int x;
double price;
bool done;C++ is a statically typed language:
- Every variable must have a type when created
- Once the type is set, it determines how the value is stored and interpreted
This differs from Python, where you can write:
x = 5
x = "hello"In C++, an int x cannot later become a string variable.
3.2 Definition, Assignment, Initialization
int x; // definition
x = 5; // assignment
int a = 5; // copy initialization
int b(5); // direct initialization
int c{5}; // brace initialization
int d{}; // value initialization -> 0The most important Week 1 takeaway:
- Initialize variables at the point of definition
- Prefer
{}
int x{4.5}; // compile error — prevents narrowing conversion
int y = 4.5; // compiles, but value becomes 4So {} is safer.
3.3 Uninitialized Variables & Undefined Behavior
int x;
std::cout << x; // dangerousIf a local variable is not initialized, it typically contains a garbage value.
This leads to undefined behavior (UB):
- Might output a strange number
- Might crash
- Might "appear to work fine"
But "appears to work fine" does not mean the code is correct.
Best practice: always initialize a variable when you create it.
3.4 Constants & Magic Numbers
constexpr double pi{3.1415926};
constexpr char newline{'\n'};constexprdenotes a compile-time constant- Constants cannot be modified
- Named constants are clearer than raw numbers
double area(double r) {
return pi * r * r;
}3.5 Common Fundamental Types in Week 1
| Type | Purpose |
|---|---|
int |
Integers |
float / double |
Floating-point numbers |
bool |
True / false |
char |
A single character |
pointer |
An address |
Modifiers:
shortlongunsigned
These affect the range of values or memory usage.
4. Input, Output & Strings
4.1 cout, cin, endl
#include <iostream>
int main() {
int x{};
std::cin >> x;
std::cout << "You entered: " << x << '\n';
return 0;
}// Input: 42
// Output:
You entered: 42std::cout <<— outputstd::cin >>— inputstd::endl— newline and flushes the buffer'\n'— newline only, usually more efficient
std::cout << "Hello" << std::endl;
std::cout << "Hello\n";Week 1 recommendation: prefer '\n'.
4.2 Insertion / Extraction Operators
std::cout << "A" << "B" << '\n'; // Output: AB
std::cin >> value;<<— insertion operator>>— extraction operator
They can be chained:
std::cout << "x = " << x << '\n';4.3 Word Input vs Line Input
std::string name{};
std::cin >> name;This reads only the next word — it stops at whitespace.
To read an entire line:
#include <string>
std::string line{};
std::getline(std::cin, line);4.4 char and string
char letter{'A'};
std::string name{"Hello"};'A'is achar"Hello"is a string literal- In this course, single quotes → think "single character"
In Python, 'a' and "a" are essentially the same; in C++ they are different concepts.
4.5 Basic string Operations
#include <string>
std::string s{"Hello"};
std::cout << s[0] << '\n'; // Output: H
std::cout << s.size() << '\n'; // Output: 5
for (char c : s) {
std::cout << c << ' ';
}
// Output: H e l l os[i]— access character by indexs.size()— length- Range-based
foriterates character by character
5. Operators, Expressions & Primitive Data
5.1 Numeric Types & Integer Division
std::cout << 7 / 3 << '\n'; // 2
std::cout << 7.0 / 3 << '\n'; // 2.333...
std::cout << 7 % 3 << '\n'; // 1Critical rules:
int / intperforms integer division%is the modulus operator, integers only
| Python | C++ |
|---|---|
7 // 3 |
7 / 3 |
7 / 3 |
7.0 / 3 |
2 ** 10 |
pow(2, 10) |
5.2 Booleans & Logical Operators
bool flag{true};
bool test{false};| Python | C++ |
|---|---|
and |
&& |
or |
|| |
not |
! |
Relational operators:
<,>,<=,>=,==,!=
5.3 Literals & Operators
A literal is a value written directly in code:
5
3.14
'A'
"Hello"
trueAn operator is a symbol that performs an operation on values:
- Arithmetic:
+ - * / % - Assignment:
= += -= *= /= %= - Comparison:
== != < > - Logical:
&& || !
5.4 Increment, Decrement & Precedence
int x{10};
x++;
x--;x++— incrementx--— decrement
When in doubt about precedence, the safest approach is to use parentheses.
2 + 3 * 4; // 14
(2 + 3) * 4; // 205.5 Operator Precedence & Associativity
When an expression contains multiple operators, C++ uses precedence and associativity to determine the order of evaluation.
Precedence: higher number = evaluated first.
| Precedence | Operators | Description | Associativity |
|---|---|---|---|
| 1 (highest) | :: |
Scope resolution | Left→Right |
| 2 | () [] . -> ++(postfix) --(postfix) |
Postfix / call | Left→Right |
| 3 | ++(prefix) --(prefix) +(unary) -(unary) ! ~ (type) *(deref) &(addr) sizeof |
Prefix / unary | Right→Left |
| 4 | * / % |
Multiplication, division, modulo | Left→Right |
| 5 | + - |
Addition, subtraction | Left→Right |
| 6 | << >> |
Bitwise shift / stream I/O | Left→Right |
| 7 | < <= > >= |
Relational comparison | Left→Right |
| 8 | == != |
Equality | Left→Right |
| 9 | & |
Bitwise AND | Left→Right |
| 10 | ^ |
Bitwise XOR | Left→Right |
| 11 | | |
Bitwise OR | Left→Right |
| 12 | && |
Logical AND | Left→Right |
| 13 | || |
Logical OR | Left→Right |
| 14 | ?: |
Ternary conditional | Right→Left |
| 15 | = += -= *= /= %= etc. |
Assignment | Right→Left |
| 16 (lowest) | , |
Comma | Left→Right |
Associativity determines the order when operators share the same precedence:
// Left→Right: same-precedence operators evaluated left to right
8 - 3 - 2 // = (8 - 3) - 2 = 3, NOT 8 - (3 - 2) = 7
// Right→Left: assignment chains evaluate right to left
int a, b, c;
a = b = c = 5; // = a = (b = (c = 5)), c first, then b, then aCommon examples:
2 + 3 * 4 // 14: * has higher precedence than +, so 3*4=12 first, then 2+12
!x == 0 // (!x) == 0: ! is unary, higher precedence than ==
x = y == 5 // x = (y == 5): == has higher precedence than =
a && b || c // (a && b) || c: && has higher precedence than ||
cout << x + 1 // cout << (x + 1): + has higher precedence than <<💡 Best practice: when in doubt, add parentheses
()— they have the highest precedence and make your code easier to read.
5.6 Expressions & Expression Statements
2 + 3
x = 5
xThese are all expressions.
An expression followed by a semicolon becomes an expression statement:
x = 5;5.7 Key Takeaways
- In C++, values and types are bound more tightly
- Operators are affected by the types of their operands
int / intis one of the easiest Week 1 pitfalls
6. Control Structures
6.1 if / else if / else
if (score >= 90) {
std::cout << "A\n";
} else if (score >= 80) {
std::cout << "B\n";
} else {
std::cout << "F\n";
}- Conditions must be in
() - Code blocks go in
{} - Python's
elifbecomeselse ifin C++
6.2 switch
switch (grade) {
case 'A': std::cout << "Excellent"; break;
case 'B': std::cout << "Good"; break;
default: std::cout << "Other";
}Key points:
- Good for discrete-value checks
- Usually needs
breakafter eachcase defaulthandles "everything else"
6.3 while
int count{0};
while (count < 5) {
std::cout << count << '\n';
++count;
}// Output:
0
1
2
3
46.4 for
for (int i{0}; i < 10; ++i) {
std::cout << i << '\n';
}// Output:
0
1
2
3
4
5
6
7
8
9Python equivalent:
| Python | C++ |
|---|---|
for i in range(10): |
for (int i = 0; i < 10; ++i) |
6.5 Range-based for
for (int n : nums) {
std::cout << n << '\n';
}This is closer to Python's:
for x in nums:
print(x)6.6 break and continue
for (int i{0}; i < 10; ++i) {
if (i == 3) {
continue;
}
if (i == 8) {
break;
}
std::cout << i << '\n';
}// Output: (skips 3, stops at 8)
0
1
2
4
5
6
7continue— skip the rest of the current iterationbreak— exit the entire loop
7. Functions, Parameters & Scope
7.1 Why Use Functions
Five key benefits (from LearnCpp 2.6):
- Organization — Break large problems into smaller, manageable pieces; each function handles one task
- Reusability — Write once, call anywhere; avoid repeating code (DRY principle)
- Testing — Small functions are easier to test individually, and bugs are easier to locate
- Extensibility — Easier to maintain and extend
- Abstraction — The caller only needs to know what a function does (interface), not how it does it (implementation)
// The caller only needs to know: pass in two ints, get back their sum
int result = add(3, 4);
// No need to care how add() is implemented internallyAbstraction reduces complexity. It's like driving a car — you don't need to know how the engine works; you just need to know that the gas pedal accelerates and the brake pedal stops.
💡 This concept directly connects to encapsulation in Week 2: classes bundle data and functions together, exposing only the interface while hiding internal implementation.
Ideally, each function should do one thing.
7.2 Defining Functions
int add(int a, int b) {
return a + b;
}
void greet(std::string name) {
std::cout << "Hello " << name << '\n';
}- Functions must specify a return type
- Parameters must also have types
voidmeans no return value
7.3 Declaration vs Definition
double average(double x, double y); // declaration
int main() {
std::cout << average(2.0, 3.0) << '\n'; // Output: 2.5
}
double average(double x, double y) { // definition
return (x + y) / 2.0;
}- Declaration — tells the compiler "this exists"
- Definition — provides the actual implementation
- Before a call, the compiler must have seen at least the declaration
7.4 Return Values & void
int getValueFromUser() {
int input{};
std::cin >> input;
return input;
}void printHello() {
std::cout << "Hello!\n";
}Rules:
- An
intfunction must return anint - A
voidfunction returns nothing - Forgetting
returnin a non-voidfunction may cause UB
7.5 Parameters, Arguments & Pass by Value
void print(int x) {
std::cout << x << '\n';
}
print(5); // Output: 5xis the parameter (formal parameter)5is the argument (actual parameter)
By default, C++ uses pass by value:
- The function receives a copy
- Modifying the copy does not affect the original variable
void addOne(int x) {
++x; // only modifies the copy — original is unchanged
}
int a{5};
addOne(a);
std::cout << a << '\n'; // Output: 5 (a is unchanged)7.6 Local Scope
void func() {
int x{5};
std::cout << x;
}- Local variables are created at the point of definition
- They are destroyed when their enclosing block ends
- Identically named locals in different functions are independent
8. Arrays & Pointers
8.1 Arrays
int scores[5] = {90, 85, 78, 92, 88};
std::cout << scores[0] << '\n'; // Output: 90| Python list | C++ array |
|---|---|
| Dynamic size | Fixed size |
| Mixed types allowed | Must be same type |
| Out-of-bounds → exception | Out-of-bounds → possible UB |
append() |
Not supported |
8.2 Arrays as Function Parameters
double average(int list[], int length) {
double total{0};
for (int i{0}; i < length; ++i) {
total += list[i];
}
return total / length;
}When passing an array to a function, you typically pass the length as well.
8.3 Pointers
A pointer is a variable that stores an address.
int value{100};
int* ptr{&value};
std::cout << value << '\n'; // Output: 100
std::cout << &value << '\n'; // Output: a memory address, e.g. 0x7ffd5e3a2b4c
std::cout << *ptr << '\n'; // Output: 100Three things you must distinguish:
&x— address-of operatorint* ptr— declares a pointer*ptr— dereference, retrieves the value pointed to
*ptr = 2000;
std::cout << value << '\n'; // 20008.4 nullptr
int* ptr{nullptr};nullptrmeans "points to nothing"- Dereferencing a null pointer is a serious error
9. GoogleTest Primer
9.1 Basic Hierarchy
Test Program
-> Test Suite
-> Test
-> Assertion- Assertion — checks a condition
- Test — a group of assertions
- Test Suite — a collection of related tests
9.2 EXPECT_* vs ASSERT_*
| Type | On Failure | Use When |
|---|---|---|
EXPECT_* |
Non-fatal, continues execution | Most cases |
ASSERT_* |
Fatal, stops the current function | Subsequent code depends on this condition |
Common assertions:
EXPECT_TRUE(condition)EXPECT_FALSE(condition)EXPECT_EQ(a, b)EXPECT_NE(a, b)EXPECT_LT(a, b)EXPECT_LE(a, b)EXPECT_GT(a, b)EXPECT_GE(a, b)EXPECT_STREQ(s1, s2)
9.3 A Simple Test
#include <gtest/gtest.h>
TEST(FactorialTest, HandlesZeroInput) {
EXPECT_EQ(Factorial(0), 1);
}
TEST(FactorialTest, HandlesPositiveInput) {
EXPECT_EQ(Factorial(1), 1);
EXPECT_EQ(Factorial(2), 2);
EXPECT_EQ(Factorial(3), 6);
}Rules:
TEST(TestSuiteName, TestName)- Names cannot contain underscores
_ - Test names within the same suite must be unique
9.4 When to Use ASSERT_*
TEST(QueueTest, DequeueWorks) {
Queue q;
q.Enqueue(1);
int* n = q.Dequeue();
ASSERT_NE(n, nullptr);
EXPECT_EQ(*n, 1);
delete n;
}Without first asserting n != nullptr, the subsequent *n could crash.
10. Sample Quiz 0 (Week 2)
⚠️ Note: Sample Quiz 0 is Week 2 content (given Thursday of Week 2). Included here for early reference.
Assume all necessary
#includes are present and correct.
10.1 Operator Precedence
Problem:
x = +a + b * c - d / -e
y = z = -a - b / c * dFully parenthesized:
(x = (((+a) + (b * c)) - (d / (-e))))
(y = (z = ((-a) - ((b / c) * d))))10.2 Write square
int square(int i) {
return i * i;
}10.3 Print 1 through 10 with Their Squares
int main() {
for (int i = 1; i <= 10; ++i) {
std::cout << i << ' ' << square(i) << '\n';
}
return 0;
}// Output:
1 1
2 4
3 9
4 16
5 25
6 36
7 49
8 64
9 81
10 10010.4 Object Lifetime
Question: Give the specific word describing each step in the lifetime of an object in C++.
Answer:
1) Birth
1a) Allocation — memory is reserved
1b) Construction — object is initialized
2) Life
3) Death
3a) Destruction — object is cleaned up
3b) Deallocation — memory is released⚠️ It's Destruction, NOT
Deconstruction. -5 pts if you write "con".
10.5 What This Quiz Tests
This quiz simultaneously checks four things:
- Can you read operator precedence?
- Can you write a minimal function?
- Can you write a
forloop? - Do you have the "object lifetime" concept down?
11. Quick Reference Table
| Concept | Python | C++ |
|---|---|---|
| Output | print("hi") |
cout << "hi" << '\n'; |
| Input | x = input() |
cin >> x; |
| Variable | x = 5 |
int x{5}; |
| Typing | Dynamic | Static |
| Integer division | 7 // 3 |
7 / 3 |
| Power | 2 ** 10 |
pow(2, 10) |
| Boolean | True / False |
true / false |
| Logic | and / or / not |
&& / || / ! |
| Conditional | if x > 0: |
if (x > 0) {} |
elif |
elif |
else if |
| Loop | for i in range(n): |
for (int i = 0; i < n; ++i) |
| Function | def f(x): |
int f(int x) {} |
| No return | def f(): |
void f() {} |
| Character | 'a' |
'a' is char |
| String | "abc" |
std::string{"abc"} |
| Array | [1, 2, 3] |
int a[]{1, 2, 3}; |
| Pointer | No direct equivalent | int* p = &x; |
| Null pointer | None |
nullptr |
| Increment | x += 1 |
++x or x++ |
| Testing | assert / unittest |
GoogleTest |
Five Most Important Week 1 Takeaways:
- C++ is a statically typed language
- Initialize variables at definition — prefer
{} int / intis integer divisionmain()is the program entry point- Functions must be declared before they are called; the default passing mode is pass by value