Intro to Computing
Computer
Definition: A computer is an electronic machine that processes data
into useful information.
Components: Hardware: CPU; memory (RAM, ROM); storage
(HDD/SSD); input devices (keyboard, mouse); output devices (monitor,
printer). Software: System software (operating system); application
software.
Functions: Input → Process → Store → Output.
Types: Desktop; Laptop; Server; Embedded systems; Mobile devices.
Tip: Break tasks into small steps to simplify problem solving.
Flowchart
Definition: A flowchart is a visual diagram that shows the steps of a
process or algorithm using symbols and arrows.
Basic symbols: Start/End (oval); Process (rectangle); Decision
(diamond); Input/Output (parallelogram); Flow line (arrow).
Use cases: Program logic design, debugging, process documentation.
Example (simple):
1. Start
2. Read number
3. Is number > 0? — yes → Print "Positive" — no → Is number < 0?
— yes → Print "Negative" — no → Print "Zero"
4. End
Algorithms
Definition: An algorithm is a step-by-step procedure that solves a
specific problem.
Characteristics: Finite steps; Unambiguous; Defined inputs and
outputs; Effective (each step is feasible).
Design tips: Keep it simple; consider edge cases; estimate time and
space complexity.
Common examples: Sorting (bubble, merge), Searching (linear,
binary), Factorial, GCD.
Pseudocode
Definition: Pseudocode is a mix of natural language and
programming-like statements used to describe an algorithm before
writing real code.
Purpose: Clarify logic without worrying about programming syntax;
great for team communication.
Style guidelines: Use clear action words (READ, IF, FOR, WHILE,
PRINT); indent blocks; use consistent names.
Example (factorial pseudocode):
READ n
IF n < 0 THEN
PRINT "Undefined for negative numbers"
ELSE
result ← 1
FOR i FROM 1 TO n DO
result ← result * i
END FOR
PRINT result
END IF
C++
Role: C++ is a high-level programming language that offers both
performance and low-level control; commonly used to implement
algorithms.
Basic structure: Headers, main function, statements, return value.
Simple example (factorial using a loop):
#include <iostream>
using namespace std;
int main() {
int n;
cout << "Enter a non-negative integer: ";
cin >> n;
if (n < 0) {
cout << "Undefined for negative numbers\n";
return 0;
long long result = 1;
for (int i = 1; i <= n; ++i) result *= i;
cout << "Factorial of " << n << " is " << result << "\n";
return 0;
Learning path: Syntax → Data types & operators → Control flow (if,
loops) → Functions → Arrays/strings → Pointers & memory → OOP basics
→ STL (vectors, algorithms).
Practice tip: Write pseudocode first, draw a flowchart next, then
implement in C++; test each step with small cases.
Flowchart
Definition
A flowchart is a graphical representation of the sequential steps in an
algorithm, process, or workflow; it uses standard symbols connected by
arrows to show the order of operations and decision points.
Why use flowcharts (computing context)
Flowcharts help programmers and designers visualize algorithms before
coding, find logic errors early, and communicate program structure clearly to
teammates and reviewers.
Common symbols and their meanings
Start / End (Terminal): oval — marks beginning or termination of the
process.
Process: rectangle — a single operation or computation (e.g., sum = a
+ b).
Input / Output: parallelogram — reading or printing data (e.g., READ
n; PRINT result).
Decision: diamond — a conditional branching (true/false or multiple
choices).
Flow line: arrow — shows control flow direction between symbols.
Connector: small circle or labeled shape — joins flows on the same
page or across pages.
Basic rules for clear flowcharts
Use one entry and one exit for each sub-process where possible.
Keep symbols consistent and label arrows when multiple branches
exist.
Keep steps simple: one action per Process box; keep decision boxes to
yes/no or mutually exclusive choices.
Use connectors when diagrams get large to avoid crossing lines and
clutter.
Simple example 1 — Classify a number (diagram + explanation)
Goal: Read a number and print whether it is Positive, Negative, or Zero.
Textual steps:
1. Start
2. Read number n
3. If n > 0 then Print "Positive"
4. Else if n < 0 then Print "Negative"
5. Else Print "Zero"
6. End
ASCII-style flowchart: Start | [Read n] | {Is n > 0?}──Yes──>[Print
"Positive"]──┐ |No | └─{Is n < 0?}──Yes──>[Print "Negative"]──┐ |No |
└────────>[Print "Zero"]────┘ | End
Explanation: The first decision checks positivity; if false it checks negativity;
otherwise it falls to zero. Label each decision arrow (Yes/No) to avoid
ambiguity.
Example 2 — Add two numbers (compact flowchart + mapping to
code)
Steps:
1. Start
2. Read a, b
3. sum = a + b
4. Print sum
5. End
ASCII flowchart: Start | [Read a, b] | [sum = a + b] | [Print sum] | End
Mapping: Each Process box maps directly to a line in code (input, compute,
output) which makes translating the flowchart to a program trivial and
reduces logical mistakes.
Example 3 — Loop example (compute factorial using iteration)
Steps:
1. Start
2. Read n
3. If n < 0 → Print "Undefined" → End
4. result = 1; i = 1
5. Is i <= n? → Yes: result = result * i; i = i + 1; go back to step 5 → No:
continue
6. Print result
7. End
Simplified ASCII: Start | [Read n] | {Is n < 0?}──Yes──>[Print
"Undefined"]──>End |No [result = 1; i = 1] | {Is i <= n?}──Yes──>[result =
result * i; i = i + 1]──┐ |No |
└───────────────────────────────────────────────────┘ | [Print
result] | End
Explanation: Loops are represented by arrows returning to an earlier decision
or process; show loop conditions clearly and initialize loop variables before
the loop starts.
Algorithms
Definition
An algorithm is a finite, well-defined sequence of instructions designed to
solve a specific problem or perform a task; it specifies the exact steps to
transform input into the desired output.
Key characteristics
Finite steps: The algorithm must terminate after a limited number of
steps.
Unambiguous: Each step must be clear and precisely stated.
Defined inputs and outputs: Inputs (what you start with) and
outputs (what you expect) must be specified.
Effectiveness: Every step must be executable with the available
resources (feasible operations).
Why algorithms matter in computing
Algorithms form the backbone of programming: they turn problem
descriptions into implementable procedures, determine program correctness,
and strongly influence performance (time and memory). Choosing or
designing the right algorithm is often more important than low-level code
optimizations.
Design guidelines and tips
Start with a clear problem statement and examples of expected
input/output.
Break the problem into smaller subproblems (divide and conquer).
Prefer simple, readable steps first; optimize only after correctness is
confirmed.
Consider edge cases and invalid inputs early.
Estimate time and space complexity to compare alternatives (see
Complexity section).
Use flowcharts or pseudocode to verify logic before coding; these
visual/textual tools help catch mistakes and communicate design to
others.
Translating an algorithm into implementation
Typical workflow: Problem statement → Pseudocode → Flowchart (optional) →
Code (e.g., C++) → Test with sample inputs and edge cases.
Example 1 — Factorial (iterative)
Textual algorithm:
1. Read n
2. If n < 0 then output "Undefined" and stop
3. result = 1; for i from 1 to n do result = result * i
4. Output result
ASCII flow-style diagram: Start | [Read n] | {n < 0?} --Yes--> [Print
"Undefined"] --> End | No | [result = 1; i = 1] | { i <= n? } --Yes--> [result =
result * i; i = i + 1] --┐ | | No <-----------------------------------------------┘ | [Print
result] | End
Explanation: This algorithm is finite, unambiguous, and maps directly to a
loop in code; it is simple to test with n = 0, 1, 5.
Example 2 — Linear search (simple searching algorithm)
Purpose: Find target value in an array.
Pseudocode: READ array A of size n, READ target FOR i FROM 0 TO n-1 DO IF
A[i] = target THEN PRINT "Found at", i; STOP END FOR PRINT "Not found"
ASCII diagram (compact): Start → [Read A, target] → [i = 0] → {i < n?} → Yes
→ {A[i] == target?} → Yes → [Print found] → End → No → [i = i + 1] → loop
back to {i < n?} → No (from {i < n?}) → [Print not found] → End
Explanation: Linear search is straightforward, scans elements until it finds
the target or ends; good for small or unsorted data.
Example 3 — Merge sort (divide and conquer, high-level)
High-level steps:
1. If array size ≤ 1, return array
2. Split array into left and right halves
3. Recursively sort left and right
4. Merge the two sorted halves and return result
Recursive structure diagram (conceptual): Sort(array) ├─ if small return ├─
left = Sort(left half) └─ right = Sort(right half) Merge(left, right) → return
Explanation: Merge sort breaks the problem into smaller subproblems (divide
and conquer); it is more complex to implement but much faster on large data
than simple sorts. Use diagrams or recursion trees to reason about
correctness and complexity.
Complexity (brief)
Time complexity: Measure of steps as a function of input size (e.g.,
O(n), O(n log n), O(n^2)).
Space complexity: Extra memory required beyond input storage.
Compare candidate algorithms on both metrics and on typical vs worst-
case behavior when choosing an approach.
Pseudocode
Definition
Pseudocode is a human-readable, language-neutral way to describe
an algorithm using plain-English statements shaped like code. It sits
between an algorithm (idea) and an actual program (implementation).
Purpose (computing context)
Clarify program logic without worrying about syntax rules.
Help teams review and reason about algorithms quickly.
Serve as a direct blueprint for writing code in any programming
language.
Style rules and conventions
Use clear action words: READ, SET, IF, ELSE, FOR, WHILE, RETURN,
PRINT.
Keep one action per line; indent blocks to show structure.
Use meaningful variable names (n, sum, index).
Avoid language-specific constructs (no ;, no types unless helpful).
Show initialization and termination conditions explicitly.
Keep pseudocode concise but unambiguous.
Mapping between flowchart, pseudocode, and code
Flowchart box (Input) → Pseudocode: READ n → Code: cin >> n; (C++)
Flowchart box (Process) → Pseudocode: sum ← a + b → Code: sum = a
+ b;
Flowchart diamond (Decision) → Pseudocode: IF condition THEN ... ELSE
... → Code: if (condition) { ... } else { ... }
Loop arrow (back to decision) → Pseudocode: WHILE condition DO ... or
FOR i FROM 1 TO n DO ... → Code: while(...) { } or for(...) { }
Examples
Factorial (iterative)
Pseudocode: READ n
IF n < 0 THEN
PRINT "Undefined for negative numbers"
ELSE
result ← 1
FOR i FROM 1 TO n DO
result ← result * i
END FOR
PRINT result
END IF
Explanation: Initialization (result ← 1) done before loop; loop runs exact
number of times; handles invalid input first.
Linear search
Pseudocode: READ array A of size n
READ target
FOR i FROM 0 TO n - 1 DO
IF A[i] = target THEN
PRINT "Found at", i
RETURN
END IF
END FOR
PRINT "Not found"
Explanation: Straightforward scan; returns on first match; worst-case visits
all elements.
Bubble sort (simple sorting example)
Pseudocode: READ array A of size n
FOR i FROM 0 TO n - 2 DO
FOR j FROM 0 TO n - 2 - i DO
IF A[j] > A[j + 1] THEN
SWAP A[j], A[j + 1]
END IF
END FOR
END FOR
PRINT A
Explanation: Nested loops; each outer iteration places next largest element
at the end.
Examples with small test trace (helps validate pseudocode)
Factorial with n = 4: result starts 1 → loop multiplies 1×1, ×2, ×3, ×4
→ result = 24.
Linear search A = [3,7,2], target = 7: i=0 (3 ≠ 7), i=1 (7 = 7) → prints
index 1 and returns.
Bubble sort A = [3,1,2]: passes transform to [1,2,3] after required
swaps.
Best practices and tips
Write pseudocode at two levels: high-level for module structure, then
expanded low-level for tricky parts.
Walk through the pseudocode with sample inputs (trace) and edge
cases (empty inputs, negative, extremes).
Keep decisions simple; if a condition is complex, move it into a named
sub-process (e.g., IS-VALID(x)).
Convert pseudocode to code line-by-line; each pseudocode statement
should map clearly to one or a few code statements.
Comment or annotate non-obvious steps for teammates.
C++
Definition and role
C++ is a general-purpose programming language that balances high-level
abstractions and low-level control. It is widely used in systems programming,
game development, performance-critical applications, and for implementing
algorithms where both speed and control over memory matter.
Why learn C++ for computing
Implements algorithms efficiently and maps closely to machine
resources.
Teaches important concepts: memory management, pointers, and
object-oriented design.
Large standard library (STL) supports common data structures and
algorithms for production code.
Basic program structure (visual mapping)
Start → Preprocessor/directives → Declarations → main() → Statements →
Return → End
Simple mapping to code: #include // Preprocessor using namespace std; //
Declarations int main() { // Entry point // statements return 0; // End }
C++ Program Structure — Simple Pattern
Overview
A C++ program follows a small, repeatable pattern: documentation
(optional), headers, global declarations (optional), functions
(including main), and statements. Think of it as a recipe: list the
ingredients, prepare reusable steps, then run the main procedure.
Minimal template (clean and ready)
// 1. Documentation / comments (optional)
// Purpose: short description of the program
// 2. Preprocessor / headers
#include <iostream>
#include <vector> // add headers you need
// 3. Using-directives or namespace (optional)
using namespace std;
// 4. Global declarations (use sparingly)
const int MAX = 100;
// 5. Function declarations / prototypes (optional)
int add(int a, int b);
// 6. main function — program entry point
int main() {
// Initialization / input
int x = 5, y = 3;
// Call functions / core logic
int s = add(x, y);
// Output / finalization
cout << "Sum: " << s << "\n";
return 0;
// 7. Function definitions
int add(int a, int b) {
return a + b;
What each section is for (easy explanation)
Documentation: one- or two-line comment that explains the
program’s purpose. Helpful later.
Headers: bring in library features (IO, strings, containers,
algorithms). Example: , , .
Namespace: using namespace std; shortens code (optional;
you can use std:: explicitly).
Globals: shared constants or configuration; keep minimal to
avoid bugs.
Prototypes: declare functions you will define later so main can
call them.
main(): the program’s starting point. Initialize variables, call
functions, produce output, then return 0.
Function definitions: implement reusable logic; keep each
function focused on one task.
Simple rules and idioms (practical, beginner-friendly)
One logical action per line; one responsibility per function.
Prefer local variables inside functions; avoid globals when
possible.
Name variables clearly: count, index, sum, total.
Use functions to split tasks: input(), compute(), output().
Compile with warnings on (g++ -Wall -Wextra) and fix warnings
early.
Test with small inputs first, then edge cases.
Short annotated example (factorial)
#include <iostream>
using namespace std;
long long factorial(int n) { // function: calculates factorial
long long result = 1;
for (int i = 1; i <= n; ++i) result *= i;
return result;
int main() {
int n;
cout << "Enter n: ";
if (!(cin >> n) || n < 0) { // input validation
cout << "Invalid input\n";
return 0;
cout << "Factorial: " << factorial(n) << "\n"; // use function
return 0;
Why this pattern works: main stays short and readable; heavy logic
lives in a named function you can test separately.
Quick checklist before running code
Include the correct headers for features you use.
Initialize variables before use.
Handle invalid input and edge cases.
Keep main short: delegate tasks to functions.
Compile and fix all warnings.
If you want, I’ll:
Convert this into a one-page cheat-sheet you can print, or
Walk through line-by-line how to turn a pseudocode algorithm
into this C++ pattern using your own example. Which do you
want?
Core language building blocks
Data types and variables
Primitive types: int, long, float, double, char, bool.
Derived: arrays, pointers, references.
Compound: structs, classes.
Example: int count = 10; double pi = 3.14159;
Control flow
Conditional: if, else, switch.
Loops: for, while, do-while.
Example (flow → code): Flow: Read n → If n > 0 then Print "Positive"
else Print "Non-positive" Code: if (n > 0) cout << "Positive"; else cout
<< "Non-positive";
Functions
Encapsulate reusable logic; support parameters and return values.
Example: int add(int a, int b) { return a + b; }
Arrays and strings
Arrays: fixed-size sequences.
std::string: safer, dynamic string type.
Example: vector-like usage later via STL.
Pointers and memory (concept + ASCII diagram)
Pointer stores address of a variable. Use * to dereference, & to get
address.
Memory model (simple):
Stack: Heap: [ main vars ] [ dynamically allocated objects ] (return addr)
Example: int x = 5; int *p = &x; // p points to x *p = 7; // x becomes 7
Be explicit with ownership when using new/delete; prefer smart pointers
(std::unique_ptr, std::shared_ptr).
Object-oriented basics
Class encapsulates data and behavior; supports inheritance and
polymorphism.
Example: class Rectangle { public: int w, h; int area() { return w *
h; } };
Standard Template Library (STL)
Containers: vector, list, deque, map, set, unordered_map.
Algorithms: sort, binary_search, find, transform.
Iterators connect containers and algorithms.
Example: sort a vector vector a = {3,1,2}; sort(a.begin(), a.end()); // a
becomes {1,2,3}
Example programs
1) Hello World
#include <iostream>
using namespace std;
int main() {
cout << "Hello, World!\n";
return 0;
2) Factorial (iterative) — full example with input validation
#include <iostream>
using namespace std;
int main() {
int n;
cout << "Enter a non-negative integer: ";
if (!(cin >> n)) { cout << "Invalid input\n"; return 0; }
if (n < 0) { cout << "Undefined for negative numbers\n"; return 0; }
long long result = 1;
for (int i = 1; i <= n; ++i) result *= i;
cout << "Factorial of " << n << " is " << result << "\n";
return 0;
3) Linear search (array) with return index
#include <iostream>
#include <vector>
using namespace std;
int linear_search(const vector<int>& a, int target) {
for (size_t i = 0; i < a.size(); ++i)
if (a[i] == target) return int(i);
return -1;
int main() {
vector<int> arr = {3,7,2};
int t = 7;
int idx = linear_search(arr, t);
if (idx >= 0) cout << "Found at index " << idx << "\n";
else cout << "Not found\n";
4) Small class example (Rectangle)
#include <iostream>
using namespace std;
class Rectangle {
public:
int w, h;
Rectangle(int width, int height) : w(width), h(height) {}
int area() const { return w * h; }
};
int main() {
Rectangle r(4, 5);
cout << "Area: " << r.area() << "\n";
Mapping algorithm workflow → C++ development
1. Write problem statement and examples.
2. Draft pseudocode.
3. (Optional) Draw flowchart for complex logic.
4. Implement in C++ using small functions and test each piece.
5. Use STL when possible to avoid reinventing containers/algorithms.
6. Test edge cases and large inputs; measure performance if needed.
Debugging and testing tips
Compile with warnings enabled (e.g., g++ -Wall -Wextra).
Test with small inputs first, then edge cases (zero, negative, large).
Use assertions and simple logging (cout) to trace logic.
For memory issues, use tools like Valgrind (or sanitizers: -
fsanitize=address,undefined).