C++ - Cheat Sheet



This C++ programing cheat sheet can be very handy to use and provides key information in a short time frame. It is tailormade for people who want to address important topics and leap into the world of programming in C++. This includes all major and minor details one might need to surf through, and contains examples and code snippets to guide people on how to practically use this language.

Introduction to C++ Programming Language

C++ stands out as a robust and efficient programming language. It's a cornerstone for crafting operating systems, software for embedded systems, and the engines that power video games. Due to its demanding nature for learners, a cheat sheet can be an invaluable tool for both programmers new to the field and those with experience.

Basics of C++

The First Program: Hello World

The very foundation of any programming language is the process of it's development. And any beginner starts to learn a programming language by learning it's syntax. So, let's start by writing the very first program in C++, ie. Hello World −

Example

#include <bits/stdc++.h>
using namespace std;

// main() is where program execution begins.
int main() {

   cout<<"Hello World"<<endl;

   // This is where you write your code
   return 0;
}
Output
Hello World

Comments

Comments in C++ are used to write extra information that are useful to the programmer. C supports single-line comment // is used to indicate the single-line comment, whereas /* is used to start a multi-line comment and */ to end it.

Example

#include <bits/stdc++.h>
using namespace std;

int main() {
   /* This is multi-lined comment.
   The below statement will only print Hello World*/

   cout<<"Hello World"<<endl;

   // This is a single-lined comment

   return 0;
}
Output
Hello World

Input and Output Statements

Here, "cin" is the input statement, accompanied by ">>", whereas "cout" is the output statement, accompanied by ">>".

Example

#include <bits/stdc++.h>
using namespace std;

int main() {
	
   //declaration of an integer variable
   int age;
   cout << "Enter your age: "<<endl;
   cin >> age;
   cout << "Your age is: " << age << endl;
   return 0;
}

Variables

Variables are areas of storage where different types of data can be invariably stored. The variables in c++ must be declared before using, and the names of variables must start with an alphabet, and can contain letters, numbers and underscore(_).

Example

#include <bits/stdc++.h>
using namespace std;

int main() {
	
   // Declaring multiple variables
   int a, b, c;
   char ch;
   string s;
   return 0;
}

Keywords in C++

Keywords are special type of words that are reserved by the compiler of a specific language and can’t be explicitly used by the programmer. Some of these keywords are as follows −

asm else new this
auto enum operator throw
bool explicit private true
break export protected try
case extern public typedef
catch false register typeid
char float reinterpret_cast typename
class for return union
const friend short unsigned
const_cast goto signed using
continue if sizeof virtual
default inline static void
delete int static_cast volatile
do long struct wchar_t
double mutable switch while
dynamic_cast namespace template  

Data Types

Data types are types of available classifications of storage where variables are stored in the memory. Data types can be categorized into three sections −

Primitive data types

Primitive data types are already existing in the c++ language libraries. These can be used without any modification.

Int

The keyword used for integer data types is int. Integers typically require 4 bytes of memory space and range from -2147483648 to 2147483647.

Float

Floating Point data type is used for storing single-precision floating-point values or decimal values. The keyword used for the floating-point data type is float. Float variables typically require 4 bytes of memory space.

Char

Character data type is used for storing characters. The keyword used for the character data type is char. Characters typically require 1 byte of memory space and range from -128 to 127 or 0 to 255.

Double

Double Floating Point data type is used for storing double-precision floating-point values or decimal values. The keyword used for the double floating-point data type is double.

String

String data type is used for storing multiple characters together in a single variable.

Bool

Boolean data type is used for storing Boolean or logical values. A Boolean variable can store either true or false. The keyword used for the Boolean data type is bool.

Example

int main() {
	
   int age=12; 
   //takes only whole numbers, size is 4 Bytes

   float weight=70.4; 
   //takes decimal valued numbers, size is 4 Bytes

   char alpha='a'; 
   //takes single characters as per ASCII, size is 1 Bytes

   string s="hey siri"; 
   //takes multiple characters, size is variable

   double d=2.2222; 
   //takes more precise floating point numbers, size is 8 Bytes

   bool k=true; 
   //takes only true or false values (or 0/1)
	    
   return 0;
}

Derived data types

These are derived from the primitive datatypes , and are referred to as Derived Data Types. These can be of four types namely −

These are briefly discussed in the further sections.

User-defined data types

These datatypes are defined by the user itself, and can be customized as per the user's wish. These are of five types mainly −

Class

The concept of classes and objects is explained in OOPS section of this cheatsheet. Examples can be referred here.

Example
#include <bits/stdc++.h>
using namespace std;

class MyClass {       
   public:             
      int myNum;        
      string myString;  
};

int main() {
   MyClass myObj;  

   myObj.myNum = 1234567; 
   myObj.myString = "Helloooo";

   cout << myObj.myNum << "\n";
   cout << myObj.myString;
   return 0;
}
Output
1234567
Helloooo

Structure

The syntax of defining a structure is as follows.

struct structName{
   char  varName[size];
   int varName;
};

Union

The syntax of defining a union is as follows.

Union_Name{
   // Declaration of data members
}; union_variables;

Enumeration

The syntax of defining an enum variable is as follows.

enum  nameOfEnum {
   varName1 = 1, varName2 = 0
};

Typedef

The syntax of defining a typedef is as follows.

typedef typeName;

Example

#include <bits/stdc++.h>
using namespace std;

typedef unsigned char BYTE; 

int main() { 
   BYTE b1, b2; 
   b1 = 'c'; 
   cout << " " << b1; 
   return 0; 
}
Output
c

Conditional Statements

Conditional statements control the flow of the program, and can be used when we need to define different cases and conditions. The primitives "if", "else", "else if", "switch" and the ternary operator are used in such cases.

  • if Statement
  • if-else Statement
  • if-else-if Statement
  • Nested if-else Statement
  • Switch Statement
  • Ternary Operator

If statement

If statement executes a block of code if and only if the given condition is true.

if-else Statement

If the condition inside the if statement is true, then the code inside the if block will get executed, otherwise code inside the else block will get executed.

if-else-if Statement

The else if statement allows you to check for multiple conditions sequentially.

Nested if Statements

Multiple if statements can be nested inside each other to form different cases as per requirement.

Ternary Operator

It works as a conditional statement which takes a conditional statement and returns either the first statement or the second statement.

Switch Case

In case of multiple conditions, we can simply use switch case statements to make it easier to handle such conditions.

Example

#include <iostream>
using namespace std;
int main() {
	
   //program to explain if, else if and else conditions
   int age=12; 
   if(age<12) cout<<"YES"<<endl;

   else if(age>24) cout<<"NO"<<endl;

   else cout<<"MAYBE"<<endl;


   //program to explain ternary operator
   bool x=true;
   x==1 ? cout<<"true"<<endl : cout<<"false"<<endl;


   //program to explain switch case with break and default

   switch (x & x){
      case 0 :
         cout<<"false"<<endl;
      break;

      case 1 :
         cout<<"true"<<endl;
      break;

      default:
         cout<<"invalid"<<endl;
      break;
   }
   return 0;
}

Output

MAYBE
true
true

Operators in C++

Operators in C++ can be classified into 6 types −

Arithmetic Operators

These operators are used to perform arithmetic or mathematical operations on the operands. For example, ‘+’ is used for addition, ‘-‘ is used for subtraction ‘*’ is used for multiplication, etc.

Example

#include <iostream>
using namespace std;
int main() {
   int a = 8, b = 3;

   // Addition operator
   cout << "a + b = " << (a + b) << endl;
  
   // Subtraction operator
   cout << "a - b = " << (a - b) << endl;
  
   // Multiplication operator
   cout << "a * b = " << (a * b) << endl;
  
   // Division operator
   cout << "a / b = " << (a / b) << endl;
  
   // Modulo operator
   cout << "a % b = " << (a % b) << endl;

   //unary operators
   a++;
   cout<<a<<endl;

   a--;
   cout<<a<<endl;

   int k=++a + ++b;
   cout<<k<<endl;

   k=++a - --b;
   cout<<k<<endl;

   return 0;
}
Output
a + b = 11
a - b = 5
a * b = 24
a / b = 2
a % b = 2
9
8
13
7

Relational Operators

These operators are used for the comparison of the values of two operands. For example, ‘>’ checks if one operand is greater than the other operand or not, etc. The result returns a Boolean value, i.e., true or false.

Example

#include <iostream>
using namespace std;
int main() {
   int a = 6, b = 4;

   // Equal to operator
   cout << "a == b is " << (a == b) << endl;
  
   // Greater than operator
   cout << "a > b is " << (a > b) << endl;
  
   // Greater than or Equal to operator
   cout << "a >= b is " << (a >= b) << endl;
  
   //  Lesser than operator
   cout << "a < b is " << (a < b) << endl;
  
   // Lesser than or Equal to operator
   cout << "a <= b is " << (a <= b) << endl;
  
   // true
   cout << "a != b is " << (a != b) << endl;

   return 0;
}
Output
a == b is 0
a > b is 1
a >= b is 1
a < b is 0
a <= b is 0
a != b is 1

Logical Operators

These operators are used to combine two or more conditions or constraints, or to complement the evaluation of the original condition in consideration. The result returns a Boolean value, i.e., true or false.

Example

#include <iostream>
using namespace std;
int main() {
   int a = 6, b = 4;

   // Logical AND operator
   cout << "a && b is " << (a && b) << endl;
  
   // Logical OR operator
   cout << "a || b is " << (a || b) << endl;
  
   // Logical NOT operator
   cout << "!b is " << (!b) << endl;

   return 0;
}
Output
a && b is 1
a || b is 1
!b is 0

Bitwise Operators

These operators are used to perform bit-level operations on the operands. The operators are first converted to bit-level and then the calculation is performed on the operands. Mathematical operations such as addition, subtraction, multiplication, etc. can be performed at the bit level for faster processing.

Example

#include <iostream>
using namespace std;
int main() {
   int a = 6, b = 4;

   // Binary AND operator
   cout << "a & b is " << (a & b) << endl;

   // Binary OR operator
   cout << "a | b is " << (a | b) << endl;

   // Binary XOR operator
   cout << "a ^ b is " << (a ^ b) << endl;

   // Left Shift operator
   cout << "a<<1 is " << (a << 1) << endl;

   // Right Shift operator
   cout << "a>>1 is " << (a >> 1) << endl;

   // One’s Complement operator
   cout << "~(a) is " << ~(a) << endl;

   return 0;
}
Output
a & b is 4
a | b is 6
a ^ b is 2
a<<1 is 12
a>>1 is 3
~(a) is -7

Assignment Operators

These operators are used to assign value to a variable. The left side operand of the assignment operator is a variable and the right side operand of the assignment operator is a value. The value on the right side must be of the same data type as the variable on the left side otherwise the compiler will raise an error.

Example

#include <iostream>
using namespace std;
int main() {
   int a = 6, b = 4;

   // Assignment Operator
   cout << "a = " << a << endl;
  
   //  Add and Assignment Operator
   cout << "a += b is " << (a += b) << endl;
  
   // Subtract and Assignment Operator
   cout << "a -= b is " << (a -= b) << endl;
  
   //  Multiply and Assignment Operator
   cout << "a *= b is " << (a *= b) << endl;
  
   //  Divide and Assignment Operator
   cout << "a /= b is " << (a /= b) << endl;

   return 0;
}
Output
a = 6
a += b is 10
a -= b is 6
a *= b is 24
a /= b is 6

Loops

Looping statements are used to traverse through some data in a contiguous manner. Loops are used extensively in data structures like arrays, linked lists, graphs, trees and so on. These are the building blocks of concepts like recursion, dynamic programming and graph theory, which are advanced concepts. There are mainly three types of looping statements

For loop

For loops are used to travel a certain data stucture for a specific number of times before ending the loop at an ending condition.

Example

#include <iostream>
using namespace std;
int main() {
   for(int i=0;i<6;i++){
      cout<<"hello"<<endl;
   }
   return 0;
}
Output
hello
hello
hello
hello
hello
hello

While loop

While loops are used to run a looping statement until the specified condition turns false, otherwise the loops runs continuously.

Example

#include <bits/stdc++.h>
using namespace std;

int main() {
   int i=0;
   while(i<6){
      cout<<"hello"<<endl;
      i++;
   }
   return 0;
}
Output
hello
hello
hello
hello
hello
hello

Do-while loop

In do-while loops, the loop runs the first time on a given condition and then checks the while statement to run further.

Example

#include <bits/stdc++.h>
using namespace std;
int main() {
   int i=0;
   do{
      cout<<"hello"<<endl;
      i++;
   }while(i<6);

   return 0;
}
Output
hello
hello
hello
hello
hello
hello

References and Pointers

References and pointers are used to describe the place and the face value of the variable declared by the user.

References

References are used to create a new name for the same memory location and the value stored there. We can create reference to any variable using ampersand($) symbol next to the variable name.

Example

#include <bits/stdc++.h>
using namespace std;
int main() {
   int i=3;
   int &k=i;

   cout<<i<<k<<endl;
   return 0;
}
Output
33

Pointers

Pointers are variables that are used to store the address of the variable that they point to, and the * is used to declare a pointer to any variable.

Example

#include <bits/stdc++.h>
using namespace std;
int main() {
   int a=4;
   int *ptr=&a;

   cout<<a<<ptr<<*ptr<<endl;

   return 0;
}
Output
40x7ffeb2bcfb0c4

Arrays

An array is a sequence of elements of same data type that are stored in contiguous memory locations in the storage. The array can be declared with and without the number of elements.

Example

#include <bits/stdc++.h>
using namespace std;
int main() {    
   int arr1[]={1,2,3,4,4,3,2,1};
   int arr2[8]={0};

   for(int i=0;i<8;i++){
      cout<<arr1[i]<<arr2[i]<<endl;
   }
     
   return 0; 
}

Output

10
20
30
40
40
30
20
10

Multidimensional Arrays

Arrays can also be defined in more than one dimensions, with all elements of the same datatype.

Example

#include <bits/stdc++.h>
using namespace std;
int main() {    
   int arr[2][3]={{1,2,3},{4,4,3}};
    
   for(int i=0;i<2;i++){
      for(int j=0;j<3;j++){
         cout<<arr[i][j]<<endl;
      }
   }
   return 0; 
}
Output
1
2
3
4
4
3

Functions

Functions are parts of the code that can be called if defined previously, and help to make the code concise and readable. Functions can be created as part of the program or in the class body as well. The first function executed by the compiler in c++ is the main function.

The function has a name, a return type (which can also be void), input variables and a method body. The example below showcases how functions are defined and used in c++.

Functions in c++ can be of two types −

  • Primitive Functions which are already defined in the c++ library. Examples of primitive functions are math functions like sin(), cos(), min(), max() and so on.
  • User Defined Functions, which are defined as per the requirement of the user and can be customized accordingly.

Example

#include <bits/stdc++.h>
using namespace std;
void sum1(int &a, int &b){
   b+=a;
}
int main(){
   int a=10, b=12;
   sum1(a,b);    
   cout<<b<<a<<endl;
   return 0; 
}

Output

2210

Math Functions in C++

C++ being a superset of C, supports a large number of useful mathematical functions. These functions are available in standard C++ to support various mathematical calculations.

Instead of focusing on implementation, these functions can be directly used to simplify code and programs. In order to use these functions you need to include a header file − <math.h> or <cmath>.

The below example shows the use of many such math functions that can be directly used instead of complex calculations.

Example

#include <bits/stdc++.h>
using namespace std;

int main() {
   double x = 2.3;
   cout << "Sine value of x=2.3 : " << sin(x) << endl;
   cout << "Cosine value of x=2.3 : " << cos(x) << endl;
   cout << "Tangent value of x=2.3 : " << tan(x) << endl;
 
   double y = 0.25;
   cout << "Square root value of y=0.25 : " << sqrt(y)
      << endl;
 
   int z = -10;
   cout << "Absolute value of z=-10 : " << abs(z) << endl;
   cout << "Power value: x^y = (2.3^0.25) : " << pow(x, y)
      << endl;
 
   x = 3.0;
   y = 4.0;
   cout << "Hypotenuse having other two sides as x=3.0 and"
      << " y=4.0 : " << hypot(x, y) << endl;
 
   x = 4.56;
   cout << "Floor value of x=4.56 is : " << floor(x)
      << endl;
 
   x = -4.57;
   cout << "Absolute value of x=-4.57 is : " << fabs(x)
      << endl;
 
   x = 1.0;
   cout << "Arc Cosine value of x=1.0 : " << acos(x)
      << endl;
   cout << "Arc Sine value of x=1.0 : " << asin(x) << endl;
   cout << "Arc Tangent value of x=1.0 : " << atan(x)
      << endl;
 
   y = 12.3;
   cout << "Ceiling value of y=12.3 : " << ceil(y) << endl;
 
   x = 57.3; // in radians
   cout << "Hyperbolic Cosine of x=57.3 : " << cosh(x)
      << endl;
   cout << "Hyperbolic tangent of x=57.3 : " << tanh(x)
      << endl;
 
   y = 100.0;
   // Natural base with 'e'
   cout << "Log value of y=100.0 is : " << log(y) << endl;
 
   return 0;
}

Output

Sine value of x=2.3 : 0.745705
Cosine value of x=2.3 : -0.666276
Tangent value of x=2.3 : -1.11921
Square root value of y=0.25 : 0.5
Absolute value of z=-10 : 10
Power value: x^y = (2.3^0.25) : 1.23149
Hypotenuse having other two sides as x=3.0 and y=4.0 : 5
Floor value of x=4.56 is : 4
Absolute value of x=-4.57 is : 4.57
Arc Cosine value of x=1.0 : 0
Arc Sine value of x=1.0 : 1.5708
Arc Tangent value of x=1.0 : 0.785398
Ceiling value of y=12.3 : 13
Hyperbolic Cosine of x=57.3 : 3.83746e+24
Hyperbolic tangent of x=57.3 : 1
Log value of y=100.0 is : 4.60517

Object-Oriented Programming

OOPS concepts exist in C++ as well. This basically means the program can be subcategorized into classes and objects.

Class and Object

Class

A class is a user-defined data type that has two components, the variables and the methods. The class can be initialized using a constructor.

Objects

An object is an instance or a variable of the class. Objects occupy memory in the storage space.

OOPS Concepts

Encapsulation

Encapsulation is wrapping up the data and methods together under a single class or category. For this, classes are used.

Abstraction

This includes hiding details using a certain level of security.

Polymorphism

Using same name and body to create multiple instances of an object or method is known as polymorphism.

Types of Polymorphism

Compile-time Polymorphism

Compile-time Polymorphism can be achieved using −

Runtime Polymorphism

Runtime Polymorphism can be achieved using −

Inheritance

Deriving the properties of a class ( Parent class ) to another class ( Child class ) is known as Inheritance.

File Handling in C++

The different operations in file handling are as follows −

  • Open file − To open a file, use the open() method of the ofstream class.
  • Read a file − To read a file, use the getline() method of the ifstream class.
  • Write a file − Use the "<<" operator to write on a file while it is opened.

Example

#include <bits/stdc++.h>
using namespace std;
int main(){ 
   ofstream outputFile("file1.txt"); 

   // Open the file for writing 

   outputFile.open("file1.txt"); 
   if (outputFile.is_open()) { 

      // Write data to the file 

      outputFile << "Hello, World!" << endl; 
      outputFile << 1333113 << endl; 
      outputFile.close(); // Close the file 
   }else { 

      // Failed to open the file 
      cout << "Error"<< endl; 
      return 1; 
   } 

   // Reading from a file 

   ifstream inputFile("file1.txt"); 
   if (inputFile.is_open()) { 
      string line; 
      while (getline(inputFile, line)) { 
         // Print each line 
         cout << line << endl; 
      } 
      // Close the file 
      inputFile.close(); 
   }else { 

      // Failed to open the file 
      cout << "Error"<< endl; 
      return 1; 
   } 

   return 0; 
}

Exception Handling

When working with classes and objects, various errors and exceptions are possible due to some fault either in the program written by the user or due to some machine fault, like memory or execution. These errors may be fatal to the smooth execution of a program, and hence need to be handled using try and catch blocks.

When an error occurs, C++ will normally stop and generate an error message. The technical term for this is: C++ will throw an exception (throw an error).

  • Try Block − The try statement allows you to define a block of code to be tested for errors while it is being executed.
  • Throw − The throw keyword throws an exception when a problem is detected, which lets us create a custom error.
  • Catch Block − The catch statement allows you to define a block of code to be executed, if an error occurs in the try block.

Syntax for Try-Catch Exception handling

try {
   // Block of code to try
   throw exception; // Throw an exception when a problem arise
}
catch () {
   // Block of code to handle errors
}

Example

#include <bits/stdc++.h>
using namespace std;

try {
   int bmi=30;
   if (bmi>28) {
      cout << "You are overweight.";
   } else {
      throw (bmi);
   }
}
catch (int x) {
   cout << "You are underweight.";
   cout << "Weight is: " << x;
}

Preprocessor in C++

The preprocessors are keywords that give directions to the compiler to process the instructions before the actual compilation starts. These begin with a ‘#’, and do not need any ‘;’ at the end as these are not statements.

Examples of preprocessors are #include, #define and many more.

Let us look at the important preprocessors in C++ library −

  • #include
  • #define

#include

It is used to include header files and libraries that are required to execute the methods and functions used in the program. As stated earlier, the actual implementation of the method is not shown, and the end result is displayed.

Example

#include <math.h>
#include <iostream>

using namespace std;

//the iostream is used for input and output stream of data
//the math.h is used for including math functions like pow(x,y)

int main(void){   
   cout<<pow(2,3);
   return 0;
}
Output
8

#define

The #define preprocessor directive creates symbolic constants. The symbolic constant is called a macro and the general form of the directive is the symbol ‘#’ followed by define statement and the definition of the constant that needs to be defined. When this format appears in a file, all subsequent occurrences of macro in that file will be replaced by replacement-text before the program is compiled.

Example

#include <bits/stdc++.h>
using namespace std;

#define A 45
//defining value of A as 45

int main(void){   
   int a= A;
   cout<<a;
   return 0;
}
Output
45

Namespaces in C++

A namespace is used to define two functions of the same name in a program. This way, the compiler knows which method to use when calling calling a function. Using namespace, you can define the context in which names are defined. In essence, a namespace defines a scope.

Defining a namespace is easy. You can just write namespace followed by the code inside the method. This function can be used inside a program by mentioning the namespace where it is from, along with ‘::’ symbol in between.

Example 1

#include <bits/stdc++.h>
using namespace std;

// first name space
namespace first_space {
   void func() {
      cout << "Inside first_space" << endl;
   }
}

// second name space
namespace second_space {
   void func() {
      cout << "Inside second_space" << endl;
   }
}

int main () {
   // Calls function from first name space.
   first_space::func();
   
   // Calls function from second name space.
   second_space::func(); 

   return 0;
}

Output

Inside first_space
Inside second_space

The using keyword can be used in form of a directive to direct the following code to adhere to the mentioned namespace. The ‘std’ keyword is similarly used to mention that all of the code is going to adhere to the standard namespace.

To know more about namespaces, refer to this article – Namespaces in C++

Example 2

#include <bits/stdc++.h>
using namespace std;

// first name space
namespace first_space {
   void func() {
      cout << "Inside first_space" << endl;
   }
}

// second name space
namespace second_space {
   void func() {
      cout << "Inside second_space" << endl;
   }
}

using namespace first_space;
int main () {
   // Calls function from first name space.
   func();

   return 0;
}

Output

Inside first_space

Templates in C++

A template is a blueprint or formula for creating a generic class or a function. The library containers like iterators and algorithms have been developed using template concept.

There are two types of templates available in C++ −

  • Class Template
  • Function Template

Class Template

Class templates can be used to define different data structures like linked lists, stack, queue, priority queue, tree and so on. Class template can be defined in the following way −

Syntax

template <class type> class class-name {
   .
   .
   .
}

Example

#include <bits/stdc++.h>
using namespace std;

template <typename T> class Array {
   T* pointer;
   int size;

   public:
      Array(T a[], int s);
      void show();
};

template <typename T> Array<T>::Array(T a[], int s){
   pointer = new T[s];
   size = s;
   for (int i = 0; i < size; i++)
      pointer[i] = a[i];
}

template <typename T> void Array<T>::show(){
   for (int i = 0; i < size; i++)
      cout << *(pointer + i)<<endl;
   cout << endl;
}

int main(){   
   int size=7;
   int a[size] = { 12, 21, 45, 34, 19, 55, 66 };
   Array<int> a1(a, 7);
   a1.show();
   return 0;
}
Output
12
21
45
34
19
55
66

Function Template

These can be used to create generic functions using template libraries, with inbuilt functionalities. Some examples of function templates are max(), min(), sin(), floor(), etc.

Example

#include <bits/stdc++.h>
using namespace std;

template <typename T> T minof3(T x, T y, T z){
   if(x<y && x<z) return x;
   if(y<x && y<z) return y;
   if(z<x && z<y) return z;
   // else return "Not applicable !!!";
}

int main(){
   // Call minof3 for int
   cout << minof3<int>(32,58,97) << endl;
   // call minof3 for double
   cout << minof3<double>(13.0,12.0, 17.0) << endl;
   // call minof3 for char
   cout << minof3<char>('g', 'e', 't') << endl;
   // call minof3 for string
   cout << minof3<string>("apple", "ball", "cat")<<endl;

   return 0;
}
Output
32
12
e
apple

Dynamic Memory in C++

Memory in C++ is divided into 2 parts −

  • Stack Memory − All variables declared inside the function will take up memory from the stack.
  • Heap Memory − This is unused memory of the program and can be used to allocate the memory dynamically when program runs.

When you write a program, sometimes it might occur that the memory required would not be known beforehand, and hence extra space from the heap memory would be required at runtime. This is dynamic memory allocation, and this can be implemented using the ‘new’ keyword. After utilizing this space, the data can be deallocated using the ‘delete’ keyword.

The malloc() function from C, still exists in C++, but it is recommended to avoid using malloc() function. The main advantage of new over malloc() is that new doesn't just allocate memory, it constructs objects which is prime purpose of C++.

Example

#include <bits/stdc++.h>
using namespace std;

int main () {
   int  *ptr  = NULL; // Pointer initialized with null
   ptr  = new int;   // Request memory for the variable
 
   *ptr = 31;     // Store value at allocated address
   cout << "Value of pointer : " << *ptr << endl;

   delete ptr;         // free up the memory.

   return 0;
}

Output

Value of pointer : 31

Similarly, dynamic memory can be allocated while implementing arrays and classes as well. For any more information regarding Dynamic Memory allocation- refer to this article on Dyamic Memory Allocation.

Signal Handling in C++

Signal handling is the process of controlling interrupt signals delivered during the execution of the program. There are various kinds of interrupts, which can prematurely end the program and generate different responses. For example, in Linux/Unix command line interface (CLI) the ‘CTRL+C’ command generate the end program interrupt. Similarly, there exist many interrupts in C++ programming language as well. These are defined in the <csignal> library.

Sr.No Signal & Description
1

SIGABRT

Abnormal termination of the program, such as a call to abort.

2

SIGFPE

An erroneous arithmetic operation, such as a divide by zero or an operation resulting in overflow.

3

SIGILL

Detection of an illegal instruction.

4

SIGINT

Receipt of an interactive attention signal.

5

SIGSEGV

An invalid access to storage.

6

SIGTERM

A termination request sent to the program.

signal() Function

The signal function is provided by the <csignal> library, and is used to trap unwanted or bad interrupts at once. Here is the usage of signal() function, which takes two inputs, first one is the signal number, and the second is the signal handling function.

Example

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

void handler_func(int signal_num){ 
   cout << endl<<"You have interrupted: (" << signal_num 
      << "). \n"; 

   //using exit to terminate 
   exit(signal_num); 
} 

int main(){ 
   //initialize signal 
   signal(SIGABRT, handler_func); 

   while (true) {
      cout << "You can't stop me !!!" << endl;
      this_thread::sleep_for(chrono::seconds(1));
      //this is used for delay 
   }
   return 0; 

   //press ctrl+c to interrupt the program execution!!!
}

raise() Function

The signal function is provided by the <csignal> library, and is used generate interrupts with their numbers. Here is the usage of raise() function, which takes onw input which is the signal number.

Example

#include <csignal> 
#include <iostream>

using namespace std; 

void signal_handler(int signum){ 
   cout << "You generated this interrupt: (" << signum << ").\n"; 

   // terminate program
   exit(signum); 
} 

int main(){ 
   int i = 0; 
   signal(SIGABRT, signal_handler); 

   while (++i) { 
      cout << "You can't stop me !!!" << endl; 
      if (i == 10) 
         raise(SIGABRT); 
   } 
   return 0; 
}

Multithreading in C++

Multithreading is part of the operating systems concept of multitasking on a processor. Multitasking is generally subcategorized into two parts- Process based and Thread based.

In process based multitasking, two or more processes or programs run concurrently on a processor while executing, and it is completely dependent on the prowess of the processor to handle the tasks.

In thread based multitasking, each program is divided into threads, which can be thought of as smaller subprograms that concurrently run on a processor and generate response together. Hence, multiple threads combine together to become a single program. This is known as Multithreading.

In C++, there was no built-in support of multithreading before the launch of C++ 11. C++ uses POSIX Threads, or Pthreads which are available on many Unix-like POSIX systems. The following operations can be performed on pthreads −

  • Creating threads
  • Terminating threads
  • Passing arguments to threads
  • Joining and detaching threads

Creating threads

Threads can be created using the routine pthread_create, in the <pthread.h> library. These can be created anywhere inside the program.

Syntax

#include <pthread.h>
pthread_create (thread, attr, start_routine, arg);
Sr.No Parameter & Description
1

thread

An opaque, unique identifier for the new thread returned by the subroutine.

2

attr

An opaque attribute object that may be used to set thread attributes. You can specify a thread attributes object, or NULL for the default values.

3

start_routine

The C++ routine that the thread will execute once it is created.

4

arg

A single argument that may be passed to start_routine. It must be passed by reference as a pointer cast of type void. NULL may be used if no argument is to be passed.

Terminating a thread

The pthread_exit() is used to terminate a thread after it has completed its execution and is no longer required in the program. This helps clear the space assigned to the thread in the first place.

Syntax

#include <pthread.h>
pthread_exit (status);

Example

#include <iostream>
#include <cstdlib>
#include <pthread.h>

using namespace std;

#define NUM_THREADS 5

void *PrintHello(void *threadid) {
   long tid;
   tid = (long)threadid;
   cout << "Hello World! Thread ID, " << tid << endl;
   pthread_exit(NULL);
}

int main () {
   pthread_t threads[NUM_THREADS];
   int rc;
   int i;

   for( i = 0; i < NUM_THREADS; i++ ) {
      cout << "main() : creating thread, " << i << endl;
      rc = pthread_create(&threads[i], NULL, PrintHello, (void *)i);

      if (rc) {
         cout << "Error:unable to create thread," << rc << endl;
         exit(-1);
      }
   }
   pthread_exit(NULL);
}
Output
main() : creating thread, 0
main() : creating thread, 1
Hello World! Thread ID, 0
main() : creating thread, 2
Hello World! Thread ID, 1
main() : creating thread, 3
Hello World! Thread ID, 2
main() : creating thread, 4
Hello World! Thread ID, 3
Hello World! Thread ID, 4

Joining and detaching threads

The following routine is used to join and detatch threads in a program −

Syntax

pthread_join (threadid, status) 
pthread_detach (threadid) 

Example

#include <iostream>
#include <cstdlib>
#include <pthread.h>
#include <unistd.h>

using namespace std;

#define NUM_THREADS 5

void *wait(void *t) {
   int i;
   long tid;

   tid = (long)t;

   sleep(1);
   cout << "Sleeping in thread " << endl;
   cout << "Thread with id : " << tid << "  ...exiting " << endl;
   pthread_exit(NULL);
}

int main () {
   int rc;
   int i;
   pthread_t threads[NUM_THREADS];
   pthread_attr_t attr;
   void *status;

   // Initialize and set thread joinable
   pthread_attr_init(&attr);
   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

   for( i = 0; i < NUM_THREADS; i++ ) {
      cout << "main() : creating thread, " << i << endl;
      rc = pthread_create(&threads[i], &attr, wait, (void *)i );
      if (rc) {
         cout << "Error:unable to create thread," << rc << endl;
         exit(-1);
      }
   }

   // free attribute and wait for the other threads
   pthread_attr_destroy(&attr);
   for( i = 0; i < NUM_THREADS; i++ ) {
      rc = pthread_join(threads[i], &status);
      if (rc) {
         cout << "Error:unable to join," << rc << endl;
         exit(-1);
      }
      cout << "Main: completed thread id :" << i ;
      cout << "  exiting with status :" << status << endl;
   }

   cout << "Main: program exiting." << endl;
   pthread_exit(NULL);
}
Output
main() : creating thread, 0
main() : creating thread, 1
main() : creating thread, 2
main() : creating thread, 3
main() : creating thread, 4
Sleeping in thread 
Thread with id : 0  ...exiting 
Sleeping in thread 
Thread with id : 2  ...exiting 
Sleeping in thread 
Thread with id : 1  ...exiting 
Main: completed thread id :0  exiting with status :0
Sleeping in thread Main: completed thread id :1  exiting with status :0
Main: completed thread id :2  exiting with status :0

Thread with id : 4  ...exiting 
Sleeping in thread 
Thread with id : 3  ...exiting 
Main: completed thread id :3  exiting with status :0
Main: completed thread id :4  exiting with status :0
Main: program exiting.

Passing arguments to threads

The following program demonstrates how to pass arguments and statements inside threads using multithreading.

Example

#include <iostream>
#include <cstdlib>
#include <pthread.h>

using namespace std;

#define NUM_THREADS 5

struct thread_data {
   int  thread_id;
   char *message;
};

void *PrintHello(void *threadarg) {
   struct thread_data *my_data;
   my_data = (struct thread_data *) threadarg;

   cout << "Thread ID : " << my_data->thread_id ;
   cout << " Message : " << my_data->message << endl;

   pthread_exit(NULL);
}

int main () {
   pthread_t threads[NUM_THREADS];
   struct thread_data td[NUM_THREADS];
   int rc;
   int i;

   for( i = 0; i < NUM_THREADS; i++ ) {
      cout <<"main() : creating thread, " << i << endl;
      td[i].thread_id = i;
      td[i].message = "This is message";
      rc = pthread_create(&threads[i], NULL, PrintHello, (void *)&td[i]);

      if (rc) {
         cout << "Error:unable to create thread," << rc << endl;
         exit(-1);
      }
   }
   pthread_exit(NULL);
}
Output
main() : creating thread, 0
main() : creating thread, 1
main() : creating thread, 2
Thread ID : 0 Message : This is message
Thread ID : 1 Message : This is message
main() : creating thread, 3
Thread ID : 2 Message : This is message
main() : creating thread, 4
Thread ID : 3 Message : This is message
Thread ID : 4 Message : This is message

Conclusion

There has been a lot of change in the world of C++ programming since its inception, and it is becoming ever more important to be aware of the new syntax that is being introduced. This article provides a summary of the most popular syntaxes in C++ and has been designed to lay out all the basics for those who are early on in their programming journey. For those who are more experienced, this article will provide an overview of what is happening in the world of C++.

Advertisements