C++ For Students

TODO

not done 
path includes C++ for Students

Basics

Introduction

Basics of all programming languages are almost the same , so if you have already know another programming language just skip this part.

First Program

When someone try to learn programming language the first thing they write is a Hello World program -> more about it here

#completeCode 1

#include <iostream>  
using namespace std;  
  
int main() {  
  cout << "Hello World!";  
  return 0;  
}

How to execute it?

g++ <your_program_name> -o <output_file_name>
./<output_file_name>
Hello World!

Explenation

#include <iostream>  
using namespace std;  
#include <iostream>
using namespace std;
int main(){
  cout << "Some String\n"; // Prints "Some String"
}

if using namespace std is not included the above program will become

#completeCode 3

#include <iostream>
int main(){
std::cout << "Some String\n"; // Prints "Some String"
}

Executing your first program

g++ program_name.cpp -o bin_file_name
./bin_file_name

Screenshot 2025-05-13 at 6.54.34 AM.png
Screenshot 2025-05-13 at 6.54.27 AM.png
Screenshot 2025-05-13 at 6.54.46 AM.png
I have used Vim as the text editor , which is the default editor for linux and g++ for compiling

Printing

Displaying something on the terminal.

#completeCode 4

#include <iostream>  
using namespace std;  
int main() {  
  cout << "Hello World!" << endl;  
  return 0;  
}

Escape characters

Complete list of escape characters can be found here

New Line

#include <iostream>  
using namespace std;  
  
int main() {  
  cout << "Hello \n World!";  
  return 0;  
}
Hello 
World!

Screenshot 2025-05-13 at 12.25.29 PM.png

Comments

Comments will be excluded by the compiler.

// This is a comment in c++
/* 
This is a multi-line comment in c++
*/

Variables

a variable is a named storage location in the computer's memory that holds a value.

#example

int a = 10;
double b = 10.10;
char letter = 'A';
const char* some_string = "Hello World";
std::string some_another_string = "Hello, world";
bool something = false; 

Screenshot 2025-05-13 at 12.28.23 PM.png
a variable in the sense that their value can be changed during the execution of the program.

#snippet

int x = 10;
x = 20; // x is now 20
x = 30; // x is now 30

string

When using std::string the string lib should be included.

#include \<string>
// valid 
int a =10 , b=20 , c 30 ;
// invalid
int a,b,c = 10,20,30 ;
// valid 
int a = 10; 
// valid 
int a ;
a = 10 ; 

Constants

also called literals eg: string literals

const int number = 10 ;
// Error 
number = 20;

Screenshot 2025-05-13 at 12.30.20 PM.png

Datatypes

  1. Builtin Data types(Primitive Datatypes)
  2. Derived Datatypes
  3. User Defined Datatypes

Primitive Data Types

// Integer types 
int x = 500; // 4 bytes 
short x = 100; // 2 bytes 
long x = 1000000L ; // 4 bytes or 8 bytes 
long long x = 10000000000LL; // 8 bytes 
unsigned int x = 10;
// Floating Point 
float x = 1.2 ; // 4 bytes 
double x = 1.2312; // 8 bytes 
long double = 1.23131233434343; // 16 bytes 

// Charaters 
char x = "X" ;
wchar_t x = L"😅";

// Boolean  (0 -> false , 1 -> true)
bool isComplete = true ;
bool isComplete = 1 ;

Size of Datatypes
#include <iostream>
using namespace std;
void print_size(int x){
    cout << x <<  " bytes ; " << x*8 << "bits" << endl;
}
int main(){
    cout << "Integers" << endl ;
    cout << "----------" << endl; 
    print_size(sizeof(int)) ; 
    print_size(sizeof(short)) ; 
    print_size(sizeof(long)); 
    print_size(sizeof(long long)) ;
    cout << "----------" << endl; 
    cout << "floating point" << endl ;
    cout << "----------" << endl; 
    print_size(sizeof(float)) ; 
    print_size(sizeof(double)) ; 
    print_size(sizeof(long double)) ; 
    cout << "----------" << endl; 
    cout << "Character" << endl; 
    cout << "----------" << endl; 
    print_size(sizeof(char)) ;
    print_size(sizeof(wchar_t)) ; 
}

Derived Datatypes

  1. Arrays
  2. Pointers
  3. References

Arrays

int a[] = {1, 2, 3};               
int b[3] = {1, 2, 3};
char c[] = "abc";
char d[] = {'a', 'b', 'c'}; 
char e[3] = {'a', 'b', 'c'};

#example


#include <iostream>
#include <array>
using namespace std;

template <typename T, size_t N>
void print_arr(const T (&arr)[N]) {
   for(size_t i = 0; i < N; i++) {
       cout << arr[i] << " ";
   }
   cout << endl;
}

int main() {
   int a[] = {1, 2, 3};               
   int b[3] = {1, 2, 3};
   char c[] = "abc";
   char d[] = {'a', 'b', 'c'}; 
   char e[3] = {'a', 'b', 'c'};
   print_arr(a);   
   print_arr(b);
   print_arr(c);
   print_arr(d);
   print_arr(e);
   return 0;
}

Pointers

A more notes of pointer can be found here -> Pointers

type* pointer_name;

#examples

#include <iostream>
using namespace std;

int main() {
    int x = 5;
    int* ptr = &x; 
    cout << "Value of x: " << x << endl;
    cout << "Address of x: " << &x << endl;
    cout << "Value of ptr: " << ptr << endl;
    cout << "Value pointed to by ptr: " << *ptr << endl;
    return 0;
}
Value of x: 5
Address of x: 0x7ff7bf3ea2f8
Value of ptr: 0x7ff7bf3ea2f8
Value pointed to by ptr: 5

Operations

  1. Arithmetic Operations
  2. Assignment Operations
  3. Bitwise Operations
  4. Relational Operations
  5. Logical Operations
  6. Comma Operator
    There is actually 4 more operators namely
  7. Size of operator (sizeof)
  8. dot operator (.)
  9. arrow operator (->)
  10. Scope Resolution Operator
    You will study the last 3 in C++ for Students#Intermediate Section

Arithmetic Operators

lets a=10 , b=5

// Addition
c = a + b ; // c = 15 
// increment 
c = c+1 ; // c = 16 

++c; // c = c + 1 ; but beforez excecution c = 17
c++; // c = c + 1 ; but after excecution  c = 17
--c; // c = c - 1 ; but beforez excecution c = 16 
c--; // c = c - 1 ; but after excecution c = 16 
// substract
c = a - b ; // c = 5 

// Multiplication
c = a * b; // c = 50 
// Division 
c = a/b; // c = 2 

// Mod 

c = a % b ; // c = 0 

Screenshot 2025-05-13 at 12.38.56 PM.png

Operator Operation example Returns
+ addition 10 + 10 20
- substraction 10 - 5 5
/ division 10 / 2 5
***** multiplication 10 * 2 20
% modulus operator 10 % 3 1

Assignment operators

int a = 10 ; // Assigns the value 10 to variable a 

Bitwise Operations

int a = 10 ; // 1010 
int b = 5 ; // 0111
// bitwise or
c = a | b ; // c = 1010 or 0111 = 1111 -> 15 

// bitwise xor
c = a ^ b; // c = 1010 or 0111 = 1101 -> 13 

// bitwise not
c = ~a; // c =  not 1010 -> 0101 -> 5

// bitwise and 
c = a & b ; // c = 1010 & 0111 = 0010 -> 2 

// bitwise left shift 
c = a << 2; // c = 1010 << 2 = 0b101000 -> 40  

// bitwise right shift 
c = a >> 2 ; // c = 1010 >> 2 = 0b0010 -> 2 

Screenshot 2025-05-13 at 12.59.08 PM.png
Screenshot 2025-05-13 at 12.59.16 PM.png

Operator Operation
| or
^ xor
~ not
& and
<< left shift
>> right shift

Relational operator

int a = 10 ;
int b = 20;

// Equal to ;
a == b; // false 
a == 10 ; // true 

// Not equal to 
a != b; // true
a != 10; // false

// Greater than 
a > b ; // false
// Greater than or equal to 
a >= 10 ; // true 

// Less than 
a < b; // true 
a <= 10; // true

comparison operators are normally used to check some conditions

Screenshot 2025-05-13 at 1.08.36 PM.png
We can see that sometimes it runs the code inside if{code} and sometimes the code runs else{code} which is the primary use of comparison operator , that is run if else is used to

Operator Name
== Equal to
!= Not equal
> Greater than
< Less than
>= Greater than or equal to
<= Less than or equal to

Logical Operators

int a = 10 , b = 20 , c = 30 ;

// logical and 
a > b && a < c ; // false && true -> false
a < b && a < c ; // true && true -> true 

// logical or 
a > b || a < c ; // false | true -> true 

// logical not

!(a > b) ; // !false -> true 
!(a < b) ; // !true -> false 

Screenshot 2025-05-13 at 1.12.28 PM.png

Operator Name
&& Logical and
|| Logical or
! Logical not

Comma Operator

Screenshot 2025-05-13 at 4.58.46 PM.png


Note

You have reached the end of the c++/basics now go to C++/Intermediate

Storage Classes

  1. Automatic Storage Class (auto)
  2. Static Storage Class (static)
  3. Register Storage Class (register)
  4. External Storage Class (extern)
  5. Thread Storage Class (thread_local)

Automatic Storage Class (auto)

#include <iostream>
int main() {
    auto a = 10;
    std::cout << a;
}

this is same as

#include <iostream>
int main() {
    int a = 10;
    std::cout << a;
}

Static Storage Class (static)

#include <iostream>
int main() {
		static int a = 10;
		std::cout << a;
}

or The static storage class instructs the compiler to keep a local variable in existence during the life-time of the program Source

why:
consider this program

#include <iostream> 
void call_me(){
    static int count = 0 ;
    count++;
    std::cout << count << std::endl; 
}
int main(){
    call_me();
    call_me();
    call_me();
}

Why do you think the output will be ? some thing like this

1
1
1

if you execute this program

#include <iostream> 
void call_me(){
    static int count = 0 ;
    count++;
    std::cout << count << std::endl; 
}
int main(){
    call_me();
    call_me();
    call_me();
}

its output will be

1
1
1

but for the first program the output will be

1
2
3

Screenshot 2025-05-28 at 11.54.42 PM.png
static storage classes are often used to find total number of objects of some class , you will learn about c++ class in this intermediate section.

Register Storage Class (register)

Pasted image 20250528231121.png
as the release of c++17 this is deprecated , but it is still used in c programming language.

#include <iostream>

int main() {
    register int a = 10;
    std::cout << a;
}

Intermediate

In this section you will learn about this is not in some particular order

  1. Functions
  2. Scope
  3. Precedence
  4. OOP
  5. Classes
  6. Objects

rule 🔨 -> {def(what),why,when,example}

x explenation of x
Def Defenition
#example example
syntactic sugar make it readable
Important

You should know this before doing this.

1. Functions

Def: According to this article -> A function in C is a set of statements that, when called, perform some specific tasks

return_type function_name(arguments){
	// block of code..
	return <value>;
}

why: As far as i know you can write an entire application which does not have functions(i meant user defined functions) except main() , this is ok for simple programs that we do first while learning , but as we get hands on the real world problems , functions are must , otherwise you will end up with a file that is few mega bites in size. Using only a single function is not impossible but the main use of functions is to reduce code and reuse code.

graph LR
function_1 & function_2 & function_3 --> Single_Program

when: For example lets consider a psudo[1:1] finding roots of a quadratic equation.
we know the equation

x=b±b24ac2a

This code is written without functions , for the time being ignore the main() function

float a , b , c ; // for storing coeefficients
a = 1 ; b = 2 ; c = -3 ;
float x1 , x2  ; // storing the result
x1 = -b + sqrt(b*b - 4*a*c) / 2 * a ;
x2 = -b - sqrt(b*b - 4*a*c) / 2 * a;

This is written with functions

void get_roots(float a , float b , float c , float &x1,float &x2){
	x1 = -b + sqrt(b*b - 4*a*c) / 2 * a;
	x2 = -b - sqrt(b*b - 4*a*c) / 2 * a;
}
float x1, x2 ; 
get_roots(1,2,-3,x1,x2);

You can see that that the program is gotten bigger. But if we try to compute roots of 5 quadratic equations the first program will become

float a , b , c ; // for storing coeefficients
a = 1 ; b = 2 ; c = -3 ;
float x1 , x2  ; // storing the result
x1 = -b + sqrt(b*b - 4*a*c) / 2 * a ;
x2 = -b - sqrt(b*b - 4*a*c) / 2 * a;
a = 1 ; b = 3 , c = 4 
x1 = -b + sqrt(b*b - 4*a*c) / 2 * a ;
x2 = -b - sqrt(b*b - 4*a*c) / 2 * a;
a = 1 ; b = 3 , c = 4 
x1 = -b + sqrt(b*b - 4*a*c) / 2 * a ;
x2 = -b - sqrt(b*b - 4*a*c) / 2 * a;
a = 1 ; b = 3 , c = 4 
x1 = -b + sqrt(b*b - 4*a*c) / 2 * a ;
x2 = -b - sqrt(b*b - 4*a*c) / 2 * a;
a = 1 ; b = 3 , c = 4 
x1 = -b + sqrt(b*b - 4*a*c) / 2 * a ;
x2 = -b - sqrt(b*b - 4*a*c) / 2 * a;

Now the program with function will become

void get_roots(float a , float b , float c , float &x1,float &x2){
x1 = -b + sqrt(b*b - 4*a*c) / 2 * a;
x2 = -b - sqrt(b*b - 4*a*c) / 2 * a;
}
float x1, x2 ; 
get_roots(1,2,-3,x1,x2);
get_roots(1,2,-3,x1,x2);
get_roots(1,2,-3,x1,x2);
get_roots(1,2,-3,x1,x2);
get_roots(1,2,-3,x1,x2);

One can say that in the non function program , i'm just assigning arbitrary values to a,b and c then calculating using x2 = -b - sqrt(b*b - 4*a*c) / 2 * a;

Declaration or function prototyping

type functionName(argument_lists);

type is essentially means the return type of the function.

#examples

int sum(int a , int b);
int sum(int,int);

Return type

Consider this following program

#include <iostream>
int sum(int number_1,int number_2){
    return number_1 + number_2; 
}
int main(){
    int a = 10 , b = 5 ;
    int c = sum(a,b);
    std::cout << "a + b = " <<  c << std::endl;
}
a + b = 15

There is a function named sum which has a return type of int , the return type is chose according to what type of data we are expecting from the function. For simplicity lets consider the following program which is similar to the above program

#include <iostream>
int sum(int number_1,int number_2){
    return number_1 + number_2; 
}
int main(){
    int a = 10.1, b = 5.4 ;
    int c = sum(a,b);
    std::cout << "a + b = " <<  c << std::endl;
}

the main change is that a is now 10.1 and b is now 5.4
output

a + b = 15

But we can not see any difference in the output it is still 15 also we get warnings like implicit conversion from double to int

Screenshot 2025-05-13 at 6.54.57 PM.png
ie

#include <iostream>
float sum(float number_1,float number_2){
    return number_1 + number_2; 
}
int main(){
    float a = 10.1, b = 5.4 ;
    float c = sum(a,b);
    std::cout << "a + b = " <<  c << std::endl;
}
a + b = 15.5

Can we achieve this using only int? YES

#include <iostream>
typedef struct result{
    int integer_part;
    int decimal_part;
}result;
result sum(int number_1, int number_2,int number_3, int number_4){
    result r;
    r.integer_part = number_1 + number_2;
    r.decimal_part = number_3 + number_4;
    return r;
}
int main(){
    int a = 10, b = 5 , c = 1, d = 4; // 0.1 -> 1 , .4 -> 4 
    result res = sum(a, b, c, d);
    std::cout << "a + b = " << res.integer_part + (res.decimal_part/10.0) << std::endl;
    return 0;
}
a + b = 15.5

we can see that there are already extra complexity , and if the number is 0.01 instead of 0.1 this program will fail. but we can overcome that using a while or for loop by simply checking the length of the integer

choosing datatypes

Data type is must be chose carefully , most of the round off errors will happen due to incorrect datatypes and data types can also influence the performance of the program

Custom Data types in Functions

#include <iostream>
using namespace std;
struct Point {
    int x;
    int y;
};
struct Point create_point(int x, int y) {
    struct Point p;
    p.x = x;
    p.y = y;
    return p;
}
int main() {
    struct Point p = create_point(3, 4);
    cout  << p.x << ", " << p.y << endl;
}

#syntactic_sugar

#include <iostream>
using namespace std;
typedef struct Point {
    int x;
    int y;
} Point;
Point create_point(int x, int y) {
    Point p;
    p.x = x;
    p.y = y;
    return p;
}
int main() {
    Point p = create_point(3, 4);
    cout  << p.x << ", " << p.y << endl;
}

2. Scope

Def: Scope of a variable the region of code within which a variable is accessible[1:2].

#include <iostream>
int a = 10;
void funtion(){
    std::cout << "from function a = " << a << std::endl;
}
int main(){
    std::cout << "global a = " << a << std::endl;
    
    int a = 5;
    funtion();
    std::cout << "local a = " << a << std::endl;

    std::cout << "global a = " << ::a << std::endl;
}
global a = 10
from function a = 10
local a = 5
global a = 10

Why: the scope thing allows us to use/reuse names for local access , for example almost every programmer uses i then j for loops or as the iterator , scope is the best way to avoid pollution , if there no scopes we have to find new names for each variable that is going to be declared .

Control Statements

if-else

#syntax

if (expression)
	statement
if (expression)
	statement
else
	statement
if (expression)
	statement
else if (expression)
	statement 
else
	statement 
if (expression)
	if(expression)
		if(expression)
			statement

which is similar to

if(expression && expression && expression)
	statement

#examples

#include <iostream>
int main(){
int a = 10 ;
if (a == 10 ){
	std::cout << "HI" << std::endl;
	}
}
HI
#include <iostream>
int main(){
int a = 10 ;
if (a == 9 ){
	std::cout << "HI" << std::endl;
	}
}
// Nothing will be here 
true and flase

a value other than 1 is consderd as true , so the following programs all will output the same result

> #include <iostream>
int main(){
int a = 10 ;
if (a - 5 ){ // true
 	std::cout << "HI" << std::endl;
 	}
 }
#include <iostream>
int main(){
int a = 10 ;
if (a - 100){ // true 
 	std::cout << "HI" << std::endl;
	}
}

While

while(expression)
	statement

C++ Structs

You all will be familiar with C structs if dont check this Structs.
Look at one #example

#include <iostream>
using namespace std;
struct Point{
    int x;
    int y;
    Point(int _x, int _y) : x(_x), y(_y) {}
    void display() {
        cout << "Point(" << x << ", " << y << ")" << endl;
    }
};
int main(){
    Point p1(10, 20);
    p1.display();
}

First thing you can notice is that , in struct definition there are member functions , Constructor etc.

Constructor

Point(int _x, int _y) : x(_x), y(_y) {}

This will assign value _x to x and value _y to y . You can extend this to make things like the following.

Point(int _x, int _y) {
        x = _x * 100;
        y = _y * 100;
    }

This is exactly like the C++ Class constructor.

Member Functions

void display() {
        cout << "Point(" << x << ", " << y << ")" << endl;
    }

you can call them by struct_name.function_name() just like accessing the value inside a struct

Advanced


  1. https://docs.julialang.org/en/v1/manual/variables-and-scoping ↩︎ ↩︎ ↩︎

  2. Block of code ↩︎