StudyHub
⚙️ C & C++
← Coding Notes
Language notes · Beginner to confident

C & C++ notes for beginners

C is the language operating systems, engines and embedded chips are written in. C++ adds objects on top of it. They are compiled — faster than almost anything else — and they are the languages where you finally understand what memory actually is.

Difficulty: Steeper, but worth it Great for: Game engines, systems, robotics, DSA Compile with: g++ main.cpp -o app 9 chapters · 20+ examples
01

What C & C++ are

Fast, compiled, and close to the machine

C1972Dennis Ritchie · small, fast, everywhere
C++1985Bjarne Stroustrup · C plus objects

Both are compiled: the whole program is translated into machine code before it runs, which is why they are so fast. Windows, Linux, Photoshop, game engines and the software inside washing machines all rest on them.

Setting up

  • 1
    Install a compiler. On Windows, MinGW-w64 (or MSYS2). On Mac, xcode-select --install. On Linux, sudo apt install build-essential.
  • 2
    Install VS Code with the C/C++ extension for highlighting and debugging.
  • 3
    Save your file as .c for C or .cpp for C++, then compile it from the terminal.
  • 4
    Check it worked: g++ --version should print a version number.
02

Your first program & compiling

Write, compile, run — three separate steps

C hello.c
#include <stdio.h>      /* input / output library */

int main(void) {          /* program starts here */
    printf("Hello, Study Hub!\n");
    printf("2 + 3 = %d\n", 2 + 3);
    return 0;             /* 0 means "finished successfully" */
}
C++ hello.cpp
#include <iostream>       // input / output streams

int main() {
    std::cout << "Hello, Study Hub!" << std::endl;
    std::cout << "2 + 3 = " << 2 + 3 << std::endl;
    return 0;
}

/* after the first few files you can save typing with:
   using namespace std;
   and then write  cout << "text";  directly.  */

Compile and run

Terminal the three steps
# C
gcc hello.c -o hello
./hello                      # Windows: hello.exe

# C++
g++ hello.cpp -o hello
./hello

# turn on warnings - they find real bugs for free
g++ -Wall -Wextra hello.cpp -o hello
  • 1
    Every C/C++ program needs exactly one main(). That is where execution begins.
  • 2
    Statements end with a semicolon ; and blocks use curly braces { }.
  • 3
    Add -Wall -Wextra to every compile command. The warnings catch uninitialised variables and typos before they become bugs.
  • 4
    Compile errors are normal — expect several on your first day. Fix the first one only; the rest are often just its echo.
03

Variables & data types

You must say what type every variable is

Unlike Python or JavaScript, C and C++ need the type written out. That is what makes them fast — the compiler knows exactly how many bytes each value uses.

TypeHoldsSize (usually)printf format
intWhole numbers4 bytes%d
floatDecimals (about 7 digits)4 bytes%f
doubleDecimals, more precise8 bytes%lf
charOne character1 byte%c
booltrue / false (C++)1 byte
constAnything that must not change
C++ types.cpp
#include <iostream>
using namespace std;

int main() {
    int marks = 87;              // whole number
    double percent = 87.5;       // decimal
    char grade = 'A';            // ONE character, single quotes
    bool passed = true;          // C++ only
    auto guess = 42;             // C++ figures out the type
    const double GST = 0.18;     // cannot be changed later

    cout << "Marks: " << marks << endl;
    cout << "Percent: " << percent << endl;
    cout << "Grade: " << grade << endl;

    // integer division drops the fraction - a classic surprise
    cout << 7 / 2 << endl;                       // 3
    cout << 7 / 2.0 << endl;                     // 3.5
    cout << (double)7 / 2 << endl;                // 3.5 by casting

    // uninitialised variables hold garbage - always give a value
    int total = 0;               // never: int total;
    total = marks + 13;
    cout << "Total: " << total << endl;

    return 0;
}
04

Operators & getting input

Maths, comparisons, and reading what the user types

OperatorMeaningExampleResult
+ - * /The usual four7 / 23 (int division!)
%Remainder7 % 21
++ --Add or subtract onei++i increases by 1
+= -=Shortcut mathstotal += 5total = total + 5
== !=Equal, not equala == btrue / false
< > <= >=Comparisons7 > 3true
&& || !And, or, nota && btrue if both true
& *Address of, and pointer&x, *psee chapter 7
C input.c
#include <stdio.h>

int main(void) {
    int age;
    double marks;

    printf("Your age: ");
    scanf("%d", &age);        /* & = "the address of age" */

    printf("Your marks: ");
    scanf("%lf", &marks);     /* %lf for a double */

    printf("Next year: %d\n", age + 1);
    printf("Marks: %.2f\n", marks);   /* %.2f = 2 decimal places */

    /* %-10s pads to 10 characters, left aligned */
    printf("|%-10s|%6d|\n", "Maths", 78);

    return 0;
}
C++ input.cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    int age;
    string name;                     // C++ has easy text

    cout << "Your name: ";
    getline(cin, name);              // reads a whole line
    cout << "Your age: ";
    cin >> age;

    cout << "Hello " << name
         << ", next year you will be " << age + 1 << endl;

    return 0;
}
  • 1
    In C, forgetting the & in scanf is a crash waiting to happen. The exception is reading a string into a char array.
  • 2
    7 / 2 gives 3 with integers. Use 7 / 2.0 or cast one side to double for 3.5.
  • 3
    switch on an integer is faster and cleaner than a long chain of if/else. Every case needs break.
05

Conditions & loops

Curly braces and semicolons, every time

C++ decisions.cpp
int marks = 78;
string grade;

if (marks >= 90) {
    grade = "A+";
} else if (marks >= 75) {
    grade = "A";
} else if (marks >= 33) {
    grade = "B";
} else {
    grade = "F";
}

// ternary
string label = (marks >= 33) ? "Pass" : "Fail";

// switch needs break, or it falls through
switch (marks / 10) {
    case 10:
    case 9:  grade = "A+"; break;
    case 8:  grade = "A";  break;
    default: grade = "B";
}
C++ loops.cpp
// for - the standard counting loop
for (int i = 1; i <= 5; i++) {
    cout << i << " ";
}

// while
int count = 1;
while (count <= 3) {
    cout << "Round " << count << endl;
    count++;                  // forget this = infinite loop
}

// do...while always runs at least once
int choice;
do {
    cout << "1) Notes  2) Exit" << endl;
    cin >> choice;
} while (choice != 2);

// break and continue
for (int n = 1; n <= 10; n++) {
    if (n == 8) break;         // stop the loop
    if (n % 2 == 0) continue;  // skip this round
    cout << n << " is odd" << endl;
}

// the modern C++ range loop
int marks[] = {78, 91, 66};
for (int m : marks) {
    cout << m << endl;
}
06

Functions

Declared above main, or prototyped below it

C++ functions.cpp
#include <iostream>
using namespace std;

// you must state the return type and every parameter type
int add(int a, int b) {
    return a + b;
}

double average(double a, double b) {
    return (a + b) / 2.0;
}

// default arguments must come last
double power(double base, int exponent = 2) {
    double result = 1;
    for (int i = 0; i < exponent; i++) result *= base;
    return result;
}

// void = returns nothing
void printLine(int width = 20) {
    for (int i = 0; i < width; i++) cout << "-";
    cout << endl;
}

// pass by reference: changes the caller's variable (C++)
void bump(int &value) {
    value++;
}

// prototype: declares a function you define further down
int gradePoints(int marks);

int main() {
    cout << add(3, 4) << endl;              // 7
    cout << average(80, 90) << endl;        // 85
    cout << power(2, 10) << endl;           // 1024
    cout << power(5) << endl;              // 25 (default exponent)

    printLine(15);

    int score = 10;
    bump(score);
    cout << score << endl;                  // 11

    cout << gradePoints(78) << endl;
    return 0;
}

int gradePoints(int marks) {
    if (marks >= 90) return 10;
    if (marks >= 75) return 9;
    return 8;
}
  • 1
    The compiler reads top to bottom, so a function must be declared before it is used. Either define it above main, or write a prototype line.
  • 2
    Passing by value copies the data. Adding & in C++ (or a pointer in C) lets the function change the caller's variable — and avoids copying big objects.
  • 3
    Keep main() short. It should read like a table of contents that calls well-named functions.
07

Arrays & pointers

Where C becomes worth learning

C arrays.c
#include <stdio.h>

int main(void) {
    int marks[5] = {78, 91, 66, 88, 72};   /* fixed size, known at compile time */
    int count = 5;
    int total = 0;

    printf("First: %d  Last: %d\n", marks[0], marks[count - 1]);

    for (int i = 0; i < count; i++) {
        total += marks[i];
    }
    printf("Average: %.1f\n", (double)total / count);

    /* a 2D array: 2 students, 3 subjects each */
    int grid[2][3] = {{78, 91, 66}, {92, 88, 95}};
    for (int r = 0; r < 2; r++) {
        int sum = 0;
        for (int c = 0; c < 3; c++) sum += grid[r][c];
        printf("Student %d average: %.1f\n", r + 1, (double)sum / 3);
    }

    /* text is just an array of characters ending with '\0' */
    char name[] = "Ayush";
    printf("Hello, %s (%d letters)\n", name, (int)strlen(name));

    return 0;
}

Pointers, explained without fear

Every variable lives at a numbered address in memory. A pointer is simply a variable that stores one of those addresses, so you can pass the location of data around instead of copying it.

C pointers.c
#include <stdio.h>

/* a function that CAN change the caller's variables */
void swap(int *a, int *b) {
    int temp = *a;      /* * means "the value at this address" */
    *a = *b;
    *b = temp;
}

int main(void) {
    int marks = 87;

    int *p = &marks;     /* & means "the address of marks" */

    printf("Value: %d\n", marks);    /* 87      */
    printf("Value via pointer: %d\n", *p); /* 87  */
    printf("Address: %p\n", (void *)p);

    *p = 95;                          /* changes marks itself */
    printf("Now marks is %d\n", marks);    /* 95 */

    int x = 1, y = 2;
    swap(&x, &y);
    printf("x=%d y=%d\n", x, y);      /* x=2 y=1 */

    /* dynamic memory: ask for space while the program runs */
    int *nums = malloc(5 * sizeof(int));
    if (nums == NULL) return 1;       /* always check! */
    for (int i = 0; i < 5; i++) nums[i] = (i + 1) * 10;
    printf("%d\n", nums[4]);          /* 50 */
    free(nums);                       /* give it back - no malloc without free */
    nums = NULL;                      /* avoids a dangling pointer */

    return 0;
}
08

C++ extras

string, vector and class — the parts that make life easier

C++ strings_vectors.cpp
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>     // sort, reverse, max_element
using namespace std;

int main() {
    // ---- string: length, joining and searching are built in ----
    string name = "Ayush Danthta";
    cout << name.length() << endl;             // 13
    cout << name.substr(0, 5) << endl;         // Ayush
    cout << name.find("Danthta") << endl;      // 6  (npos if missing)
    name += " ji";                             // easy appending
    for (char c : name) { /* loop each character */ }

    // ---- vector: an array that grows by itself ----
    vector<int> marks = {78, 91, 66};
    marks.push_back(88);                       // add to the end
    cout << marks.size() << endl;              // 4
    cout << marks[0] << " " << marks.back() << endl;

    sort(marks.begin(), marks.end());          // lowest to highest
    reverse(marks.begin(), marks.end());       // highest to lowest

    int total = 0;
    for (int m : marks) total += m;            // range loop
    cout << "Average: " << (double)total / marks.size() << endl;

    // ---- a class: your own type with data and behaviour ----
    class Student {
        private:
            string name;
            vector<int> marks;

        public:
            Student(string n) : name(n) {}     // constructor

            void addMark(int m) {
                if (m >= 0 && m <= 100) marks.push_back(m);
            }

            double average() const {
                if (marks.empty()) return 0;
                int sum = 0;
                for (int m : marks) sum += m;
                return (double)sum / marks.size();
            }

            void report() const {
                cout << name << " -> " << average() << endl;
            }
    };

    Student s("Ayush");
    s.addMark(78);
    s.addMark(91);
    s.addMark(66);
    s.report();                                // Ayush -> 78.3333

    return 0;
}
ConceptMeaning in one line
classA blueprint describing data plus the functions that work on it
privateOnly the class itself can touch it — hidden by default
publicAnyone using the object can call it
constructorA function with the class name that runs when you create the object
const methodPromises not to change the object — safe to call on anything
vectorAn array that resizes itself and knows its own length
reference (&)Another name for an existing variable — no copying
09

C & C++ cheat sheet

Keep this open while you practise

Do thisWrite thisNotes
Include a library#include <stdio.h><iostream> in C++
Entry pointint main() { … return 0; }Exactly one per program
Print (C)printf("Hi\n");\n means new line
Print (C++)cout << "Hi" << endl;Double < points to cout
Whole numberint n = 0;Always give a value
Decimaldouble d = 1.5;Prefer over float
Characterchar c = 'A';Single quotes
Text (C++)string s = "Ayush";Needs <string>
Text (C)char s[] = "Ayush";Ends with '\0'
Unchangeableconst int MAX = 100;Good habit
Read a numberscanf("%d", &n);Do not forget &
Read a number (C++)cin >> n;Arrow points to cin
Print a variableprintf("%d\n", n);%d int, %f double, %s text, %c char
Decideif (n > 5) { }Braces, then semicolons inside
Count loopfor (int i = 0; i < 5; i++)Runs 5 times
Walk an arrayfor (int m : marks)C++ only
Make an arrayint m[5] = {1,2,3,4,5};Fixed size, no bounds checking
Growable listvector<int> v;C++ — use v.push_back(x)
Size of a vectorv.size()Array in C: track it yourself
Sortsort(v.begin(), v.end());Needs <algorithm>
Address of&valueWhere it lives in memory
Value at a pointer*ptrDereference
Make a pointerint *p = &x;Must match the type
Functionint add(int a, int b) { return a + b; }Define above main or use a prototype
Change the caller's valuevoid f(int &x) (C++) or void f(int *x)Pass by reference
Ask for memorymalloc(5 * sizeof(int))Pair every one with free()
Compileg++ -Wall -Wextra main.cpp -o appThen run ./app

Practice project: marks report card

C++ report.cpp
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
using namespace std;

struct Student {
    string name;
    vector<int> marks;
};

double average(const vector<int> &nums) {
    if (nums.empty()) return 0;
    int sum = 0;
    for (int n : nums) sum += n;
    return (double)sum / nums.size();
}

char gradeOf(double avg) {
    if (avg >= 85) return 'A';
    if (avg >= 70) return 'B';
    if (avg >= 50) return 'C';
    return 'D';
}

int main() {
    vector<Student> students = {
        {"Ayush", {78, 91, 66}},
        {"Riya",  {92, 88, 95}},
        {"Karan", {45, 52, 60}},
    };

    cout << left << setw(8) << "Name"
         << setw(10) << "Average"
         << setw(8) << "Grade" << endl;

    cout << string(26, '-') << endl;

    double classTotal = 0;
    for (const Student &s : students) {
        double avg = average(s.marks);
        classTotal += avg;

        cout << left << setw(8) << s.name
             << setw(10) << fixed << setprecision(1) << avg
             << setw(8) << gradeOf(avg) << endl;
    }

    cout << string(26, '-') << endl;

    cout << "Class average: "
         << fixed << setprecision(1)
         << classTotal / students.size() << endl;

    return 0;
}

Test yourself

Four quick questions on C & C++

Q1 What does 7 / 2 give when both are int?

Q2 What does &marks mean?

Q3 Why must every variable be given a value before use?

Q4 Which container resizes itself as you add items?

Answered 0 of 4 · correct 0

Continue with another language

Same structure, same depth — pick the one you need next.