0% found this document useful (0 votes)
234 views220 pages

Quant Masters

The document provides information about various MCQ websites for practice, C programming concepts like data types, operators, header files, functions, macros, variables scopes, and more. It includes code snippets to demonstrate pattern programs, taking input, data type sizes, formatting specifiers, integer representations, floating-point operations, and more essential C programming concepts.

Uploaded by

shiv sk
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
234 views220 pages

Quant Masters

The document provides information about various MCQ websites for practice, C programming concepts like data types, operators, header files, functions, macros, variables scopes, and more. It includes code snippets to demonstrate pattern programs, taking input, data type sizes, formatting specifiers, integer representations, floating-point operations, and more essential C programming concepts.

Uploaded by

shiv sk
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 220

MCQ Websites

Codechef

Sanfoundry

Indiabix

Interviewbit

Geeksforgeeks

Examtray

Examveda

cppbuzz

PATTERN PROGRAM - ASSESSMENT QUESTIONS

#include <stdio.h>

int main()

int rows, i, j, space;

rows = 5;

for (i = rows; i >= 1; --i)

for (space = 0; space < rows-i; ++space)

printf(" ");

for (j = i; j <= 2*i-1; ++j)

printf("* ");
for (j = 0; j < i-1; ++j)

printf("* ");

printf("\n");

return 0;

*********

*******

*****

***

Sample Input: 4

Sample Output:
1

2 3

4 5 6

7 8 9 10

#include <stdio.h>

int main()
{

int rows, i, j, number;

number = 1;

printf("Enter the number of rows: ");

scanf("%d", &rows);

for (i = 1; i <= rows; i++)

for (j = 1; j <= i; ++j)

printf("%d ", number++);

printf("\n");

STRUCTURE OF A C PROGRAM

Header files

main()

//statements

HEADER FILES

#include<stdio.h>
int main()

printf("Hello World");

//Hello World

#include"stdio.h"

int main()

printf("Hello World");

//Hello World

<> - inbuilt header files are searched first and then User Defined Header
Files in dir. Of the program file.

“” - User Defined Header Files in dir. Of the program file are searched
first and then inbuilt header files are searched

int main()
{
#include<stdio.h>
printf("Hello World");
}
//HELLO WORLD

int main()
{
printf("Hello World");
#include<stdio.h>
}
//Compiler Error (Compilers Compile from Top to Bottom Only
void show();
int main()
{
#include<stdio.h>
show();
}
void show()
{
printf("Hello World");
}
//Compiler Error (Header file is limited to it’s scope / brackets)

Precedence and order of Evaluation

https://docs.microsoft.com/en-us/cpp/c-language/precedence-and-order-
of-evaluation?view=msvc-160

Symbol 1 Type of operation Associativity

[ ] ( ) . ->
Expression Left to right
++ -- (postfix)

sizeof & * + - ~ !
Unary Right to left
++ -- (prefix)

typecasts Unary Right to left

* / %
Multiplicative Left to right

+ -
Additive Left to right
<< >>
Bitwise shift Left to right

< > <= >=


Relational Left to right

== !=
Equality Left to right

&
Bitwise-AND Left to right

^
Bitwise-exclusive-OR Left to right

|
Bitwise-inclusive-OR Left to right

&&
Logical-AND Left to right

||
Logical-OR Left to right

? :
Conditional-expression Right to left

= *= /= %=
Simple and compound assignment Right to left
+= -= <<= >>= &= 2
^= |=

,
Sequential evaluation Left to right

..
MACROS

#include <stdio.h>
#define MAX 10
int main()
{
printf("%d",MAX);
return 0;
}
//10

#include <stdio.h>
#define square(x) x*x
int main()
{
printf("%d",square(5));
return 0;
}
//25

Macros are substitution Functions.


Macros only replace. They do not calculate.

#include <stdio.h>
#define square(x) x*x
int main()
{
int result = 25/square(5); //becomes 25/5*5 (use associativity and
calculate)
printf("%d",result);
return 0;
}
//25

#include <stdio.h>
#define square(x) (x*x)
int main()
{
int result = 25/square(5);
printf("%d",result);
return 0;
}
//1

#include <stdio.h>
#define square(x) x*x
int main()
{
int result = 25/(square(5));
printf("%d",result);
return 0;
}
//1

#include <stdio.h>
#define double char
int main()
{
double a;
printf("%lu",sizeof(a));
return 0;
}
//1

#include <stdio.h>
int main()
{
double a;
#define double char
printf("%lu",sizeof(a));
return 0;
}
//8
Can you run a C program and print “Hello World” without the main
function?

#include <stdio.h>
#define f(a,b,c,d) d##c##b##a
int f(n,i,a,m)()
{
printf("C PROGRAMMING IS WEIRD!");
return 0;
}

//C PROGRAMMING IS WEIRD!

Compilation: Converting your C code to object code (Can be executed


by your machine)
Execution: The object code is executed.

A C program can be compiled without a main function but not executed.

#include <stdio.h>
int fun()
{
printf("C PROGRAMMING IS WEIRD!");
return 0;
}
//Compiles but doesn’t execute.

Macros are substitution functions.


Macros perform substitution during compilation phase and not execution
phase.
Macro converts f(n,i,a,m) to main during compilation.
While executing, we have main(). Hence, executes with no errors.

#include <stdio.h>
#define f(i,k) k##i
int main()
{
printf("%s",f(o,n));
return 0;
}
//no undeclared

#include <stdio.h>
#define f(i,k) k##i
int main()
{
int no = 50;
printf("%d",f(o,n));
return 0;
}
//50

#include <stdio.h>
#define f(i,k) "k##i"
int main()
{
int no = 50;
printf("%s",f(o,n));
return 0;
}
//k##i

DATATYPE SIZES & FORMAT SPECIFIERS

Datatype Size (Bytes) Format Specifier


char 1 %c
int 2/4 (16 / 32 bit) %d
Short int 2 %hd
Long int 4/8 (16 / 32 bit) %ld
float 4 %f
double 8 %lf

CHAR

#include <stdio.h>
int main()
{
char ch = 'a';
printf("%c",ch);
return 0;
}
//97
ASCII Code: American Std. Code for Info. Interchange.

A-Z: 65 - 90
a-z: 97 - 122
0-9: 48 - 57
Space: 32

#include <stdio.h>
int main()
{
char ch = 65;
printf("%c",ch);
return 0;
}
//A

#include <stdio.h>
int main()
{
char ch = 'Z';
char a = ch + ' '; //90+32
printf("%d",a);
return 0;
}
//122
(Range: -128 to 127)

#include <stdio.h>
int main()
{
char ch = 'Z';
char c = 10;
char a = ch + 4*c; //90+4*10 = 130
printf("%d",a);
return 0;
}
//-126

#include <stdio.h>
int main()
{
char ch = 'Z';
char c = 10;
char a = -(ch) - 4*c; //-90 - 4*10 = -90-40 = -130
printf("%d",a);
return 0;
}
//126

#include <stdio.h>
int main()
{
char ch = 'Z';
char c = 10;
unsigned char a = ch + 4*c; //90+4*10 = 130
printf("%d",a);
return 0;
}
//130

char => -128 to 127


unsigned char => 0 to 255

INT

#include <stdio.h>
int main()
{
int a = 010;
printf("%d",a);
return 0;
}
//8

#include <stdio.h>
int main()
{
int a = 023;
printf("%d",a);
return 0;
}
//19

#include <stdio.h>
int main()
{
int a = 039;
printf("%d",a);
return 0;
}
//Error

#include <stdio.h>
int main()
{
int a = 023;
printf("%i",a);
return 0;
}
//19

#include <stdio.h>
int main()
{
int a = 023;
printf("%o",a);
return 0;
}
//23

#include <stdio.h>
int main()
{
int a = 23;
printf("%o",a);
return 0;
}
//27

https://www.rapidtables.com/convert/number/decimal-to-octal.html

#include <stdio.h>
int main()
{
int a = 0xa;
printf("%d",a);
return 0;
}
//10

#include <stdio.h>
int main()
{
int a = 0xa;
printf("%x",a);
return 0;
}
//a

%o = Octal
%d / %i = Decimal
%x = Hexadecimal

#include <stdio.h>
int main()
{
int i;
for(i=1;i>0;i++)
printf("%d\n",i);
return 0;
}
//Run in Turbo C
1
2
3

32767

#include <stdio.h>
int main()
{
int i;
for(i=1;i!=0;i++)
printf("%d\n",i);
return 0;
}
//Run in Turbo C
1
2
3

32767
-32768
32767

-1

#include <stdio.h>
int main()
{
unsigned int i;
for(i=1;i>0;i++)
printf("%d\n",i);
return 0;
}
//Run in Turbo C
1
2
3

32767
-32768
32767

-1

#include <stdio.h>
int main()
{
unsigned int i;
for(i=1;i>0;i++)
printf("%u\n",i);
return 0;
}
//
1
2
3

65535

FLOAT & DOUBLE

#include <stdio.h>
int main()
{
unsigned int i;
for(i=1;i>0;i++)
printf("%u\n",i);
return 0;
}
//3.000000

#include <stdio.h>
int main()
{
float a = 22/7.0;
printf("%f\n",a);
}
//3.142857

#include <stdio.h>
int main()
{
float a = 22/(float)7; //Explicit type casting
printf("%f\n",a);
}
//3.142857

#include <stdio.h>
int main()
{
float a = 22/7f;
printf("%f\n",a);
}
//Error
#include <stdio.h>
int main()
{
float a = 22/7.0f;
printf("%f\n",a);
}
//3.142857

#include <stdio.h>
int main()
{
float a = 3.4;
if(a == 3.4)
printf("I KNOW C");
else
printf("I DON'T KNOW C");
}
//I DON’T KNOW C

#include <stdio.h>
int main()
{
float a = 3.4;
if(a == 3.400000)
printf("I KNOW C");
else
printf("I DON'T KNOW C");
}
//I DON’T KNOW C

#include <stdio.h>
int main()
{
printf("Size of 3.4: %lu\n",sizeof(3.4));
float a = 3.4;
printf("Size of a: %lu\n",sizeof(a));
}
//
Size of 3.4: 8
Size of a: 4

#include <stdio.h>
int main()
{
float a = 3.4;
if(a == 3.4f)
printf("I KNOW C");
else
printf("I DON'T KNOW C");
}
//I KNOW C

Sign Mantissa Exponent


Float (32) 1 23 8
Double (64) 1 52 11

#include <stdio.h>
int main()
{
float a = 2345.5;
if(a == 2345.5)
printf("I KNOW C");
else
printf("I DON'T KNOW C");
}
//I KNOW C

VARIABLES

#include <stdio.h>
int main()
{
int a = 25;
{
int a = 50;
{
int a = 75;
}printf("%d",a);
}
}
//50

#include <stdio.h>
int main()
{
int a = 10,b = 20;
printf("%d\t%d\n",a,b);
{
int a = 50;
a+=50;
b+=50;
printf("%d\t%d\n",a,b);
}
printf("%d\t%d\n",a,b);
}
//10 20
100 70
10 70

#include <stdio.h>
int a;
int a = 5;
int a;
int main()
{
printf("%d\n",a);
}
//5
When you declare a global variable multiple times, it’s not declared
multiple times (Only once).

#include <stdio.h>
int a;
int a = 5;
int a;
int a = 50;
int main()
{
printf("%d\n",a);
}
//When global variables are initialized more than once, they are
considered to be declared more than once
Error

#include <stdio.h>
int a = 50;
int main()
{
int a = a;
printf("%d\n",a);
}
//Garbage Value

//Please revise on operators

OPERATORS
Arithmetic
Relational
Incr / Decr
Logical
Bitwise
Assignment
Ternary
Comma
ARITHMETIC OPERATORS:

+,-,*,/,%

Add without +:
#include <stdio.h>
int main()
{
int a,b,c;
a = 10,b = 20;
c = a-(-b);
printf("Sum: %d",c);
}

Subtract without -:

#include <stdio.h>
int main()
{
int a = 20,b = 10,c;
c = a+~b+1;
printf("%d",c);
return 0;
}

RELATIONAL OPERATORS:
>,<,>=,<=,!=,==

#include <stdio.h>
int main()
{
int a = 5;
if(a=5)
printf("IN IF");
else
printf("IN ELSE");
}
//IN IF

#include <stdio.h>
int main()
{
int a = 5;
if(a=5-6)
printf("IN IF");
else
printf("IN ELSE");
}
//IN IF

#include <stdio.h>
int main()
{
int a = 5;
if(a=5-5)
printf("IN IF");
else
printf("IN ELSE");
}
//IN ELSE

Can you print Hello World on screen without any semicolon?


#include <stdio.h>
int main()
{
if(printf("Hello World"))
{

}
}
//Hello World

INCREMENT / DECREMENT
#include <stdio.h>
int main()
{
int a = 5,b,c;
b = a++;
c = ++b;
printf("%d %d %d",a,b,c);
}
//6 6 6

#include <stdio.h>
int main()
{
int a = 5;
printf("%d %d %d %d",a++,a++,a++,a++);
}
//8 7 6 5

#include <stdio.h>
int main()
{
int a = 5;
printf("%d %d %d %d",a++,++a,++a,a++);
}
//8 9 9 5

Whenever you perform a pre / post incr / decr of one variable more than
once before the end of the statement (sequence point).

Sequence point is where C language saves the variable value.

Whenever you update a variable >1 times before reaching sequence


point, output is undefined.
(Undefined Behavior)

LOGICAL OPERATORS
&&, ||, !

Logical AND:

Input 1 Input 2 Output


F F F
F T F
T F F
T T T

In C Language:
True: Any Non Zero Value
False: Zero

Result of Logical Operator is always 0 (F) / 1 (T)

#include <stdio.h>
int main()
{
int a = 0,b = -1,c;
c = a && b;
printf("%d",c);
return 0;
}
//0

#include <stdio.h>
int main()
{
int a = 3,b = -1,c;
c = a && b;
printf("%d",c);
return 0;
}
//1
#include <stdio.h>
int main()
{
int a = 0,b = -3,c;
c = ++a && ++b;
printf("%d %d %d",a,b,c);
return 0;
}
//1 -2 1

#include <stdio.h>
int main()
{
int a = -1,b = -9,c;
c = ++a && ++b;
printf("%d %d %d",a,b,c);
return 0;
}
//0 -9 0

#include <stdio.h>
int main()
{
int a = -2,c;
c = ++a && a++;
printf("%d %d",a,c);
return 0;
}
//0 1

https://docs.microsoft.com/en-us/cpp/c-language/c-sequence-points?
view=msvc-160

#include <stdio.h>
int main()
{
int a = -2,c;
c = a++ && ++a;
printf("%d %d",a,c);
return 0;
}
//0 0

Logical OR:

Input 1 Input 2 Output


F F F
F T T
T F T
T T T

#include <stdio.h>
int main()
{
int a = 0,b = -5,c;
c = a || b;
printf("%d %d %d",a,b,c);
return 0;
}
//0 -5 1

#include <stdio.h>
int main()
{
int a = -1,b = -1,c;
c = a++ || b++;
printf("%d %d %d",a,b,c);
return 0;
}
//0 -1 1
#include <stdio.h>
int main()
{
int a = 7,b = 8,c = 9,d;

d = a++ || b++ && c++;


printf("%d %d %d %d",a,b,c,d);
return 0;
}
//8 8 9 1

#include <stdio.h>
int main()
{
if(printf("We are "))
printf("Idiots");
else
printf("Intelligent");
return 0;
}
//We are idiots

#include <stdio.h>
int main()
{
if(!printf("We are "))
printf("Idiots");
else
printf("Intelligent");
return 0;
}
//We are Intelligent

#include <stdio.h>
int main()
{
int a = !!7;
printf("%d\n",a);
return 0;
}
//1

PRINTF

Printf is an inbuilt function which always returns no. of characters


printed.

#include <stdio.h>
int main()
{
int result = printf("Hi, my age currently is: \n");
printf("%d\n",result);
}
//Hi, my age currently is:
26

#include <stdio.h>
int main()
{
printf(" %d TIMES BETTER TODAY",printf("MY CODING SKILLS
ARE"));
}
//MY CODING SKILLS ARE 20 TIMES BETTER TODAY

#include <stdio.h>
int main()
{
int a = 1000,b = 2000;
a = printf("%d %d ",a,b);
printf("%d",a);
}
//1000 2000 10

#include <stdio.h>
int main()
{
int a = 1000,b = 2000;
printf("%d %d %d");
}
//Warning
3 Garbage values

#include <stdio.h>
int main()
{
int a = 1000,b = 2000;
printf("%d",a,b);
}
//1000

SCANF

Scanf returns number of variables read by the program.


#include <stdio.h>
int main()
{
int a,b,c;
c = scanf("%d%d",&a,&b);
printf("%d",c);
return 0;
}
//1000 2000
2

#include <stdio.h>
int main()
{
int a,b,c;
c = scanf("%d%d",&a);
printf("%d",c);
return 0;
}
//1000 2000
2

#include <stdio.h>
int main()
{
int a,b,c;
c = scanf("%d",&a,&b);
printf("%d",c);
return 0;
}
//1000
1

BITWISE OPERATORS

&, |, ^, ~, <<, >>

#include <stdio.h>
int main()
{
int a = 4,b = 7;
printf("%d\n",a&b);
return 0;
}
//4

#include <stdio.h>
int main()
{
int a = 4,b = 7;
printf("%d\n",a|b);
return 0;
}
//7

#include <stdio.h>
int main()
{
int a = 4,b = 7;
printf("%d\n",a^b);
return 0;
}
//3

Negation: Add 1 and change sign

#include <stdio.h>
int main()
{
int a = 5;
printf("%d\n",~a);
return 0;
}
//-6

#include <stdio.h>
int main()
{
int a = -9;
printf("%d\n",~a);
return 0;
}
//8

<<
Left Shift:
a<<n = a*2^n

#include <stdio.h>
int main()
{
printf("%d",512<<2);
return 0;
}
//2048

>>

a>>n = a/2^n

#include <stdio.h>
int main()
{
printf("%d",512>>2);
return 0;
}
//128

TERNARY OPERATOR

a?b:c

(condition)?(true_stmt):(false_stmt);

#include <stdio.h>
int main()
{
int c;
c = (10>20)?10:20;
printf("%d",c);
return 0;
}
//20

#include <stdio.h>
int main()
{
int c;
(10>20)?c=10:c=20;
printf("%d",c);
return 0;
}
//Error

#include <stdio.h>
int main()
{
int c;
(10>20)?(c=10):(c=20);
printf("%d",c);
return 0;
}
//20

#include <stdio.h>
int fun() {
10>20?return 10:return 20;
}
int main()
{
printf("%d",fun());
return 0;
}
//Error

#include <stdio.h>
int fun() {
10>20?(return 10):(return 20);
}
int main()
{
printf("%d",fun());
return 0;
}
//Error

Return should always be at the beginning of the statement


COMMA OPERATOR

Comma (,)
#include <stdio.h>
int main()
{
int var = 1,2,3,4,5,6,7;
printf("%d",var);
return 0;
}
//Error

#include <stdio.h>
int main()
{
int var = (1,2,3,4,5,6,7);
printf("%d",var);
return 0;
}
//Error

#include <stdio.h>
int main()
{
int var = (1,2,3,4,5,6,7);
printf("%d",var);
return 0;
}
//7

#include <stdio.h>
int main()
{
int var = (printf("Hi"),printf("Welcome "));
printf("%d",var);
return 0;
}
//HiWelcome 8

#include <stdio.h>
int main()
{
int a = -4;
if(a++,++a,++a,a++)
printf("IN IF");
else
printf("IN ELSE");
return 0;
}
//IN IF

#include <stdio.h>
int main()
{
int a = -4;
if(++a,++a,a++,++a)
printf("IN IF");
else
printf("IN ELSE");
return 0;
}
//IN ELSE

ASSIGNMENT QUESTION

#include <stdio.h>
int main()
{
printf("%d\n",3&&4||1&5|4^2*3);
return 0;
}

#include <stdio.h>
int main()
{
printf("%d\n",~3&&4||1&5|4^2*~3);
return 0;
}

STORAGE CLASSES

Auto, register, static and extern

Behavior of a var. Is identified by the storage class.

By def. Storage class is auto

AUTO STORAGE CLASS

Every variable in auto storage class:


● Lifetime is only in it’s scope.
● Accessible only in it’s scope
● Not Constant
● Stored in RAM

#include <stdio.h>
int main()
{
auto int a = 5;
printf("%d\n",a);
return 0;
}
//5

#include <stdio.h>
int main()
{
int a = 5;
printf("%d\n",a);
return 0;
}
//5

#include <stdio.h>
int main()
{
int a = 5;
printf("%p\n",&a);
return 0;
}
//Prints byte address of RAM where var. a is stored

REGISTER STORAGE CLASS

Every variable in auto storage class:


● Lifetime is only in its scope.
● Accessible only in it’s scope
● Not Constant
● Stored in Register

#include <stdio.h>
int main()
{
register int a = 5;
printf("%d\n",a);
return 0;
}
//5

#include <stdio.h>
int main()
{
register int a = 5;
printf("%d\n",&a);
return 0;
}
//Error
#include <stdio.h>
int main()
{
register int a;
scanf("%d",&a); //Read 32768
printf("%d",a);
return 0;
}
//Error

STATIC STORAGE CLASS

Every variable in auto storage class:


● Lifetime is throughout the program.
● Accessible only in it’s scope
● Not Constant
● Stored in RAM

#include <stdio.h>
void fun()
{
int var = 25;
printf("%d",++var);
}
int main()
{
fun();
fun();
fun();
return 0;
}
//
26
26
26
#include <stdio.h>
void fun()
{
static int var = 25;
printf("%d ",++var);
}
int main()
{
fun();
fun();
fun();
return 0;
}
//26 27 28

#include <stdio.h>
void fun()
{
static int var = 25;
}
int main()
{
fun();
fun();
fun();
printf("%d ",++var);
return 0;
}
//Error

Static variables are declared only once (Second time the statement is
not executed)
Static variables have a default value of 0.

#include <stdio.h>
void fun()
{
static int var;
printf("%d ",++var);
}
int main()
{
fun();
fun();
fun();
return 0;
}
//
1
2
3

#include <stdio.h>
int main()
{
static int a = 8;
if(a<=10)
{
printf("%d\n",a++);
main();
}
printf("%d\n",a--);
return 0;
}
//
8
9
10
11
10
9
8

#include <stdio.h>
int main()
{
static int a;
++a;
if(a<=6)
{
printf("%d\n",a++);
main();
}
printf("%d\n",a-2);
return 0;
}
//
1
3
5
5
5
5
5

EXTERN STORAGE CLASS

….

PRIME NUMBER PROGRAM

1: Find whether a given number is prime or not

#include <stdio.h>
int prime(int n) //function should return 1 if prime else 0
{
//Write your code here
}
int main()
{
printf("Enter the number");
scanf("%d",&n);
if(prime(n))
printf("Prime");
else
printf("Not Prime");
return 0;
}

Time Complexity

Space Complexity

Test Cases

Your program: Least time, Least memory (space), fulfill all possible
conditions.

#include <stdio.h>
#include <math.h>
int prime(int n) //function should return 1 if prime else 0
{
int i;
imt m = sqrt(n)
for(i=2;i<=m;i++)
{
if(n%i==0) //n is divisible by i
return 0;
}
return 1;
}
int main()
{
int n;
printf("Enter the number");
scanf("%d",&n);
if(prime(n))
printf("Prime");
else
printf("Not Prime");
return 0;
}
//Most efficient program to figure out whether a number is prime or not

LUCKY NUMBER PROGRAM

Ram is fond of prime numbers. He wants to create a lucky number for


every single number. For any given number, Ram wants to find the
distance to it’s closest prime number. This is the lucky number. Help
Ram find a lucky number for any given input number.

Sample Input: 25
Sample Output: 2

Sample Input: 29
Sample Output: 2

Input: An integer (n)


Output: Lucky number for the given integer

Constraints
-50000<=n<=50000

#include <stdio.h>
#include <math.h>
int prime(int n) //function should return 1 if prime else 0
{
int i;
int m = sqrt(n)
for(i=2;i<=m;i++)
{
if(n%i==0) //n is divisible by i
return 0;
}
return 1;
}
int findluckynumber(int n)
{
//Write Your Code Here
}
int main()
{
int n;
printf("Enter the number\n");
scanf("%d",&n);
printf("%d",findluckynumber(n));
return 0;
}

1: Solve manually on paper


2: That logic, write in steps
3: These steps, convert to code

TWIN PRIME PROGRAM

A Twin prime are those numbers which are prime and having a
difference of two ( 2 ) between the two prime numbers. In other words, a
twin prime is a prime that has a prime gap of two. Sometimes the term
twin prime is used for a pair of twin primes; an alternative name for this
is prime twin or prime pair. Usually the pair (2, 3) is not considered to be
a pair of twin primes. Since 2 is the only even prime, this pair is the only
pair of prime numbers that differ by one; thus twin primes are as closely
spaced as possible for any other two primes.

Write a program to find all the twin primes between the given two integer
numbers. Once done, find whether the sum of all twin primes
combinations is prime or not.
Result = 0
Sum of twin prime combinations is always even. Even number except 2
is not prime.
Write a program to find all the twin primes between the given two integer
numbers and print them.

Sample Input: 2,15


Sample Output:
3,5
5,7
11,13

Constraints 2<=n<=10000

#include <stdio.h>
#include <math.h>
int prime(int n) //function should return 1 if prime else 0
{
int i;
int m = sqrt(n);
for(i=2;i<=m;i++)
{
if(n%i==0) //n is divisible by i
return 0;
}
return 1;
}
void printTwinPrimes(int a,int b)
{
if(a<=2 && b>=6)
printf("3,5\n");
for(int i = a+6-a%6;i<b-1;i+=6)
{
if(prime(i-1)&&prime(i+1))
printf("%d,%d\n",i-1,i+1);
}
}
int main()
{
int a,b;
printf("Enter the numbers\n");
scanf("%d%d",&a,&b);
printTwinPrimes(a,b);
return 0;
}

SERIES PROGRAM - ASSIGNMENT

Find nth number of the following series:


0,2,1,3,1,5,2,7,3,11,5,13,....

Combination of Prime numbers (Even no.s of the series) and Fibonacci


numbers (Odd no.s of the series)

Dynamic Programming -> Achieved by tabulation or memoization

#include <stdio.h>
unsigned long int fibo(int n)
{
unsigned long int arr[100];
arr[0] = 0;
arr[1] = 1;
for(int i = 2;i<=n;i++)
{
arr[i] = arr[i-1] + arr[i-2];
}
return arr[n];
}
int main()
{
printf("%lu",fibo(9));
return 0;
}

#include <stdio.h>
unsigned long int fibo(int n)
{
if(n==0 || n==1) return n;
int first,second,third;
first = 0,second = 1;
for(int i = 2;i<=n;i++)
{
third = first + second;
first = second;
second = third;
}
return third;
}
int main()
{
printf("%lu",fibo(9));
return 0;
}

#include <stdio.h>
#include <math.h>
int prime(int n) //function should return 1 if prime else 0
{
int i;
int m = sqrt(n);
for(i=2;i<=m;i++)
{
if(n%i==0) //n is divisible by i
return 0;
}
return 1;
}
int nthprime(int n)
{
if(n==1) return 2;
if(n==2) return 3;
int count = 2;
for(int i = 6;;i+=6)
{
if(prime(i-1))
{
count++;
if(count == n)
return i-1;
}
if(prime(i+1))
{
count++;
if(count == n)
return i+1;
}
}
}
int main()
{
printf("%d",nthprime(5));
return 0;
}

POINTERS

What is a pointer?
A variable which stores address of another variable

#include <stdio.h>
int main()
{
char var = 'A';
char ptr = &var;
printf("Address of var: %p\n",&var);
printf("Value within ptr: %p\n",ptr);
printf("Size of var: %lu\n",sizeof(var));
printf("Size of ptr: %lu",sizeof(ptr));
return 0;
}
//
Address of var: 0x7ffed63baf06
Value within ptr: 0x6
Size of var: 1
Size of ptr: 1

Pointer size doesn’t depend on the size of the datatype.

16 bit system, size of ptr = 2 bytes


32 bit system, size of ptr = 4 bytes
64 bit system, size of ptr = 8 bytes

We add * while declaring to change size of the ptr.

#include <stdio.h>
int main()
{
char var = 'A';
char *ptr = &var;
printf("Address of var: %p\n",&var);
printf("Value within ptr: %p\n",ptr);
printf("Size of var: %lu\n",sizeof(var));
printf("Size of ptr: %lu",sizeof(ptr));
return 0;
}

Address of var: 0x7ffd3994999f


Value within ptr: 0x7ffd3994999f
Size of var: 1
Size of ptr: 8 (64 bit compiler)

* Dereferencing Operator (*) - Accessing value within an address


& Address Operator (&) - Give address of a variable

#include <stdio.h>
int main()
{
int var;
var = 10;
int *ptr;
ptr = &var;
printf("%d",*ptr);
return 0;
}
//10

#include <stdio.h>
int main()
{
int var;
var = 10;
int *ptr;
ptr = &var;
printf("%d",*&*&*&*&*ptr);
return 0;
}
//10

#include <stdio.h>
int main()
{
int var;
var = 10;
int *ptr;
ptr = &var;
printf("%d",*var);
return 0;
}
//var isn’t a ptr

#include <stdio.h>
int main()
{
int var;
var = 10;
int *ptr;
ptr = &var;
printf("%d",**&*&*&*&*ptr);
return 0;
}
//You are performing deref. To a non ptr. Variable.
#include <stdio.h>
int main()
{
int var = 10;
int *ptr1 = &var; //single pointer
int **ptr2 = &ptr1;//double pointer
printf("%d",**ptr2);
return 0;
}
//10

#include <stdio.h>
int main()
{
int var = 10;
int *ptr1 = &var; //single pointer
int **ptr2 = &ptr1;//double pointer
printf("%d",**&**&ptr2);
return 0;
}
//10

#include <stdio.h>
int main()
{
int var = 10;
int *ptr1 = &var; //single pointer
int **ptr2 = &ptr1;//double pointer
printf("%d",**&&**ptr2);
return 0;
}
//Error
Cannot get address of an address

#include <stdio.h>
int main()
{
int var = 500;
char *ptr1 = &var; //single pointer
printf("%d",*ptr1);
return 0;
}
//-12

ARRAYS

Collection of elements stored in continuous memory (Sequential) are of


same datatype.

#include <stdio.h>
int main()
{
int arr[5] = {10,20.9,30,40,'z'};
for(int i = 0;i<=4;i++)
printf("%d\t",arr[i]);
return 0;
}
//10 20 30 40 122

Every Array is a pointer

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
printf("%p\n",arr);
printf("%p\n",&arr[0]);
return 0;
}
//Same addresses

Arr name stores the address of the first element of the array

POINTER ARITHMETIC

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
printf("%p\n",*arr);
return 0;
}
//10

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
printf("%d\n",*arr+2);
return 0;
}
//12

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
printf("%d\n",*(arr+2));
return 0;
}
//30

Pointer Arithmetic => Whenever you add a value to or subtract a value


from a pointer, the value is multiplied by the size of datatype of the
pointer.
#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
printf("%d\n",*(arr+2));
return 0;
}
//30

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
printf("%d\n",*(arr+4));
return 0;
}
//50

ARRAYS CONTINUED

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
printf("%d\n",arr[5]);
return 0;
}
//Garbage Value

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
printf("%d\n",arr[-1]);
return 0;
}
//Garbage Values
Reason why we call arrays to be dangerous.

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
arr = arr + 1;
printf("%d\n",arr[-1]);
return 0;
}
//Error (Array names cannot be changed)

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
printf("%d\n",3[arr]);
return 0;
}
//40

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
int *ptr = arr;
//ptr = ptr + 1;
printf("%p\n",ptr);
printf("%p\n",arr);
return 0;
}
//Same Addresses

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
int *ptr = &arr;
//ptr = ptr + 1;
printf("%p\n",ptr);
printf("%p\n",arr);
return 0;
}
//Same Addresses with an additional warning

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
int *ptr = arr;
int c = ++*ptr;
printf("%d %d\n",c,*ptr);
return 0;
}
//11 11

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
int *ptr = arr;
int c = *++ptr;
printf("%d %d\n",c,*ptr);
return 0;
}
//20 20

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
int *ptr = arr;
int c = *ptr++;
printf("%d %d\n",c,*ptr);
return 0;
}
//10 20

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
int *ptr = arr;
int c = (*ptr)++;
printf("%d %d\n",c,*ptr);
return 0;
}
//10 11

Cdecl - Default calling convention for functions which passes arguments


right to left.

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
int *ptr = arr;
printf("%d %d %d %d\n",++*ptr,*ptr++,(*ptr)++,*++ptr);
return 0;
}
//31 21 20 20

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
int *ptr = arr;
printf("%d %d %d %d\n",*++ptr,(*ptr)++,*ptr++,++*ptr);
return 0;
}
//30 20 11 11

2 DIMENSIONAL ARRAYS

#include <stdio.h>
int main()
{
int arr[2][5] = {10,20,30,40,50,60,70,80,90,100};
return 0;
}

#include <stdio.h>
int main()
{
int arr[2][5] = {{10,20,30,40,50},{60,70,80,90,100}};
return 0;
}
//Valid

Arr[m][n] => There are m arrays, each storing n elements within it.

#include <stdio.h>
int main()
{
int arr[2][5] = {{10,20,30,40,50},{60,70,80,90,100}};
printf("%d",**arr);
return 0;
}
//10

A 1-D array is a single pointer


A 2-D array is a double pointer
A 3-D array is a triple pointer

#include <stdio.h>
int main()
{
int arr[2][5] = {{10,20,30,40,50},{60,70,80,90,100}};
printf("%d",**arr+1);
return 0;
}
//11

#include <stdio.h>
int main()
{
int arr[2][5] = {{10,20,30,40,50},{60,70,80,90,100}};
printf("%d",**(arr+1));
return 0;
}
//60

*(arr+i) = arr[i] (For 1D Arrays)


*(*(arr+i)+j) = arr[i][j] (For 2D Arrays)

#include <stdio.h>
int main()
{
int arr[2][5] = {{10,20,30,40,50},{60,70,80,90,100}};
printf("%d",arr[0][9]);
return 0;
}
//100

#include <stdio.h>
int main()
{
int arr[2][5] = {{10,20,30,40,50},{60,70,80,90,100}};
printf("%d",arr[1][-5]);
return 0;
}
//10

ASSIGNMENT
#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
int *ptr = &arr[5];
printf("%d %d %d %d\n",--*ptr,(*ptr)--,*ptr--,*--ptr);
return 0;
}
//38 40 50 50

#include <stdio.h>
void sum_array_elements(int **arr,int rows, int cols)
{
//Write your code to add all elements of the 2D array and print the
result.
}
int main()
{
int arr[2][5] = {{10,20,30,40,50},{60,70,80,90,100}};
sum_array_elements(arr,2,5);
return 0;
}

#include <stdio.h>
int main()
{
int arr[] = {10,20,30,40,50,60,70,80,90,100};
printf("%d",arr[0]);
return 0;
}
//10

#include <stdio.h>
int main()
{
int arr[];
arr = {10,20,30,40,50,60,70,80,90,100};
printf("%d",arr[0]);
return 0;
}
//Doesn’t work

#include <stdio.h>
int main()
{
int arr[][] = {10,20,30,40,50,60,70,80,90,100};
printf("%d",arr[0]);
return 0;
}
//Error

For any n-d arrays, last n-1 dimensions must be specified.

#include <stdio.h>
int main()
{
int arr[][5] = {10,20,30,40,50,60,70,80,90,100};
printf("%d",arr[0][0]);
return 0;
}
//10

#include <stdio.h>
void sum_array_elements(int rows, int cols,int arr[rows][cols])
{
int sum = 0;
for(int i = 0;i<rows;i++)
for(int j = 0;j<cols;j++)
sum+=arr[i][j];
printf("%d",sum);
}
int main()
{
int arr[2][5] = {{10,20,30,40,50},{60,70,80,90,100}};
sum_array_elements(2,5,arr);
return 0;
}
//550

POINTERS RETURNED FROM FUNCTIONS

#include <stdio.h>
int fun()
{
int var = 5;
return var;
}
int main()
{
int result = fun();
printf("%d",result);
return 0;
}
//5

#include <stdio.h>
int* fun()
{
int var = 5;
return &var;
}
int main()
{
int *result = fun();
printf("%d",*result);
return 0;
}
//5 (Turbo C)

#include <stdio.h>
int* fun()
{
int var = 5;
return &var;
}
int main()
{
int *result = fun();
printf("\n");
printf("%d",*result);
return 0;
}
//GV (Turbo C)

#include <stdio.h>
int* fun()
{
int var = 5;
return &var;
}
int main()
{
int *result = fun();
printf("%d",*result);
return 0;
}
//Not Run (Modern Compilers)
Error: Address of a local variable is returned.

#include <stdio.h>
int* fun()
{
static int var = 5;
return &var;
}
int main()
{
int *result = fun();
printf("%d",*result);
return 0;
}
//5

FUNCTION POINTERS

#include <stdio.h>
void sum(int a,int b)
{
printf("%d",a+b);
}
int main()
{
void (*ptr)(int a,int b) = &sum;
(*ptr)(10,20);
return 0;
}
//30

STRINGS

An array of characters.

#include <stdio.h>
int main()
{
char arr[5] = "Hello";
printf("%p\n",arr); //prints starting address
printf("%s\n",arr); //prints whole array from starting address
printf("%c",*arr);//prints a char.
return 0;
}
//Random Addr.
Hello
H
#include <stdio.h>
int main()
{
char arr[5] = "hello";
printf("%s\n",&arr[2]);
return 0;
}
//llo

#include <stdio.h>
int main()
{
char arr[50] = "hello\0abcdefg";
printf("%s\n",&arr[2]);
return 0;
}
//llo

#include <stdio.h>
int palindrome(char *str) //return 1 if palindrome else 0
{
int low,high;
low = 0;
high = 0;
while(str[high]!='\0')
high++;
high--;
while(low<high)
if(str[low++]!=str[high--])
return 0;
return 1;
}
int main()
{
char arr[50] = "NEVERODDOREVEN";
if(palindrome(arr))
printf("Palindrome");
else
printf("Not a Palindrome");
return 0;
}
//Palindrome

COMMAND LINE ARGUMENTS

One way to read inputs is using STDIN (scanf, getch, gets)


Other way is using command line arguments.

Write a C Program to add 2 input numbers. (Use Command Line


Arguments)

#include<stdio.h>
int main(int argc,char **argv)
{
//argc stores no. of arguments and argv stores values of arguments
printf("%d",argc);
}
//prog.out 1 2 3
4

Main is a user defined function because the user / programmer defines


the logic of the function.

#include<stdio.h>

int main(int count_of_arguments, char **vector_of_arguments)


{
printf("%d",count_of_arguments);
}
//./a.out 1 2 3 4
Output: 5

#include<stdio.h>
int main(int argc, char **argv)
{
printf("%d",argv[1]+argv[2])
}
//./a.out 10 20

Output: Error

#include<stdio.h>
#include<stdlib.h>
int main(int argc, char **argv)
{
printf("%d",atoi(argv[1]));
}
//./a.out abcd

Output: 0

#include<stdio.h>
#include<stdlib.h>
int main(int argc, char **argv)
{
printf("%d",atoi(argv[1]));
}
//./a.out 10
Output: 10

#include<stdio.h>
#include<stdlib.h>
int main(int argc, char **argv)
{
printf("%d",atoi(argv[1])+atoi(argv[2]));
}
//./a.out 10 20
Output: 30
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char **argv)
{
printf("%d",atoi(argv[1])+atoi(argv[2]));
}
//./a.out 10.5 20.5
Output: 0

#include<stdio.h>
#include<stdlib.h>
int main(int argc, char **argv)
{
printf("%d",atof(argv[1])+atof(argv[2]));
}
//./a.out 10.5 20.5
Output: 31.000000

#include <stdio.h>
int main()
{
char *ptr1[] = {"munch","google","bing","oreo"};
char *ptr2[] = {ptr1[3],ptr1[2],ptr1[1],ptr1[0]};
char **ptr3 = ptr2;
ptr3++;
printf("%s",&ptr3[2][2]);
return 0;
}
//nch

CONSTANT POINTERS

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
const int *ptr = arr;
ptr = ptr+1;
printf("%d",*ptr);
return 0;
}
//20

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
int const *ptr = arr;
ptr = ptr+1;
printf("%d",*ptr);
return 0;
}
//20

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
int const *ptr = arr;
*ptr = *ptr+1;
printf("%d",*ptr);
return 0;
}
//Error

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
int *const ptr = arr;
*ptr = *ptr+1;
printf("%d",*ptr);
return 0;
}
//11

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
int *const ptr = arr;
ptr = ptr+1;
printf("%d",*ptr);
return 0;
}
//Error

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
int const *const ptr = arr;
ptr = ptr+1;
printf("%d",*ptr);
return 0;
}
//Error in Line 6

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
int const *const ptr = arr;
*ptr = *ptr+1;
printf("%d",*ptr);
return 0;
}
//Error (Line 6)

#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
const const int const const *const const ptr = arr;
*ptr = *ptr+1;
printf("%d",*ptr);
return 0;
}
//Turbo C - Error (const must be written only once for each var)
STRING FUNCTIONS

String.h header file has different functions for different compilers.

Strlen
#include <stdio.h>
int main()
{
int arr[5] = {10,20,30,40,50};
int const *const ptr = arr;
*ptr = *ptr+1;
printf("%d",*ptr);
return 0;
}
//5

Strlwr
#include <stdio.h>
#include <string.h>
int main()
{
char str[25] = "HELLO";
printf("%s",strlwr(str));
return 0;
}
//hello (Only for Turbo C)

Strupr
#include <stdio.h>
#include <string.h>
int main()
{
char str[25] = "HELLO";
printf("%s",strlwr(str));
return 0;
}
//HELLO (Only in Turbo C)
Strcpy
#include <stdio.h>
#include <string.h>
int main()
{
char str[25];
str = "hello";
printf("%s",str);
return 0;
}
//Assignment to array not possible after declaration stmt.

#include <stdio.h>
#include <string.h>
int main()
{
char str[25];
strcpy(str,"hello");
printf("%s",str);
return 0;
}
//hello

Strcat
#include <stdio.h>
#include <string.h>
int main()
{
char str1[25] = "hello ",str2[25] = "world";
printf("%s",strcat(str1,str2));
return 0;
}
//hello world

Strncat
#include <stdio.h>
#include <string.h>
int main()
{
char str1[25] = "hello ",str2[25] = "world";
printf("%s",strncat(str1,str2,3));
return 0;
}
//hello wor

Strcmp

#include <stdio.h>
#include <string.h>
int main()
{
char str1[25] = "HELLO",str2[20] = "HELLO";
if(strcmp(str1,str2))
printf("Equal");
else
printf("Not Equal");
return 0;
}
//Not Equal

#include <stdio.h>
#include <string.h>
int main()
{
char str1[25] = "HELLO",str2[20] = "hello";
printf("%d",strcmp(str1,str2));
return 0;
}
//-32

#include <stdio.h>
#include <string.h>
int main()
{
char str1[25] = "HELLO",str2[20] = "HELLO";
printf("%d",strcmp(str1,str2));
return 0;
}
//0

Strcmpi
#include <stdio.h>
#include <string.h>
int main()
{
char str1[25] = "HELLO",str2[20] = "hello";
printf("%d",strcmpi(str1,str2));
return 0;
}
//0 (Works only in Turbo C)

Strncmp
#include <stdio.h>
#include <string.h>
int main()
{
char str1[25] = "HELLO",str2[20] = "HELLo World";
printf("%d",strncmp(str1,str2,4));
return 0;
}
//0

Strchr
Searches for a character within a string (First occurrence of the
character is searched). Returns the address where the char. Was found
in the string. If the char. Isn’t found the result is NULL

#include <stdio.h>
#include <string.h>
int main()
{
char str[25] = "Hello World";
printf("%p\n",str);
printf("%p",strchr(str,'o'));
return 0;
}
0x7fff1ed340f0
0x7fff1ed340f4

#include <stdio.h>
#include <string.h>
int main()
{
char str[25] = "Hello World";
printf("%p\n",strchr(str,'d')-str);
return 0;
}
//0xa

Strstr - searches a string2 within another string1 (First occurrence of the


string2 is searched). Returns the address where the string2. Was found
in the string1. If the string2. Isn’t found the result is NULL

#include <stdio.h>
#include <string.h>
int main()
{
char str1[50] = "The rain in spain is such a pain";
char str2[25] = "pain";
printf("%p\n",strstr(str1,str2)-str1);
return 0;
}
//0xd
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/crt-
alphabetical-function-reference?view=msvc-170

DYNAMIC MEMORY ALLOCATION

When is memory size decided for variables?


During compilation or during execution?
4 functions: malloc, calloc, realloc and free

Malloc: Allocate memory dynamically.

Allocates contiguous bytes of memory.


malloc(sizeofdatatype*no_of_elements)

Malloc always returns the starting address of the contiguous bytes of


memory allocated.

What happens if the required amount of bytes are not available? Returns
NULL

#include <stdio.h>
#include <stdlib.h>
int main()
{
int *arr,n;
printf("Enter the number of elements required\n");
scanf("%d",&n);
arr = malloc(n*sizeof(int));
for(int i = 0;i<n;i++)
scanf("%d",&arr[i]);
for(int i = 0;i<n;i++)
printf("%d ",arr[i]);
return 0;
}
//5
12345
12345
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *arr,n;
printf("Enter the number of elements required\n");
scanf("%d",&n);
arr = malloc(n*sizeof(int));
if(arr==NULL)
{
printf("Memory cannot be allocated\n");
return 0;
}
for(int i = 0;i<n;i++)
scanf("%d",&arr[i]);
for(int i = 0;i<n;i++)
printf("%d",arr[i]);
return 0;
}
//Enter the number of elements required
9999999999999999999999
Memory cannot be allocated

Malloc only allocates memory. It doesn’t care what’s the value within that
memory. Malloc returns garbage values.

To get 0’s, we can use calloc.

Calloc returns a starting address as well. Only diff. Is it returns all blocks
as 0.

calloc(no.of.elements,size.of.each.element);

#include <stdio.h>
#include <stdlib.h>
int main()
{
int *arr,n;
printf("Enter the number of elements required\n");
scanf("%d",&n);
arr = calloc(n,sizeof(int));
if(arr==NULL)
{
printf("Memory cannot be allocated\n");
return 0;
}
for(int i = 0;i<n;i++)
printf("%d",arr[i]);
return 0;
}
//1000

It prints 1000 0’s. (No Garbage Values)

Realloc
Used to reallocate the memory in terms of size.
Realloc can only change the size of dynamically allocated arrays.

New_starting_address =
realloc(cur_starting_address,new_size_in_bytes)

What if I increase the size of the array?


1. If there is enough space ahead of the array, st. address remains
same.
2. If there isn’t enough space ahead of the array, starting address is
updated to a new address where there’s enough contiguous space
available. All prev. Array values are copied to new array.
3. When incr. Size of array, if enough contiguous space is not
available at all, it returns NULL indicating new array cannot be
created.
What if I decrease the size of the array?
1. St. address remains the same.
#include<stdlib.h>
#include <stdio.h>
int main()
{
int *arr,*new_arr,n;
printf("Enter the number of elements required\n");
scanf("%d",&n);
arr = calloc(n,sizeof(int));
if(arr==NULL)
{
printf("Memory cannot be allocated\n");
return 0;
}
printf("Enter the number of updated elements\n");
scanf("%d",&n);
new_arr = realloc(arr,n*sizeof(int));
printf("Old Address: %p\n",arr);
printf("New Address: %p\n",new_arr);
return 0;
}
//Enter the number of updated elements
30
Old Address: 0x562409d1fac0
New Address: 0x562409d1fac0

Enter the number of elements required


20
Enter the number of updated elements
999999
Old Address: 0x563a03eb8ac0
New Address: 0x7f8197627010
25

Enter the number of elements required


200
Enter the number of updated elements
20
Old Address: 0x55bd62e12ac0
New Address: 0x55bd62e12ac0
25

Free:
Remove dynamically allocated memory from your program’s memory.
DMA is not removed until the end of the program.

free(starting_address)

Memory allocated is removed but not pointer.


Memory allocated which is now removed, could or could not be replaced.
The values in allocated memory may or may not remain.

#include<stdlib.h>
#include <stdio.h>
int main()
{
int *arr,n;
printf("Enter the number of elements required\n");
scanf("%d",&n);
arr = calloc(n,sizeof(int));
arr[0] = 25;
printf("Before Free: Address: %p\n",arr);
free(arr); //Memory allocated is removed. The pointer isn't removed.
printf("After Free: Address: %p\n",arr);
printf("%d",arr[0]);
return 0;
}
Enter the number of elements required
10
Before Free: Address: 0x5636c85a5ac0
After Free: Address: 0x5636c85a5ac0
0 (May or may not be 10. Could be GV also)

Every function of dynamic memory allocation (malloc, calloc and realloc)


always return void pointers.
Int *arr = (int*)malloc(n*sizeof(int))

TYPES OF POINTERS

Dangling Pointer
When a pointer is allocated memory during DMA (Either by calloc,
malloc or be realloc) and that memory is deallocated, the pointer points
to a memory which is NO LONGER allocated.

#include<stdlib.h>
#include <stdio.h>
int main()
{
int *arr,n;
printf("Enter the number of elements required\n");
scanf("%d",&n);
arr = calloc(n,sizeof(int));
arr[0] = 25;
printf("Before Free: Address: %p\n",arr);
free(arr); //Memory allocated is removed. The pointer isn't removed.
printf("After Free: Address: %p\n",arr);
//arr is a dangling pointer here.
return 0;
}

Null Pointer
#include<stdlib.h>
#include <stdio.h>
int main()
{
int *arr = NULL;
printf("Address: %p\n",arr);
return 0;
}
//NULL (0)
Wild Pointer
int *arr;
When a pointer is just allocated memory i.e. declared but not initialized
(Could have GV)

Void Pointer
#include<stdlib.h>
#include <stdio.h>
int main()
{
int a = 25;
void *ptr = &a;
printf("%d\n",*ptr);
return 0;
}
//Error: Cannot dereference a void pointer.

STRUCTURES & UNIONS

Arrays can only store elements of a single datatype.


Structures and unions allow us to create custom datatypes which can
store elements of different datatypes together under a single block.

#include <stdio.h>
struct student { //just like int, struct student is a new datatype
char name[25];
int semester;
float sgpa;
};
//struct student is the datatype
//s1 is a variable of this datatype
//name, semester and sgpa are called members of s1
int main()
{
struct student s1 = {"John",3,7.45};
printf("Name: %s\n",s1.name);
printf("Semester: %d\n",s1.semester);
printf("SGPA: %.2f",s1.sgpa);
return 0;
}
//Name: John
Semester: 3
SGPA: 7.45

#include <stdio.h>
struct student { //just like int, struct student is a new datatype
char name[25];
int semester;
float sgpa;
};
//struct student is the datatype
//s1 is a variable of this datatype
//name, semester and sgpa are called members of s1
int main()
{
struct student s1 = {.semester = 3,.sgpa = 7.45,.name = "John"};
printf("Name: %s\n",s1.name);
printf("Semester: %d\n",s1.semester);
printf("SGPA: %.2f",s1.sgpa);
return 0;
}
//Name: John
Semester: 3
SGPA: 7.45

#include <stdio.h>
struct student { //just like int, struct student is a new datatype
char name[25];
int semester;
float sgpa;
};
void fun()
{
printf("Name: %s\n",s1.name);
printf("Semester: %d\n",s1.semester);
printf("SGPA: %.2f",s1.sgpa);
}
int main()
{
struct student s1 = {.semester = 3,.sgpa = 7.45,.name = "John"};
fun();
return 0;
}
//Error: s1 is not declared.

#include <stdio.h>
#include<string.h>
struct student { //just like int, struct student is a new datatype
char name[25];
int semester;
float sgpa;
};
struct student s1;
void fun()
{
printf("Name: %s\n",s1.name);
printf("Semester: %d\n",s1.semester);
printf("SGPA: %.2f",s1.sgpa);
}
int main()
{
strcpy(s1.name,"John");
s1.semester = 3;
s1.sgpa = 7.45;
fun();
return 0;
}
//Name: John
Semester: 3
SGPA: 7.45
#include <stdio.h>
#include<string.h>
struct student { //just like int, struct student is a new datatype
char name[25];
int semester;
float sgpa;
}s1;
void fun()
{
printf("Name: %s\n",s1.name);
printf("Semester: %d\n",s1.semester);
printf("SGPA: %.2f",s1.sgpa);
}
int main()
{
strcpy(s1.name,"John");
s1.semester = 3;
s1.sgpa = 7.45;
fun();
return 0;
}
//Name: John
Semester: 3
SGPA: 7.45

#include <stdio.h>
#include<string.h>
struct values { //just like int, struct student is a new datatype
int a;
char b;
}s1;
int main()
{
s1.a = 90;
s1.b = 'z';
printf("%c %d\n",s1.a,s1.b);
return 0;
}
//Z 122

Structure: Each member of the variable gets it’s own space.


Union: All members share the space (Bytes) equal to the size of the
largest member.

#include <stdio.h>
#include<string.h>
union values { //just like int, struct student is a new datatype
int a;
char b;
}u1;
int main()
{
u1.a = 90;
u1.b = 'z';
printf("%c %d\n",u1.a,u1.b);
return 0;
}
//z 122

STRUCTURE PADDING

Every member in a structure variable begins with an address that is a


multiple of the size of the address.

#include <stdio.h>
struct abc {
char a; //1 byte
short int b; // 2 bytes
};
int main()
{
struct abc s1;
printf("%p",&s1);
return 0;
}
//4

#include <stdio.h>
struct abc {
char a; //1 byte
float b; // 4 bytes
};
int main()
{
struct abc s1;
printf("%lu",sizeof(s1));
return 0;
}
//8

#include <stdio.h>
struct abc {
char a; //1 byte
double b; // 8 bytes
};
int main()
{
struct abc s1;
printf("%lu",sizeof(s1));
return 0;
}
//16

The size of struct variable is always a multiple of it’s largest member


size.

#include <stdio.h>
struct abc {
float a; //4 byte
char b; // 1 bytes
};
int main()
{
struct abc s1;
printf("%lu",sizeof(s1));
return 0;
}
//8

#include <stdio.h>
struct abc {
double a; //8 byte
char b; // 1 bytes
};
int main()
{
struct abc s1;
printf("%lu",sizeof(s1));
return 0;
}
//16

#include <stdio.h>
struct abc {
char c; //1 byte
short int a; //2 byte
char b; // 1 byte
};
int main()
{
struct abc s1;
printf("%lu",sizeof(s1));
return 0;
}
//6

#include <stdio.h>
struct abc {
char c; //1 byte
char b; // 1 byte
short int a; //2 byte
};
int main()
{
struct abc s1;
printf("%lu",sizeof(s1));
return 0;
}
//4

When structure members are aligned in order of increment of the size of


members, it uses memory efficiently.

STRUCTURE BIT FIELDS

#include <stdio.h>
struct birthday {
short int day;
short int month;
short int year;
};
int main()
{
struct birthday b1 = {17,2,2022};
printf("%lu",sizeof(b1));
return 0;
}
//6

#include <stdio.h>
struct birthday {
unsigned short int day:5; //takes only 5 bits
unsigned short int month:4;//takes only 4 bits
unsigned short int year:11;//takes only 11 bits
};//each var. takes 20 bits.
int main()
{
struct birthday b1 = {17,2,2022};
printf("%lu",sizeof(b1));
return 0;
}
//4

#include <stdio.h>
struct birthday {
unsigned short int day:5; //takes only 5 bits
unsigned short int month:4;//takes only 4 bits
unsigned short int year:11;//takes only 11 bits
};//each var. takes 20 bits.
int main()
{
struct birthday b1 = {17,2,2022};
printf("%d/%d/%d",b1.day,b1.month,b1.year);
return 0;
}
//17/2/2022

DATA STRUCTURES

A data structure is a data organization, management, and storage format


that enables efficient access and modification.

Array => Data is stored in a contiguous memory of the same datatype.


Using pointer arithmetic, it’s easy to access any value.

Time and Space Efficiency


For Arrays:
Space Efficiency (Bytes): n

Time Efficiency can’t be measured in seconds. We use no. of


operations.

Best Case TIme Complexity: Omega


Average Case TIme Complexity: Theta
Worst Case TIme Complexity: Big - Oh

Best Time Avg. Time Worst Time


Complexity Complexity Complexity
Access 1 1 1
Insert 1 n n
Delete 1 n n
Search 1 n n

Arrays are highly efficient to access elements.


When we modify or search, it’s not so efficient.

https://www.bigocheatsheet.com/

STACK

What is the data structure?


Where do we use it in real life?
How do we implement it?
Space and Time Complexity?
How do we use it to solve certain interview questions?

Elements are inserted in one order and removed in the same order.
(FILO / LIFO DS)

Where do we use it?


Undo Operations
Redo Operations
Navigation of App / Web Pages
Function Call Stack
Recursion

GLOBAL STACK PROGRAM

#include <stdio.h>
#define SIZE 5
int top = -1;
int stack[SIZE];
int isempty() { //return 1 if empty, else return 0.
if(top == -1) return 1;
else return 0;
}
int isfull() { //return 1 if full else return 0.
if(top == SIZE-1) return 1;
else return 0;
}
void push(int value) { //insert the element
if(isfull()) { //isfull() returns 1 => Enter if condition
printf("Stack Overflow\n");
return;
}
stack[++top] = value;
printf("Value %d pushed onto index %d\n",value,top);
}
void pop() { //remove the topmost element
if(isempty())
{
printf("Stack Underflow\n");
return;
}
printf("Value %d popped from index %d\n",stack[top],top);
top--;
}
void display() {
if(isempty()) printf("Stack is Empty");
else {
for(int i = top;i>=0;i--)
{
printf("%d\t",stack[i]);
}
}
printf("\n\n");
}
int peek() { //return the topmost element
if(isempty()) return 0;
return stack[top];
}
int main()
{
for(int i = 10;i<=60;i+=10)
push(i);
display();
printf("%d\n",peek());
for(int i = 10;i<=60;i+=10)
pop();
display();
return 0;
}

Value 10 pushed onto index 0


Value 20 pushed onto index 1
Value 30 pushed onto index 2
Value 40 pushed onto index 3
Value 50 pushed onto index 4
Stack Overflow
50 40 30 20 10

50
Value 50 popped from index 4
Value 40 popped from index 3
Value 30 popped from index 2
Value 20 popped from index 1
Value 10 popped from index 0
Stack Underflow
Stack is Empty

LOCAL STACK PROGRAM

#include <stdio.h>
#define SIZE 5
int isempty(int top) { //return 1 if empty, else return 0.
if(top == -1) return 1;
else return 0;
}
int isfull(int top) { //return 1 if full else return 0.
if(top == SIZE-1) return 1;
else return 0;
}
void push(int stack[],int *top,int value) { //insert the element
if(isfull(*top)) { //isfull() returns 1 => Enter if condition
printf("Stack Overflow\n");
return;
}
stack[++*top] = value;
printf("Value %d pushed onto index %d\n",value,*top);
}
void pop(int stack[],int *top) { //remove the topmost element
if(isempty(*top))
{
printf("Stack Underflow\n");
return;
}
printf("Value %d popped from index %d\n",stack[*top],*top);
(*top)--;
}
void display(int stack[],int top) {
if(isempty(top)) printf("Stack is Empty");
else {
for(int i = top;i>=0;i--)
{
printf("%d\t",stack[i]);
}
}
printf("\n\n");
}
int peek(int stack[],int top) { //return the topmost element
if(isempty(top)) return 0;
return stack[top];
}
int main()
{
int top = -1;
int stack[SIZE];
for(int i = 10;i<=60;i+=10)
push(stack,&top,i);
display(stack,top);
printf("%d\n",peek(stack,top));
for(int i = 10;i<=60;i+=10)
pop(stack,&top);
display(stack,top);
return 0;
}

How do I reverse a stack?

#include <stdio.h>
#define SIZE 5
int isempty(int top) { //return 1 if empty, else return 0.
if(top == -1) return 1;
else return 0;
}
int isfull(int top) { //return 1 if full else return 0.
if(top == SIZE-1) return 1;
else return 0;
}
void push(int stack[],int *top,int value) { //insert the element
if(isfull(*top)) { //isfull() returns 1 => Enter if condition
printf("Stack Overflow\n");
return;
}
stack[++*top] = value;
printf("Value %d pushed onto index %d\n",value,*top);
}
void pop(int stack[],int *top) { //remove the topmost element
if(isempty(*top))
{
printf("Stack Underflow\n");
return;
}
printf("Value %d popped from index %d\n",stack[*top],*top);
(*top)--;
}
void display(int stack[],int top) {
if(isempty(top)) printf("Stack is Empty");
else {
for(int i = top;i>=0;i--)
{
printf("%d\t",stack[i]);
}
}
printf("\n\n");
}
int peek(int stack[],int top) { //return the topmost element
if(isempty(top)) return 0;
return stack[top];
}
int main()
{
int top1 = -1,top2 = -1;
int stack1[SIZE],stack2[SIZE];
for(int i = 10;i<=50;i+=10)
push(stack1,&top1,i);

display(stack1,top1);

for(int i = top1;i>=0;i--) //for each element of stack1


{
push(stack2,&top2,peek(stack1,top1));
pop(stack1,&top1);
}

display(stack2,top2);
return 0;
}

Value 10 pushed onto index 0


Value 20 pushed onto index 1
Value 30 pushed onto index 2
Value 40 pushed onto index 3
Value 50 pushed onto index 4
50 40 30 20 10

Value 50 pushed onto index 0


Value 50 popped from index 4
Value 40 pushed onto index 1
Value 40 popped from index 3
Value 30 pushed onto index 2
Value 30 popped from index 2
Value 20 pushed onto index 3
Value 20 popped from index 1
Value 10 pushed onto index 4
Value 10 popped from index 0
10 20 30 40 50

ASSIGNMENT QUESTION:

Use global stack program and reverse the stack without an auxiliary
(second / additional) stack
#include <stdio.h>
#define SIZE 5
int top = -1;
int stack[SIZE];
int isempty() { //return 1 if empty, else return 0.
if(top == -1) return 1;
else return 0;
}
int isfull() { //return 1 if full else return 0.
if(top == SIZE-1) return 1;
else return 0;
}
void push(int value) { //insert the element
if(isfull()) { //isfull() returns 1 => Enter if condition
printf("Stack Overflow\n");
return;
}
stack[++top] = value;
//printf("Value %d pushed onto index %d\n",value,top);
}
void pop() { //remove the topmost element
if(isempty())
{
printf("Stack Underflow\n");
return;
}
//printf("Value %d popped from index %d\n",stack[top],top);
top--;
}
void display() {
if(isempty()) printf("Stack is Empty");
else {
for(int i = top;i>=0;i--)
{
printf("%d\t",stack[i]);
}
}
printf("\n\n");
}
int peek() { //return the topmost element
if(isempty()) return 0;
return stack[top];
}
void insertAtBottom(int topmost)
{
if(isempty()) push(topmost);
else {
int t = peek();
pop();
insertAtBottom(topmost);
push(t);
}
}
void reverse()
{
if(!isempty())
{
int topmost = peek();
pop();
reverse();
insertAtBottom(topmost);
}
}
int main()
{
for(int i = 10;i<=50;i+=10)
push(i);
display();
reverse();
display();
return 0;
}
50 40 30 20 10
10 20 30 40 50

[HINT: Use Recursion and Function Call Stack to store values internally]

POSTFIX EVALUATION

Given a postfix expression like 53*62/-, solve the same using a C


program.

Step 1: Solve the program manually in your mind / on a paper.


Step 2: Write your solution in the form of steps [Algorithm].
Step 3: Convert these steps [Algorithm] into Code.
Step 4: Check for Test Cases [Can also be done during Step 2]

Input: A postfix expression in it’s string format


Output: Solution of the postfix expression

Sample Input: 53*62/-


Sample Output: 12

#include <stdio.h>
#define SIZE 5
int top = -1;
int stack[SIZE];
int isempty() { //return 1 if empty, else return 0.
if(top == -1) return 1;
else return 0;
}
int isfull() { //return 1 if full else return 0.
if(top == SIZE-1) return 1;
else return 0;
}
void push(int value) { //insert the element
if(isfull()) { //isfull() returns 1 => Enter if condition
printf("Stack Overflow\n");
return;
}
stack[++top] = value;
printf("Value %d pushed onto index %d\n",value,top);
}
void pop() { //remove the topmost element
if(isempty())
{
printf("Stack Underflow\n");
return;
}
printf("Value %d popped from index %d\n",stack[top],top);
top--;
}
void display() {
if(isempty()) printf("Stack is Empty");
else {
for(int i = top;i>=0;i--)
{
printf("%d\t",stack[i]);
}
}
printf("\n\n");
}
int peek() { //return the topmost element
if(isempty()) return 0;
return stack[top];
}
void evaluate_postfix(char *str)
{
//print the result of postfix expression on screen
//if the postfix expression is not valid, print "INVALID EXPRESSION"
//iterate through every character of the string
//if it's number, push to stack
//if it's operator, pop two top elements, perform op., push result
for(int i=0;str[i]!='\0';i++)
{
if(str[i]>=48 && str[i]<=57) //ascii of 0 is 48, 9 is 57
push(str[i]-48);
else { //if it's an operator
int op1,op2;
if(isempty()) {
printf("Invalid Expression"); return;
}
op2 = peek();
pop();
if(isempty()) {
printf("Invalid Expression"); return;
}
op1 = peek();
pop();
switch(str[i])
{
case '+': push(op1+op2); break;
case '-': push(op1-op2); break;
case '*': push(op1*op2); break;
case '/': push(op1/op2); break;
case '%': push(op1%op2); break;
default: printf("Invalid Expression\n");
return;
}
}
}
int result = peek();
pop();
if(isempty())
printf("Result: %d",result);
else
printf("Invalid Expression");
}
int main()
{
char str[25] = "53*62/-";
evaluate_postfix(str);
return 0;
}
//12

ASSIGNMENT PROGRAM: VALIDATE AND EVALUATE PREFIX


EXPRESSION

Take the prefix expression and read it from right to left.


If the. Char is an operand, push onto stack
If the char. Is operator, pop two elements from stack, perform operation
and push the result.

Tower of Hanoi

Best Time Avg. Time Worst Time


Complexity Complexity Complexity
Access 1 n n
Insert 1 1 1
Delete 1 1 1
Search 1 n n

QUEUES

First in First Out / Last in Last out Data Structure

Applications:

CPU - Multitasking
CPU Scheduling
Train ticket booking (Waiting List)
Flash Sales
Web Requests

Code:
Linear Queue doesn’t offer deletion with O(1). It instead makes it O(n).
To reduce time complexity for deletion, we use circular queues.

#include <stdio.h>
#define SIZE 5
int queue[SIZE];
int front = -1,rear = -1;
int isFull() {
if(front == (rear+1)%SIZE) return 1;
return 0;
}
int isEmpty() {
if(front == -1) return 1;
return 0;
}
void enqueue(int value)
{
if(isFull()) //if queue is full
{
printf("Queue Overflow\n");
return;
}
if(front == -1) //if queue is empty
front = rear = 0;
else //if queue is neither full nor empty
rear = (rear+1)%SIZE;
queue[rear] = value;
printf("Value %d inserted in index %d\n",value,rear);
}
void dequeue() //remove an element
{
if(isEmpty()) //queue is empty
{
printf("Queue Underflow\n");
return;
}
printf("Value %d removed from index %d\n",queue[front],front);
if(front!=rear) //there is more than one element
{
front = (front+1)%SIZE;
}
else //there is only one element
{
front = rear = -1;
}
}
int peek() //return first element
{
return queue[front];
}
void display()
{
if(isEmpty()) printf("Queue is Empty\n");
else {
for(int i = front; i!=rear; i=(i+1)%SIZE)
printf("%d\t",queue[i]);
printf("%d\n",queue[rear]);
}
}
int main()
{
for(int i=10;i<=60;i+=10)
enqueue(i);
for(int i=10;i<=60;i+=10)
dequeue();
return 0;
}

IMPL. QUEUES FROM STACKS

You need two stacks.


If you want to make enqueue less costly O(1), dequeue will be O(n)
If you want to make dequeue less costly O(1), enqueue will be O(n)
#include <stdio.h>
#define SIZE 5
int isempty(int top) { //return 1 if empty, else return 0.
if(top == -1) return 1;
else return 0;
}
int isfull(int top) { //return 1 if full else return 0.
if(top == SIZE-1) return 1;
else return 0;
}
void push(int stack[],int *top,int value) { //insert the element
if(isfull(*top)) { //isfull() returns 1 => Enter if condition
printf("Stack Overflow\n");
return;
}
stack[++*top] = value;
printf("Value %d pushed onto index %d\n",value,*top);
}
void pop(int stack[],int *top) { //remove the topmost element
if(isempty(*top))
{
printf("Stack Underflow\n");
return;
}
printf("Value %d popped from index %d\n",stack[*top],*top);
(*top)--;
}
void display(int stack[],int top) {
if(isempty(top)) printf("Stack is Empty");
else {
for(int i = top;i>=0;i--)
{
printf("%d\t",stack[i]);
}
}
printf("\n\n");
}
int peek(int stack[],int top) { //return the topmost element
if(isempty(top)) return 0;
return stack[top];
}
void enqueue(int stack1[],int *top1,int value)
{
push(stack1,top1,value);
}
void dequeue(int stack1[],int *top1,int stack2[],int *top2)
{
if(isempty(*top1))
{
printf("Queue is Empty\n");
}
else
{
while(!isempty(*top1))
{
int temp = peek(stack1,*top1);
push(stack2,top2,temp);
pop(stack1,top1);
}
pop(stack2,top2);
while(!isempty(*top2))
{
int temp = peek(stack2,*top2);
push(stack1,top1,temp);
pop(stack2,top2);
}
}
}
int main()
{
int stack1[SIZE],stack2[SIZE];
int top1 = -1,top2 = -1;
for(int i = 10;i<=60;i+=10)
enqueue(stack1,&top1,i);
for(int i = 10;i<=50;i+=10)
{
dequeue(stack1,&top1,stack2,&top2);
printf("\n\n");
display(stack1,top1);
printf("\n\n");
}
return 0;
}

IMPL. STACKS FROM QUEUES

Use two queues


Push: Insert into first queue
Pop:
Move all except last element of first queue to second queue.
Remove last element of first queue
Move all elements of second queue to first queue

LINKED LISTS

List of elements stored in non-continuous order.


Are better in terms of inserting / deleting elements compared to arrays.
However, accessing elements is not as efficient as arrays.

#include <stdio.h>
struct node {
int data;
struct node *next;
}
int main()
{
struct node s1,s2,s3;
s1.data = 10;
s2.data = 20;
s3.data = 30;
s1.next = &s2;
s2.next = &s3;
s3.next = NULL;
return 0;
}

#include <stdio.h>
struct node {
int data;
struct node *next;
}*first = NULL; //address of the first element is NULL
int main()
{
struct node *s1,*s2,*s3;
s1 = (struct node*)malloc(sizeof(struct node));
s2 = (struct node*)malloc(sizeof(struct node));
s3 = (struct node*)malloc(sizeof(struct node));
s1->data = 10;
s2->data = 20;
s3->data = 30;
s1->next = s2;
s2->next = s3;
s3->next = NULL;
return 0;
}

Linked List Program:

#include<stdio.h>
#include<stdlib.h>
struct node {
int data;
struct node* next;
}*start = NULL; //start => Pointer storing address of first. var.
int size = 0; //size of the linked list
void insert(int value,int index) //insert given value in given index
{
if(index <= -1 || index >= size+1)
printf("Invalid Index\n");
else
{
struct node *temp = start;
while(index-1 > 0) //loop to reach the prev. element of index req.
{
index--;
temp = temp->next;
}
//temp points to the address after which you need to insert element.
struct node* new_element = (struct node*)malloc(sizeof(struct
node));
new_element->data = value;
if(start == NULL || index == 0)
{
//LL is empty and you are entering first element
//ll has any no. of element and you are entering first element
new_element->next = temp;
start = new_element;
}
else
{
//Entering any element (Not first element)
new_element->next = temp->next;
temp->next = new_element;
}
size++;
}
}
void display() {
if(start == NULL) //Linked List is Empty
printf("Linked List is Empty\n");
else { //Linked List has at least one element
struct node *temp = start;
do {
printf("%d\t",temp->data);
temp = temp->next;
}while(temp!=NULL);
printf("\n");
}
}
void search(int key) {
if(start == NULL) //Linked List is Empty
printf("Linked List is Empty\n");
else { //Linked List has at least one element
struct node *temp = start;
do {
if(temp->data == key)
{
printf("Element Found\n");
return;
}
temp = temp->next;
}while(temp!=NULL);
printf("Element Not Found\n");
}
}
void delete(int key) //delete by value, not by index
{
if(start == NULL) { //linked list is empty
printf("Linked List is Empty");
return;
}
else if(start->data == key) { //first element is to be deleted (Single /
multiple elements)
struct node *temp = start;
start = start->next;
free(temp);
printf("Element Found and Deleted\n");
return;
}
else { //middle or last element is to be deleted
struct node *temp = start->next;
struct node *prev = start;
while(temp!=NULL) {
if(temp->data == key)
{
printf("Element Found and Deleted\n");
prev->next = temp->next;
free(temp);
return;
}
temp = temp->next;
prev = prev->next;
}
}
//linked list doesn't have the element
printf("Element Not Found\n");
}
void reverse() {
if(start == NULL)
printf("Linked List is Empty!\n");
else if(start->next == NULL)
printf("Linked List has one element! No need to reverse.\n");
else { //Linked List has >1 elements
struct node *prev = NULL,*ahead = start->next;
while(ahead!=NULL) //as long as we have not reached the last
element
{
start->next = prev;
prev = start;
start = ahead;
ahead = ahead->next;
}
//we reach the last element
start->next = prev;
printf("Linked List is Reversed\n");
}
}
void create_loop() {
if(start == NULL) //Linked List is Empty
printf("Linked List is Empty\n");
else { //Linked List has at least one element
struct node *temp = start;
while(temp->next!=NULL) {
temp = temp->next;
}
temp->next = start;
}
}
void find_loop() {
//Floyd's Tortoise and Hare Algorithm O(n)
struct node *hare,*tortoise;
tortoise = hare = start;
while(hare->next!=NULL && hare->next->next!=NULL)
{
tortoise = tortoise->next;
hare = hare->next->next;
if(tortoise == hare)
{
printf("Loop Detected\n");
return;
}
}
printf("No Loop Detected\n");
}
void main()
{
int choice,key,index;
while(1)
{
printf("Enter the choice\n");
printf("1. Insert an Element\n");
printf("2. Delete an Element\n");
printf("3. Search an Element\n");
printf("4. Display the List\n");
printf("5. Reverse the list\n");
printf("6. Create Loop within List\n");
printf("7. Find Loop within List\n");
printf("8. Press Anything Else to Exit\n");
scanf("%d",&choice);
printf("----------------------------------\n");
switch(choice) {
case 1: printf("Enter the value to insert\n");
scanf("%d",&key);
printf("Enter the index to insert in\n");
scanf("%d",&index);
insert(key,index);
break;
case 2: printf("Enter the value to delete\n");
scanf("%d",&key);
delete(key);
break;
case 3: printf("Enter the value to search\n");
scanf("%d",&key);
search(key);
break;
case 4: display();
break;
case 5: reverse();
break;
case 6: create_loop();
break;
case 7: find_loop();
break;
default:exit(0);
}
printf("----------------------------------\n");
}
}

Best Time Avg. Time Worst Time


Complexity Complexity Complexity
Access 1 n n
Insert 1 1 1
Delete 1 1 1
Search 1 n n

CIRCULAR LINKED LIST

To convert the above program to a circular linked list, two changes must
be done.
1. When inserting the last element, it should not point to null, instead
should point to start.
2. When deleting the last element, the last second element should
point to start.

#include<stdio.h>
#include<stdlib.h>
struct node {
int data;
struct node* next;
}*start = NULL,*end = NULL; //start => Pointer storing address of first.
var.
int size = 0; //size of the linked list
void insert(int value,int index) //insert given value in given index
{
if(index <= -1 || index >= size+1)
printf("Invalid Index\n");
else
{
struct node *temp = start;
while(index-1 > 0) //loop to reach the prev. element of index req.
{
index--;
temp = temp->next;
}
//temp points to the address after which you need to insert element.
struct node* new_element = (struct node*)malloc(sizeof(struct
node));
new_element->data = value;
if(start == NULL || index == 0)
{
//LL is empty and you are entering first element
//ll has any no. of element and you are entering first element
if(start == NULL)
{
start = new_element;
start->next = start;
end = start;
}
else {
new_element->next = start;
start = new_element;
end->next = start;
}
}
else
{
//Entering any element (Not first element)
if(temp == end) //inserting after last index
{
end = new_element;
}
new_element->next = temp->next;
temp->next = new_element;
}
size++;
}
}
void display() {
if(start == NULL) //Linked List is Empty
printf("Linked List is Empty\n");
else { //Linked List has at least one element
struct node *temp = start;
do {
printf("%d\t",temp->data);
temp = temp->next;
}while(temp!=start);
printf("\n");
}
}
void delete(int key) //delete by value, not by index
{
if(start == NULL) { //linked list is empty
printf("Linked List is Empty");
return;
}
else if(start->data == key) { //first element is to be deleted (Single /
multiple elements)
struct node *temp = start;
start = start->next;
end->next = start;
free(temp);
printf("Element Found and Deleted\n");
return;
}
else { //middle or last element is to be deleted
struct node *temp = start->next;
struct node *prev = start;
while(temp!=NULL) {
if(temp->data == key)
{
printf("Element Found and Deleted\n");
if(temp == end)
{
end = prev;
}
prev->next = temp->next;
free(temp);
return;
}
temp = temp->next;
prev = prev->next;
}
}
//linked list doesn't have the element
printf("Element Not Found\n");
}
void main()
{
int choice,key,index;
while(1)
{
printf("Enter the choice\n");
printf("1. Insert an Element\n");
printf("2. Delete an Element\n");
printf("3. Display the List\n");
printf("4. Press Anything Else to Exit\n");
scanf("%d",&choice);
printf("----------------------------------\n");
switch(choice) {
case 1: printf("Enter the value to insert\n");
scanf("%d",&key);
printf("Enter the index to insert in\n");
scanf("%d",&index);
insert(key,index);
break;
case 2: printf("Enter the value to delete\n");
scanf("%d",&key);
delete(key);
break;
case 3: display();
break;
default:exit(0);
}
printf("----------------------------------\n");
}
}

ASSIGNMENTS:

1: Modify delete method to ensure the linked list has start and end =
NULL when the only remaining element is deleted.

Circular Queue

#include<stdio.h>
#include<stdlib.h>
struct node {
int data;
struct node* next;
}*start = NULL,*end = NULL; //start => Pointer storing address of first.
var.
int size = 0; //size of the linked list
void insert(int value) //insert given value in given index
{
struct node* new_element = (struct node*)malloc(sizeof(struct
node));
new_element->data = value;
if(start == NULL)
{
start = new_element;
start->next = start;
end = start;
}
else {
new_element->next = start;
start = new_element;
end->next = start;
}
size++;
}
void display() {
if(start == NULL) //Linked List is Empty
printf("Linked List is Empty\n");
else { //Linked List has at least one element
struct node *temp = start;
do {
printf("%d\t",temp->data);
temp = temp->next;
}while(temp!=start);
printf("\n");
}
}
void delete(int key) //delete by value, not by index
{
//
}
void main()
{
int choice,key,index;
while(1)
{
printf("Enter the choice\n");
printf("1. Insert an Element\n");
printf("2. Delete an Element\n");
printf("3. Display the List\n");
printf("4. Press Anything Else to Exit\n");
scanf("%d",&choice);
printf("----------------------------------\n");
switch(choice) {
case 1: printf("Enter the value to insert\n");
scanf("%d",&key);
insert(key);
break;
case 2: delete();
break;
case 3: display();
break;
default:exit(0);
}
printf("----------------------------------\n");
}
}

ASSIGNMENTS:

1: Create delete method.

DOUBLE LINKED LIST

Datatype for Double Linked List:


struct node {
int data;
struct node *prev,*next;
};

Double Linked List Applications:


1. Gallery
2. Navigation Apps

NON Linear DS:

Non Linear DS: TREES & Graphs

Tree:

Has one root node, could have many leaf nodes.

Simple application:
Directory Structures (FTP, Hard Drives, Websites)

Binary Tree (Each node has max. Of two children)

N-ary Tree (Each node can have a max. Of n children)


Trees are recursive in nature.
Root Node: First element of the tree
Leaf Nodes: Last elements of the tree

B+ Tree & B- Tree are both used in directory structures.


B+ Tree (NTFS), B- Tree (FAT Format Systems)

Searching Techniques

Linear Search:

#include <stdio.h>
int main()
{
int arr[10] = {5,7,9,1,3,2,4,6,8,10};
int key = 8;
for(int i=0;i<10;i++)
{
if(key == arr[i])
{
printf("Element Found");
return 0;
}
}
printf("Element Not Found");
return 0;
}

Time Complexity O(n)

Binary Search

#include <stdio.h>
int main()
{
int count = 0;
int arr[128];
for(int i=0;i<128;i++)
arr[i] = i+1;
int low = 0,high = 127,mid,key = 57;
while(low<=high)
{
count++;
mid = (low+high)/2;
if(key == arr[mid])
{
printf("Element Found after %d iterations",count);
return 0;
}
else if(key>arr[mid])
low = mid+1;
else
high = mid-1;
}
printf("Element Not Found after %d iterations",count);
return 0;
}
//Time Complexity is O(logn) //base 2

Binary Trees

Trees which have only two children at maximum per node.

Implementation of Binary Tree within C Language?

struct node {
Int data;
struct node *left,*right;
};

Height of a tree: Distance from the node to the leaf node which has the
longest distance.

Depth of a tree: Distance from the root node.


The root node always exists in level 0. Each row is considered as a
level.

In a binary tree, how many elements can there be at maximum in level


5?
2^5 = 32 elements.

For a level i, a binary tree has a maximum no. of elements as 2^i

Within a binary tree of n levels, at maximum how many elements can


there be in the entire tree?
(2^n)-1

Types of Binary Trees

Full Binary Tree - Each node has either 0 or 2 children.


Complete Binary Tree - All levels are full except for the last level.
In the last level, each element is stored in left to right order (0/1/2
children as well)
Perfect Binary Tree - All levels are completely filled
Pathological Binary Tree / Degenerate Binary Tree - There is only one
direction in the tree.
Balanced Binary Tree -
For each node, it’s left sub tree and it’s right sub tree must have a
difference in height either as 0 or 1
Binary Search Tree -
Binary Tree where each node is greater than it’s left child and lesser
than it’s right child.

Balanced Binary Search Tree -A Balanced Binary Tree which is also a


Binary Search Tree

To automatically balance binary search trees, two common algorithms:


AVL Tree
Red-Black Tree
Tree Traversal:

Breadth First Search & Depth First Search

Breadth First Search (Horizontal Traversal) - Level Order Traversal

1-7-9-2-6-9-5-11-5

Depth First Search - Preorder, Inorder and Postorder Traversal

PreOrder Traversal :
Root - Left Tree - Right Tree

Rules:
First element in Pre-Order is always the root.
Flow: Root Node, Left Sub Tree, Right Sub Tree
Second element = Left Child

1-7-2-6-5-11-9-9-5

Inorder Traversal:

Left Sub Tree - Root Node - Right Sub Tree


Rules:
Every element to the left of root node belongs to left sub tree
Every element to the right of the root node is the right sub tree.
Flow: Left Sub Tree, Root Node, Right Sub Tree
Also called as freefall method.

2-7-5-6-11-1-9-5-9

Post Order Traversal:

Left Sub Tree - Right Sub Tree - Root Node


Rules:
Flow: Left Sub Tree - Right Sub Tree - Root Node
Root node is always the last element in our scenario.
Left sub tree is printed first, then right sub tree is printed. Finally, root
node is printed.
Last second element is always the right child of root node.

2-5-11-6-7-5-9-9-1

Input: Expressions (Traversal Expressions)


Output: Tree.

Preorder: 1-2-4-8-9-5-10-11-3-6-13-7-14
Inorder: 8-4-9-2-10-5-11-1-6-13-3-14-7
Postorder: 8-9-4-10-11-5-2-13-6-14-7-3-1
Find the other expression using only two expressions.

Preorder:
Root Node - Left Sub Tree - Right Sub Tree
(Left Child of RN) (Right Child of RN)

Graphs

A graph consists of Vertices are connected together by Edges

Directed / Undirected Graph


(Represented by 2D Matrix)
Directed graphs could or could not be symmetric.
Undirected graphs are always symmetric.

Breadth First Search Algorithm


Select a root vertex. Visit it’s nearest neighbor vertex. (Repeat this until
all elements are visited)
To identify if elements are visited or not, we use Visited Graph

Applications:
P2P Networks (Torrents)
Used to find shortest path in the graph (Dijkstra’s Algorithm)
Used to create Minimum Spanning Tree
Ford Fulkerson’s Max. Flow Calculation Algorithm

Depth First Search Algorithm

Backtracking Algorithms

SORTING ALGORITHMS

Bubble Sort
Insertion Sort
Selection Sort
Merge Sort
Quick Sort
Heap Sort
Bucket Sort
Radix Sort
Counting Sort
Tim Sort

How does it work?


Code:
Time and Space Complexity
Advantages
Disadvantages
In Place Algorithm
Stable Algorithm

BUBBLE SORT

How it works?
Also called as Sinking Sort. (In each iteration, the heaviest element will
go to the bottom of the array).

Code:
#include <stdio.h>
void display_array(int *arr,int n)
{
for(int i = 0;i<n;i++)
printf("%d\t",arr[i]);
printf("\n");
}
void bubble_sort(int *arr,int n)
{
for(int i=0;i<n-1;i++) //perform n-1 passes
{
int swap = 0;
for(int j=0;j<n-i-1;j++) //perform n-i-1 comparisons for each pass
{
if(arr[j]>arr[j+1])
{
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
swap = 1;
}
}
if(swap == 0)
return;
}
}
int main()
{
int n = 10;
int arr[10] = {10,8,6,4,2,1,3,5,7,9};
printf("Unsorted Array\n-------------------------------------\n");
display_array(arr,n);
printf("\n-------------------------------------\n");

//perform bubble sort


bubble_sort(arr,n);

printf("Sorted Array\n-------------------------------------\n");
display_array(arr,n);

return 0;
}

ASSIGNMENT
Given your name as a string to perform bubble sort in order to sort
it in ascending order, print the number of swaps required to sort
your name.

#include <stdio.h>
int swaps;
void display_array(char *arr,int n)
{
for(int i = 0;i<n;i++)
printf("%c\t",arr[i]);
printf("\n");
}
void bubble_sort(char *arr,int n)
{
for(int i=0;i<n-1;i++) //perform n-1 passes
{
int swap = 0;
for(int j=0;j<n-i-1;j++) //perform n-i-1 comparisons for each pass
{
if(arr[j]>arr[j+1])
{
char temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
swap = 1;
swaps++;
}
}
if(swap == 0)
return;
}
}
int main()
{
int n = 8;
char arr[25] = "shashank";
printf("Unsorted Array\n-------------------------------------\n");
display_array(arr,n);
printf("\n-------------------------------------\n");

//perform bubble sort


bubble_sort(arr,n);
printf("Swaps Required: %d\n",swaps);
printf("Sorted Array\n-------------------------------------\n");
display_array(arr,n);

return 0;
}
Time and Space Complexity
Space: O(1) [How many extra spaces apart from array do we need?)

Time Complexity [No. of loops / times an operation is performed]


Best Case: Omega - Ω(n)
Avg and Worst Case: O(n^2)

Advantages
If array is sorted, no. of steps is less (n steps only)
Space complexity is less

Disadvantages
If array is in opp. Order of sorting, no. of steps is more (n^2)
Whenever memory operations are expensive, bubble sort cannot be
used

In Place Algorithm
[Whenever space complexity is less than O(n), the algo. Is in place]
Yes

Stable Algorithm
[The order of elements which have same value remains same even after
sorting]
Yes

INSERTION SORT

How it works?
Array is divided into two parts: Unsorted and Sorted.
First element of the array is sorted. Remaining are not.
For each element in unsorted part of the array, insert it into it’s right
position.

Code:
#include <stdio.h>
void display_array(int *arr,int n)
{
for(int i = 0;i<n;i++)
printf("%d\t",arr[i]);
printf("\n");
}
void insertion_sort(int *arr,int n)
{
for(int i = 1;i<n;i++) //perform n-1 passes
{
int j = i;
while(j>0 && arr[j]<arr[j-1])
{
int temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
j--;
}
}
}
int main()
{
int n = 10;
int arr[10] = {9,8,7,6,5,10,3,2,1,4};
printf("Unsorted Array\n-------------------------------------\n");
display_array(arr,n);
printf("\n-------------------------------------\n");

//perform insertion sort


insertion_sort(arr,n);

printf("Sorted Array\n-------------------------------------\n");
display_array(arr,n);

return 0;
}

Time and Space Complexity


Space Complexity: O(1)
Time Complexity:
Best Case: Omega - Ω(n) [Completely Sorted]
Avg / Worst Case: n^2

Advantages
It isn’t having too many swaps (Memory expensive systems can use this)
Space complexity is less
If the array is sorted, it takes O(n)

Disadvantages
If array isn’t sorted (Worst case scenario): O(n^2)

In Place Algorithm
Yes

Stable Algorithm
Yes

SELECTION SORT

How it works?
In each pass, the smallest element of the array is swapped with the
leftmost element of the unsorted array. Initially, the entire array is
unsorted.

You SELECT the smallest element in each step.

Code:
#include <stdio.h>
void display_array(int *arr,int n)
{
for(int i = 0;i<n;i++)
printf("%d\t",arr[i]);
printf("\n");
}
void selection_sort(int *arr,int n)
{
for(int i=0;i<n-1;i++) //number of passes
{
int min_index = i;
for(int j=i+1;j<=n-1;j++)
{
if(arr[j]<arr[min_index])
min_index = j;
}
if(i!=min_index)
{
int temp = arr[min_index];
arr[min_index] = arr[i];
arr[i] = temp;
}
}
}
int main()
{
int n = 10;
int arr[10] = {9,8,7,6,5,10,3,2,1,4};
printf("Unsorted Array\n-------------------------------------\n");
display_array(arr,n);
printf("\n-------------------------------------\n");

//perform selection sort


selection_sort(arr,n);

printf("Sorted Array\n-------------------------------------\n");
display_array(arr,n);

return 0;
}

Time and Space Complexity


Space Complexity: O(1)
Time Complexity: O(n^2) [Best / Avg / Worst]
Advantages
No. of swaps done are less compared to bubble & insertion sort.
Useful in systems which are memory expensive.

Disadvantages
Time complexity doesn’t change regardless of order of sorting in input.

In Place Algorithm
Yes

Stable Algorithm
No

Quicksort

How it works?
In each recursive iteration, take the leftmost element and put it in it’s
right index position. Consider the sub array to the left and right of the
element. Repeat the same steps.

Repeat as long as i<j


Initially, take the leftmost index as pivot.
Let i be pivot
Let j be the last index.
Keep increasing i, till you reach an element > pivot
Keep decreasing j, till you reach an element <= pivot
Once you reach such a scenario, swap i and j (If i<j)
Swap j with pivot element

Code:
#include <stdio.h>
void display_array(int *arr,int n)
{
for(int i = 0;i<n;i++)
printf("%d\t",arr[i]);
printf("\n");
}
int partition(int *arr,int low,int high)
{
int pivot_index = low;
int i = low;
int j = high;
while(i<j)
{
do {
i++;
}while(arr[i]<=arr[pivot_index]);
do {
j--;
}while(arr[j]>arr[pivot_index]);
if(i<j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
int temp = arr[j];
arr[j] = arr[pivot_index];
arr[pivot_index] = temp;
return j;
}
void quicksort(int *arr,int low,int high)
{
if(low<high) //if low == high / low > high, that part is sorted
{
int mid = partition(arr,low,high);
quicksort(arr,low,mid);
quicksort(arr,mid+1,high);
}
}
int main()
{
int n = 10;
int arr[10] = {9,8,7,6,5,10,3,2,1,4};
printf("Unsorted Array\n-------------------------------------\n");
display_array(arr,n);
printf("\n-------------------------------------\n");

//perform quick sort


quicksort(arr,0,n);

printf("Sorted Array\n-------------------------------------\n");
display_array(arr,n);

return 0;
}

Time and Space Complexity


Avg / Worst Case Time Complexity: O(n^2)
Best Case Time Complexity: Ω(nlogn)
Space Complexity: O(1)

Advantages
Best case: Time complexity is lesser than n^2

Disadvantages
Worst case: Time complexity is n^2 and best case, bubble sort is better
than this.

In Place Algorithm
Yes

Stable Algorithm
No

MERGE SORT

How it works?
We divide the array by half in each step / pass / iteration. This is
recursively performed until each division has only one element. Then,
they are combined and sorted simultaneously.

Code:
#include <stdio.h>
#include<stdlib.h>
void display_array(int *arr,int n)
{
for(int i = 0;i<n;i++)
printf("%d\t",arr[i]);
printf("\n");
}
void merge_and_sort(int *arr,int low,int mid,int high)
{
int *n1,*n2;
int size_n1,size_n2;
int i,j,k;
size_n1 = mid-low+1;
size_n2 = high-mid;
n1 = (int*)malloc(size_n1*sizeof(int));
n2 = (int*)malloc(size_n2*sizeof(int));
for(i = 0;i<size_n1;i++)
n1[i] = arr[low+i]; //n1 stores from low to mid
for(j = 0;j<size_n2;j++)
n2[j] = arr[mid+1+j]; //n2 stores from mid+1 to high
i = 0,j = 0,k = low;
while(i<size_n1 && j<size_n2) //as long as both arrays have elements
{
if(n1[i]<n2[j])
arr[k++] = n1[i++];
else
arr[k++] = n2[j++];
}
while(j<size_n2) //n1 is completely copied i.e. only n2 elements are
left
{
arr[k++] = n2[j++];
}
while(i<size_n1) //n2 is completely copied i.e. only n1 elements are
left
{
arr[k++] = n1[i++];
}
}
void mergesort(int *arr,int low,int high)
{
if(low < high) //if low == high / low > high, that part is sorted
{
int mid = (low+high)/2;
mergesort(arr,low,mid);
mergesort(arr,mid+1,high);
merge_and_sort(arr,low,mid,high);
}
}
int main()
{
int n = 10;
int arr[10] = {9,8,7,6,5,10,3,2,1,4};
printf("Unsorted Array\n-------------------------------------\n");
display_array(arr,n);
printf("\n-------------------------------------\n");

//perform quick sort


mergesort(arr,0,n-1);

printf("Sorted Array\n-------------------------------------\n");
display_array(arr,n);

return 0;
}

Time and Space Complexity


Avg / Worst Case Time Complexity: O(nlogn)
Best Case Time Complexity: Ω(nlogn)
Space Complexity: n

Advantages
Time complexity is less

Disadvantages
Space complexity is more

In Place Algorithm
Not an in-place algorithm (Space complexity: n)

Stable Algorithm
Is stable

Which is the fastest sorting algorithm?

Best Case: Insertion Sort (n)


Avg / Worst Case: Merge Sort (nlogn)

Tim Peters combined Merge & Insertion Sort to form a hybrid algorithm.
Tim Sort is an algorithm. => Fastest Sorting Algo.
Best Case: n, Avg / Worst: nlogn

Python uses TimSort as it’s default sorting algorithm


C / C++ / Java (Merge Sort)

https://iq.opengenus.org/tim-sort/
C++

C++ is an improved version of C - Bjarne Stroustrup's

https://www.stroustrup.com/

C++ is a superset of C.
C++ contains everything in C and even more things.

Can you run a program which executes in C but not in C++? Yes
#include<stdio.h>
int main()
{
int public = 25;
printf("WORKS ONLY IN C LANGUAGE!");
return 0;
}
//WORKS ONLY IN C LANGUAGE!

https://docs.microsoft.com/en-us/cpp/cpp/keywords-cpp?view=msvc-170

C++ Additional Features include:


1. Object Oriented Programming
2. Inbuilt implementation of data structures.
3. Generic Programming
4. Exception Handling

Hello World Program of C++

Iostream is a header file (input, output stream)


Read & Write from console input or error log
To read input, we use a class called istream
To print output, we use a class called ostream
A class is only a blueprint. So, we need it’s objects.
C++ has inbuilt objects of istream called cin (console input)
Of ostream called cout (console output)

Cout uses << (Left Shift Symbol) - Extraction Operator


Cin uses >> (Right Shift Symbol) - Insertion Operator

Cout and cin objects are declared in a special region.


Special region is called std.
We need to use this special region of declaration (namespace) called std

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

#include<iostream>
using namespace std;
int main()
{
int age = 25;
char name[25] = "Tom Cruise";
cout<<"Name is "<<name<<" and age is "<<age;
return 0;
}
//Name is Tom Cruise and age is 25

:: => Belongs To

#include<iostream>
int main()
{
int age;
char name[25];
std::cout<<"Enter the name"<<std::endl;
std::cin>>name;
std::cout<<"Enter the age"<<std::endl;
std::cin>>age;
std::cout<<"Name is "<<name<<" and age is "<<age;
return 0;
}
Enter the name
Tom Cruise
Enter the age
Name is Tom and age is 0
Datatypes within C++

#include<iostream>
using namespace std;
int main()
{
char a;
cout<<sizeof(a);
return 0;
}
//1

#include<iostream>
using namespace std;
int main()
{
wchar_t a;
cout<<sizeof(a);
return 0;
}
//2 or 4 bytes (Depending on Compiler 16 / 32)
#include<iostream>
using namespace std;
int main()
{
bool a = -12;
cout<<a;
return 0;
}
//1

#include<iostream>
using namespace std;
int main()
{
bool a = true;
cout<<a;
return 0;
}
//1

#include<iostream>
using namespace std;
int main()
{
bool a = false;
cout<<a;
return 0;
}
//0

#include<iostream>
using namespace std;
int main()
{
bool a = 0;
cout<<a;
return 0;
}
//0

Operators,if, else, while, do while, for….

#include<iostream>
using namespace std;
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
for(int i : arr)
cout<<i<<endl;
for(int i = 0;i<10;i++)
cout<<arr[i]<<endl;
return 0;
}
//1 to 10 is printed twice

#include<iostream>
using namespace std;
int main()
{
char arr[10] = "JOHNNY";
for(char i : arr) //(iterator : array)
cout<<i<<endl;
return 0;
}
//
J
O
H
N
N
Y

#include<iostream>
using namespace std;
int main()
{
char arr[10] = "Johnny";
for(int i : arr)
cout<<i<<endl;
return 0;
}
//74
111
104
110
110
121
0
0
0
0

Inline Function

#include<iostream>
using namespace std;
inline int square(int n)
{
return n*n;
}
int main()
{
cout<<square(5)<<endl;
return 0;
}
//25

Advantage is that function overhead is reduced.

It’s up to the compiler to perform inline or not.

If the inline function has recursion / loop / static variables / switch, it does
not perform inline replacement.

Sending Values to Functions / Passing Parameters

3 ways to pass parameters to a function (C++).


2 ways (C)

Pass by Value:

#include<iostream>
using namespace std;
void swap(int a,int b)
{
a = a+b;
b = a-b;
a = a-b;
cout<<"Swap Function: value if a is "<<a<<" and b is "<<b<<endl;
}
int main()
{
int a = 10,b = 20;
swap(a,b);
cout<<"Main Function: value if a is "<<a<<" and b is "<<b;
return 0;
}
//Swap Function: value if a is 20 and b is 10
Main Function: value if a is 10 and b is 20
Pass by Address:
#include<iostream>
using namespace std;
void swap(int *a,int *b)
{
*a = *a+*b;
*b = *a-*b;
*a = *a-*b;
cout<<"Swap Function: value if a is "<<*a<<" and b is "<<*b<<endl;
}
int main()
{
int a = 10,b = 20;
swap(&a,&b);
cout<<"Main Function: value if a is "<<a<<" and b is "<<b;
return 0;
}
//Swap Function: value if a is 20 and b is 10
Main Function: value if a is 20 and b is 10

Pass by Reference

#include<iostream>
using namespace std;
int main()
{
int a = 25;
int &b = a; //not valid within c, valid within c++
printf("%d",b);
return 0;
}
//25

Reference Variables = Alias names / pointers which point to only a


single variable (They cannot change addresses of the pointers).
#include<iostream>
using namespace std;
int main()
{
int a = 25;
int &b = a; //not valid within c, valid within c++
a = 50;
printf("%d",b);
return 0;
}
//50

#include<iostream>
using namespace std;
int main()
{
int a = 25;
int &b = a; //not valid within c, valid within c++
b = 50;
printf("%d",a);
return 0;
}
//50

#include<iostream>
using namespace std;
void swap(int &a,int &b)
{
a = a+b;
b = a-b;
a = a-b;
cout<<"Swap Function: value if a is "<<a<<" and b is "<<b<<endl;
}
int main()
{
int a = 10,b = 20;
swap(a,b);
cout<<"Main Function: value if a is "<<a<<" and b is "<<b;
return 0;
}
//Swap Function: value if a is 20 and b is 10
Main Function: value if a is 20 and b is 10

#include<iostream>
using namespace std;
int main()
{
int a = 10;
int &b = 10;
a = 20;
cout<<b;
return 0;
}
//Error

Object Oriented Programming

Class is a blueprint and an object is an implementation of the blueprint.


No memory is assigned for the blueprint / class variable. Any code within
the class written, should be copied to RAM.

Each object gets memory assigned for variables (it’s own copies of
variables). Every object has access to the same method of the class.
Variables belong to objects, methods / functions belong to classes.

Every data member and member function of a class is private by default.


(Inaccessible outside the class).

Access Specifiers:

3 access specifiers / access modifiers within C++.


Access Specifiers tell you how the data members and member functions
can be accessed from a class.

Private: Any data member / member functions are accessible only within
the class (Default).

Protected: Accessible within class, within subclasses

Public: Accessible within class, within subclasses and by objects

#include<iostream>
using namespace std;
class Bank_Account {
int account_number; //data members or attributes
float balance = 0;
public: void deposit(int sum) { //member functions or member
methods
balance+=sum;
}
void withdraw(int sum) {
if(sum<=balance)
balance-=sum;
else
cout<<"Insufficient Funds";
}
void check_balance() {
cout<<"Balance: "<<balance;
}
};
int main()
{
Bank_Account b1,b2; //objects of Bank_Account class are created
b1.balance = 2500;
b1.check_balance();
return 0;
}
//balance is private - error

#include<iostream>
using namespace std;
class Bank_Account {
int account_number; //data members or attributes
float balance = 0;
public: void deposit(int sum) { //member functions or member
methods
balance+=sum;
}
void withdraw(int sum) {
if(sum<=balance)
balance-=sum;
else
cout<<"Insufficient Funds";
}
void check_balance() {
cout<<"Balance: "<<balance;
}
};
int main()
{
Bank_Account b1,b2; //objects of Bank_Account class are created
b1.deposit(2500);
b1.check_balance();
return 0;
}
//Balance: 2500

THIS POINTER

By default, whenever you access a method of a class using an object,


the address of the object is automatically sent to the method. Address of
objects are received as a pointer called “this” by default.

#include<iostream>
using namespace std;
class Bank_Account {
int account_number; //data members or attributes
float balance = 0;
public: void deposit(int sum) { //member functions or member
methods
balance+=sum;
}
void withdraw(int sum) {
if(sum<=balance)
balance-=sum;
else
cout<<"Insufficient Funds\n";
}
void check_balance() {
cout<<"Balance: "<<this->balance<<endl;
}
};
int main()
{
Bank_Account b1,b2; //objects of Bank_Account class are created
b1.deposit(2500);
b1.check_balance();
b2.check_balance();
return 0;
}
//Balance: 2500
Balance: 0
#include<cstdio>
#include<iostream>
using namespace std;
class Bank_Account {
public: void check_this(Bank_Account *ptr)
{
if(this == ptr)
printf("This pointer exists and is proven\n");
else
printf("This pointer is fake and doesn't exist\n");
}
};
int main()
{
Bank_Account b1,b2; //objects of Bank_Account class are created
b1.check_this(&b1);
b2.check_this(&b2);
return 0;
}
//This pointer exists and is proven
This pointer exists and is proven

CONSTRUCTORS:

Methods within classes which are public (They are called by the objects)
and are executed the moment an object is created.

Rules:
1. Constructor must be public
2. Constructor must have same name as class name
3. Constructors cannot have any return type (not even void)

Default constructor / non parameterized constructor (without any


parameters)
#include<iostream>
using namespace std;
class Bank_Account {
int account_number; //data members or attributes
float balance;
public: void deposit(int sum) { //member functions or member
methods
balance+=sum;
}
void withdraw(int sum) {
if(sum<=balance)
balance-=sum;
else
cout<<"Insufficient Funds\n";
}
void check_balance() {
cout<<"Balance: "<<this->balance<<endl;
}
Bank_Account() { //default constructor
balance = 0;
cout<<"Bank Account Successfully Created\n";
}
};
int main()
{
Bank_Account b1,b2; //objects of Bank_Account class are created
return 0;
}
//Bank Account Successfully Created
Bank Account Successfully Created

#include<iostream>
using namespace std;
class Bank_Account {
int account_number; //data members or attributes
float balance;
public: void deposit(int sum) { //member functions or member
methods
balance+=sum;
}
void withdraw(int sum) {
if(sum<=balance)
balance-=sum;
else
cout<<"Insufficient Funds\n";
}
void check_balance() {
cout<<"Balance: "<<this->balance<<endl;
}
Bank_Account() { //default constructor
balance = 0;
cout<<"Bank Account Successfully Created\n";
}
Bank_Account(float bal) { //parameterized constructor
balance = bal;
cout<<"Bank Account with balance "<<balance<<" Successfully
Created\n";
}
Bank_Account(int acc_num) { //parameterized constructor
balance = 0;
account_number = acc_num;
cout<<"Bank Account with account number "<<account_number<<"
Successfully Created\n";
}
Bank_Account(int acc_num,float bal) { //parameterized constructor
account_number = acc_num;
balance = bal;
cout<<"Bank Account with "<<account_number<<" and balance
"<<balance<<" Successfully Created\n";
}
};
int main()
{
Bank_Account b1(2500.0f),b2(12345),b3(12345,2500);
return 0;
}
//
Bank Account with balance 2500 Successfully Created
Bank Account with account number 12345 Successfully Created
Bank Account with 12345 and balance 2500 Successfully Created

Copy Constructor

There is a default copy constructor available, it automatically copies all


data members of one object to another object. Default copy constructor
doesn’t print anything.

#include<iostream>
using namespace std;
class Bank_Account {
int account_number; //data members or attributes
float balance;
public: void deposit(int sum) { //member functions or member
methods
balance+=sum;
}
void withdraw(int sum) {
if(sum<=balance)
balance-=sum;
else
cout<<"Insufficient Funds\n";
}
void check_balance() {
cout<<"Balance: "<<this->balance<<" of account number
"<<account_number<<endl;
}
Bank_Account() { //default constructor
balance = 0;
cout<<"Bank Account Successfully Created\n";
}
Bank_Account(float bal) { //parameterized constructor
balance = bal;
cout<<"Bank Account with balance "<<balance<<" Successfully
Created\n";
}
Bank_Account(int acc_num) { //parameterized constructor
balance = 0;
account_number = acc_num;
cout<<"Bank Account with account number "<<account_number<<"
Successfully Created\n";
}
Bank_Account(int acc_num,float bal) { //parameterized constructor
account_number = acc_num;
balance = bal;
cout<<"Bank Account with "<<account_number<<" and balance
"<<balance<<" Successfully Created\n";
}
};
int main()
{
Bank_Account b1(12345,2500);
Bank_Account b2 = b1;//calls copy constructor
Bank_Account b3(b1); //calls copy constructor
b1.check_balance();
b2.check_balance();
b3.check_balance();
return 0;
}
//Bank Account with 12345 and balance 2500 Successfully Created
Balance: 2500 of account number 12345
Balance: 2500 of account number 12345
Balance: 2500 of account number 12345

Copy constructors - 2 types


1: Default Copy Constructor - Copy every single bit of data from one
object to the other.
2: User Defined Copy Constructor - Coder manually needs to decide
which fields are copied. This overrides the default copy constructor.

#include<iostream>
using namespace std;
class Bank_Account {
int account_number; //data members or attributes
float balance;
public: void deposit(int sum) { //member functions or member
methods
balance+=sum;
}
void withdraw(int sum) {
if(sum<=balance)
balance-=sum;
else
cout<<"Insufficient Funds\n";
}
void check_balance() {
cout<<"Balance: "<<this->balance<<" of account number
"<<account_number<<endl;
}
Bank_Account() { //default constructor
balance = 0;
cout<<"Bank Account Successfully Created\n";
}
Bank_Account(float bal) { //parameterized constructor
balance = bal;
cout<<"Bank Account with balance "<<balance<<" Successfully
Created\n";
}
Bank_Account(int acc_num) { //parameterized constructor
balance = 0;
account_number = acc_num;
cout<<"Bank Account with account number "<<account_number<<"
Successfully Created\n";
}
Bank_Account(int acc_num,float bal) { //parameterized constructor
account_number = acc_num;
balance = bal;
cout<<"Bank Account with "<<account_number<<" and balance
"<<balance<<" Successfully Created\n";
}
Bank_Account(Bank_Account &object) { //copy constructor
cout<<"Copy Constructor Called\n";
this->balance = object.balance;
//this represents the object that calls the functions
//object represents the argument sent to the function.
}
};
int main()
{
Bank_Account b1(12345,2500);
Bank_Account b2 = b1;//calls copy constructor
Bank_Account b3(b1); //calls copy constructor
b1.check_balance();
b2.check_balance();
b3.check_balance();
return 0;
}
//
Bank Account with 12345 and balance 2500 Successfully Created
Copy Constructor Called
Copy Constructor Called
Balance: 2500 of account number 12345
Balance: 2500 of account number 1952022816
Balance: 2500 of account number -1085612304

Destructor:

A function within a class which executes the moment the object is


destroyed / deleted.

Rules:
1. Function name is same as class name
2. A prefix of tilde symbol is written (~)
3. There is only one destructor function available
4. It is called the moment an object is deleted
5. Destructor is called by the object, so it must be public

#include<iostream>
using namespace std;
class A {
public:
A() {
cout<<"3"<<endl;
}
~A() {
cout<<"4"<<endl;
}
};
int main() {
cout<<"1"<<endl;
A a;
cout<<"2"<<endl;
return 0;
}
//
1
3
2
4

#include<iostream>
using namespace std;
class A {
public:
A() {
cout<<"3"<<endl;
}
~A() {
cout<<"4"<<endl;
}
};
int main() {
cout<<"1"<<endl;
{ A a; }
cout<<"2"<<endl;
return 0;
}
//
1
3
4
2

#include<iostream>
using namespace std;
class A {
public:
A() {
cout<<"3"<<endl;
}
~A() {
cout<<"4"<<endl;
}
};
int main() {
cout<<"1"<<endl;
{ static A a; }
cout<<"2"<<endl;
return 0;
}
//
1
3
2
4
Static in class:

Static variable / method in class has a different meaning.


Static means, there’s only one copy?

Static data member rules in class:


1. Static variable cannot be initialized within a class.
2. Static variable within a class, cannot be left uninitialized to be
initialized in main function.
3. Static variables are having a single copy throughout the program
which means, even the class can access it.

#include<iostream>
using namespace std;
class Bank_Account {
public:
static float interest_rate; //declared and uninitialized within class
};
float Bank_Account::interest_rate = 5.5; //initialized outside class as a
part of the class
int main() {
Bank_Account b1,b2;
cout<<b2.interest_rate;
return 0;
}
//5.5

:: = Scope Resolution Operator


A::1B
B resolves within the scope of A

#include<iostream>
using namespace std;
class Bank_Account {
public:
static float interest_rate; //declared and uninitialized within class
};
float Bank_Account::interest_rate = 5.5; //initialized outside class as a
part of the class
int main() {
Bank_Account b1,b2;
Bank_Account::interest_rate = 6.5;
cout<<b2.interest_rate;
return 0;
}
//6.5

Static methods within class

Rules:
1. Static method is accessible by objects as well as class.
2. Static methods in class can only consist of static variables / data
members (because it can be called by the class name as well)
#include<iostream>
using namespace std;
class Bank_Account {
public:
int balance;
static float interest_rate; //can be accessed by the class name
static void fun() { //can be accessed by the class name
cout<<balance; //
}
};
float Bank_Account::interest_rate = 5.5;
int main() {
Bank_Account b1,b2;
Bank_Account::fun();
return 0;
}
//Error

#include<iostream>
using namespace std;
class Bank_Account {
public:
int balance;
static float interest_rate; //can be accessed by the class name
static void fun() { //can be accessed by the class name
cout<<interest_rate; //
}
};
float Bank_Account::interest_rate = 5.5;
int main() {
Bank_Account b1,b2;
Bank_Account::fun();
return 0;
}
//5.5

OOPS:
Abstraction, Encapsulation, Inheritance and Polymorphism

Abstraction (Hiding Data): We can have variables and methods as


private within a class. (It’s hidden). That is an abstraction.

Encapsulation: (Putting things within a capsule):


Each data member and member function is combined together to form a
capsule called class. Class is a single unit / element.

You cannot divide a class and access any member (data or method)
separately.

Inheritance

A class can inherit the data members and member functions of another
class.
Main reason: Code Reusability.

Bank Accounts: Junior Account, Senior Account, Current Account,


Savings Account, ….
Deposit, Withdraw and Check_Balane have the same code. Instead of
writing this code for different classes, you can reuse one copy of code
alone.

Base / Super / Parent Class: is the class which consists of the reusable
code
Derived / Sub / Child Class: is the class which accesses the reusable
code from base class.

#include<iostream>
using namespace std;
class Base {
public:
void fun() { cout<<"IN BASE"; }
};
class Derived: public Base {

};
int main() {
Derived d;
d.fun();
return 0;
}
//IN BASE

During inheritance, 3 types based on the access specifier:

Private, protected and public inheritance

Base class Base class Base class


variable / variable / variable /
method is method is method is
private protected public
Private Inaccessible Becomes Becomes
Inheritance within derived private in private in
class derived class derived class
Protected Inaccessible Remains Becomes
Inheritance within derived protected in protected in
class derived class derived class
Public Inaccessible Remains Remains public
Inheritance within derived protected in in derived class
class derived class

An access specifier can get stronger but cannot become weaker


during inheritance.

Private is strongest, protected is second most strongest, public is


weakest.

#include<iostream>
using namespace std;
class Base {
private: int base_private = 10;
protected: int base_protected = 20;
public: int base_public = 30;
};
class Derived1: protected Base {
//base_protected becomes protected
};
class Derived2: public Derived1 {
public: void fun() {
cout<<base_protected;
}
};
int main() {
Derived2 d2;
d2.fun();
return 0;
}
//20

#include<iostream>
using namespace std;
class Base {
private: int base_private = 10;
protected: int base_protected = 20;
public: int base_public = 30;
};
class Derived1: protected Base {
//base_protected becomes protected
};
class Derived2: public Derived1 {
//base_protected is still protected
public: void fun() {
cout<<base_protected;
}
};
int main() {
Derived2 d2;
//d2.fun();
cout<<d2.base_public;
return 0;
}
//Error

Based on order of inheritance:


Single Inheritance
Multilevel Inheritance
Hierarchical Inheritance
Multiple Inheritance

Single Inheritance

One base class inherited by one derived class

#include<iostream>
using namespace std;
class Operations {
public: double square(double n) { return n*n; }
};
class Circles : public Operations {
public: double area(double radius) { return 3.14*square(radius); }
};
int main() {
Circles c;
cout<<c.area(25);
return 0;
}

Hierarchical Inheritance

One base class is inherited by many derived classes

#include<iostream>
using namespace std;
class Operations {
public: double square(double n) { return n*n; }
};
class Circles : public Operations {
public: double area(double radius) { return 3.14*square(radius); }
};
class Spheres : public Operations {
public: double surface_area(double radius) { return
4*3.14*square(radius); }
};
int main() {
Circles c;
cout<<c.area(25)<<endl;
Spheres s;
cout<<s.surface_area(25);
return 0;
}

Multilevel Inheritance:

A base class is inherited by a derived class. This derived class is again


inherited by another derived class.
#include<iostream>
using namespace std;
class Operations {
public: double square(double n) { return n*n; }
};
class Circles : public Operations {
public: double area(double radius) { return 3.14*square(radius); }
};
class Spheres : public Circles {
public: double surface_area(double radius) { return 4*area(radius);
}
};
int main() {
Circles c;
cout<<c.area(25)<<endl;
Spheres s;
cout<<s.surface_area(25);
return 0;
}

Multiple Inheritance

#include<iostream>
using namespace std;
class Base1 {
public: void fun1() { cout<<"IN BASE1"<<endl; }
};
class Base2 {
public: void fun2() { cout<<"IN BASE2"<<endl; }
};
class Derived: public Base1, public Base2 {

};
int main() {
Derived d;
d.fun1();
d.fun2();
return 0;
}
//IN BASE 1
IN BASE 2

Derived classes only remember names of functions within the base class
(Not return type or parameters).
If multiple base classes have the same function names, the derived
class doesn’t know which one to access? (called Ambiguity)

Error: Ambiguous Error

#include<iostream>
using namespace std;
class Base1 {
public: void fun() { cout<<"IN BASE1"<<endl; }
};
class Base2 {
public: void fun() { cout<<"IN BASE2"<<endl; }
};
class Derived: public Base1, public Base2 {

};
int main() {
Derived d;
d.fun();
return 0;
}
//Ambiguity Error

DIAMOND INHERITANCE PROBLEM:

#include<iostream>
using namespace std;
class Base {
public: Base() { cout<<"BASE CON"<<endl; }
~Base() { cout<<"BASE DES"<<endl; }
};
class Derived: public Base {
public: Derived() { cout<<"DERIVED CON"<<endl; }
~Derived() { cout<<"DERIVED DES"<<endl; }
};
int main() {
Derived d;
return 0;
}
//BASE CON
DERIVED CON
DERIVED DES
BASE DEV

#include<iostream>
using namespace std;
class Base {
public: void fun() { cout<<"IN BASE"<<endl; }
};
class D1: public Base {};
class D2: public Base {};
class D3: public D1,public D2 {};
int main() {
D3 d;
d.fun();
return 0;
}
//Ambiguity

#include<iostream>
using namespace std;
class Base {
public:
Base() { cout<<"In Base"<<endl; }
void fun() { cout<<"IN BASE"<<endl; }
};
class D1: public Base {};
class D2: public Base {};
class D3: public D1,public D2 {};
int main() {
D3 d;
//d.fun();
return 0;
}
//In Base
In Base

Virtual keyword:

#include<iostream>
using namespace std;
class Base {
public:
Base() { cout<<"In Base"<<endl; }
void fun() { cout<<"IN BASE"<<endl; }
};
class D1: public virtual Base {};
class D2: public virtual Base {};
class D3: public D1,public D2 {};
int main() {
D3 d;
//d.fun();
return 0;
}
//In Base

(Only one internal base class object will be created)

Polymorphism

Multiple Forms, one entity.

One entity can exist in multiple forms during CT & RT = Compile Time
Polymorphism
One entity can exist in multiple forms not during CT & only in RT = Run
Time Polymorphism

Compile Time Polymorphism

1: Operator Overloading

#include <stdio.h>
int main()
{
int a = 50<<1;
cout<<a;
return 0;
}
//100

#include <iostream>
using namespace std;
class Complex {
public: int real, imaginary;
Complex() {}
Complex(int r,int i) {
real = r;
imaginary = i;
}
Complex operator+(Complex &second)
{
Complex temp;
temp.real = real + second.real;
temp.imaginary = imaginary + second.imaginary;
return temp;
}
};
int main()
{
Complex c1(10,5),c2(20,3);
Complex c3 = c1+c2;
cout<<c3.real<<"+i"<<c3.imaginary;
return 0;
}
//30+i8

#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1,s2;
s1 = "hello";
s2 = "world";
string s3 = s1 + s2;
cout<<s3;
Int a = 3 + 5;
cout<<a;
return 0;
}
//helloworld8

https://docs.microsoft.com/en-us/cpp/cppcx/platform-string-class?
view=msvc-170

https://www.cplusplus.com/reference/string/string/

#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1,s2;
s1 = "The rain in spain is such a pain";
s2 = "uch";
cout<<s1.find(s2);
return 0;
}
//22 (Returns index in which s2 is found within s1). Else, returns -1.

Java doesn’t allow custom operator overloading. Only inbuilt works.

2: Method Overloading

Within a single class, there can be more than one function with the same
name and same return type as long as parameters differ.

#include <iostream>
#include <string>
using namespace std;
class A {
public:
void fun() { cout<<"1"<<endl; }
void fun(char a) { cout<<"2"<<endl; }
void fun(int b) { cout<<"3"<<endl; }
void fun(float c) { cout<<"4"<<endl; }
};
int main()
{
A a;
a.fun();
a.fun('A');
a.fun(25);
a.fun(25.99);
return 0;
}
//Error (Double can be received by 3 candidate functions: Ambiguity)

#include <iostream>
#include <string>
using namespace std;
class A {
public:
void fun() { cout<<"1"<<endl; }
void fun(char a) { cout<<"2"<<endl; }
void fun(int b) { cout<<"3"<<endl; }
void fun(double c) { cout<<"4"<<endl; }
};
int main()
{
A a;
a.fun();
a.fun('A');
a.fun(25);
a.fun(25.99);
return 0;
}
//
1
2
3
4

#include <iostream>
#include <string>
using namespace std;
class A {
public:
void fun() { cout<<"1"<<endl; }
void fun(char a) { cout<<"2"<<endl; }
void fun(int b) { cout<<"3"<<endl; }
void fun(double c) { cout<<"4"<<endl; }
};
int main()
{
A a;
a.fun();
a.fun('A');
a.fun(25);
a.fun(25.99f);
return 0;
}
//
1
2
3
4
(Double is same as long float)

#include <iostream>
#include <string>
using namespace std;
class A {
public:
void fun() { cout<<"1"<<endl; }
void fun(int a) { cout<<"2"<<endl; }
void fun(int a,int b) { cout<<"3"<<endl; }
void fun(int a,int b,int c) { cout<<"4"<<endl; }
};
int main()
{
A a;
a.fun();
a.fun(10);
a.fun(10,20);
a.fun(10,20,30);
return 0;
}
//
1
2
3
4

Default Arguments => C++ & Python (Not in Java)


Default arguments can only be written right to left (Not anywhere in
middle)

#include <iostream>
#include <string>
using namespace std;
class A {
public:
void fun() { cout<<"1"<<endl; }
void fun(int a) { cout<<"2"<<endl; }
void fun(int a,int b) { cout<<"3"<<endl; }
void fun(int a,int b,int c = 15) { cout<<c<<endl; }
};
int main()
{
A a;
a.fun();
a.fun(10);
a.fun(10,20); //ambiguity
a.fun(10,20,30);
return 0;
}
//Ambiguity

#include <iostream>
#include <string>
using namespace std;
class A {
public:
void fun() { cout<<"1"<<endl; }
void fun(int a) { cout<<"2"<<endl; }
//void fun(int a,int b) { cout<<"3"<<endl; }
void fun(int a,int b,int c = 15) { cout<<c<<endl; }
};
int main()
{
A a;
a.fun();
a.fun(10);
a.fun(10,20);
a.fun(10,20,30);
return 0;
}
//
1
2
15
30

#include <iostream>
#include <string>
using namespace std;
class A {
public:
void fun() { cout<<"1"<<endl; }
void fun(int a) { cout<<"2"<<endl; }
//void fun(int a,int b) { cout<<"3"<<endl; }
void fun(int a,int b = 7,int c = 15) { cout<<c<<endl; }
};
int main()
{
A a;
a.fun();
a.fun(10); //can go to second fun(int a)
a.fun(10,20);
a.fun(10,20,30);
return 0;
}

//Ambiguity

Runtime Polymorphism

Method Overriding

A pointer to a class points to the functions of class at compile time.

#include <iostream>
using namespace std;
class Base {
public: void fun() { cout<<"IN BASE"<<endl; }
};
int main()
{
Base *b;
b->fun();
return 0;
}
//IN BASE

A pointer to a class can only point to the address of obj. Of the same
class.
One exception: Base class pointers can store addresses of derived class
objects because derived classes create internal base class objects.

#include <iostream>
using namespace std;
class Base {
};
class Derived: public Base {
public:
void fun() { cout<<"IN BASE"<<endl; }
};
int main()
{
Base *base_ptr;
Derived derived_object;
base_ptr = &derived_object;
base_ptr->fun();
return 0;
}
//Error

#include <iostream>
using namespace std;
class Base {
public:
virtual void fun() { cout<<"IN BASE"<<endl; }
};
class Derived: public Base {
};
int main()
{
Base *base_ptr;
//Derived derived_object;
//base_ptr = &derived_object;
base_ptr->fun();
return 0;
}
//empty output

A virtual function doesn’t become a part of the class during compile time.
It only becomes a part of the class during runtime.

Base class pointer points to base class function during CT.


Virtual keyword makes function part of class only during RT.

#include <iostream>
using namespace std;
class Base {
public:
virtual void fun() { cout<<"IN BASE"<<endl; } //exists only during
RT
};
class Derived: public Base {
public:
void fun() { cout<<"IN DERIVED"<<endl; } //exists during CT & RT
};
int main()
{
Base *base_ptr;
Derived derived_object;
base_ptr = &derived_object;
base_ptr->fun();
return 0;
}
//IN DERIVED

Base class ptr. Points to base class function at CT. Base class function
is virtual (exists only during RT). Base class ptr. Looks at the object it
points to (Derived class object whose function exists during CT).

Friend Classes & Functions

Friends are not a part of the class, yet they can access private, protected
and public members of the class.

Friend Functions

#include <iostream>
using namespace std;
class A {
int var = 5;
public:
friend int get_var(A &object); //retrieve the value of var
friend void set_var(A &object,int num); //update the value of var
};
int get_var(A &object) {
return object.var;
}
void set_var(A &object,int num) {
object.var = num;
}
int main()
{
A a;
set_var(a,100);
cout<<get_var(a);
return 0;
}

#include <iostream>
using namespace std;
class A {
int var = 5;
public:
friend class B;
};
class B {
public:
int get_var(A &object) {
return object.var;
}
void set_var(A &object,int num) {
object.var = num;
}
};
int main()
{
A a; B b;
b.set_var(a,100);
cout<<b.get_var(a);
return 0;
}
//100

Generic Programming

You can write modules that could execute with any datatype whatsoever.
No need to rewrite the same code with different datatypes

Templates

Means to implement Generic Programming


#include <iostream>
using namespace std;
template <class T,class U>
void bubble_sort(T *arr,U n)
{
for(int i=0;i<n-1;i++) //perform n-1 passes
{
int swap = 0;
for(int j=0;j<n-i-1;j++) //perform n-i-1 comparisons for each pass
{
if(arr[j]>arr[j+1])
{
T temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
swap = 1;
}
}
if(swap == 0)
return;
}
}
template <class T,class U>
void display_array(T *arr,U n)
{
for(int i = 0;i<n;i++)
cout<<arr[i]<<"\t";
printf("\n");
}
int main()
{
int arr1[10] = {10,5,6,4,3,7,8,2,1,9};
float arr2[10] = {5.5,5.6,5.4,5.7,5.3,5.8,5.2,5.9,5.1,5};
char arr3[13] = "Quantmasters";
bubble_sort(arr1,10);
display_array(arr1,10);
bubble_sort(arr2,10);
display_array(arr2,10);
bubble_sort(arr3,10);
display_array(arr3,10);
return 0;
}

#include <iostream>
using namespace std;
template<class T>
class Sorting {
public:
void bubble_sort(T *arr,int n)
{
for(int i=0;i<n-1;i++) //perform n-1 passes
{
int swap = 0;
for(int j=0;j<n-i-1;j++) //perform n-i-1 comparisons for each pass
{
if(arr[j]>arr[j+1])
{
T temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
swap = 1;
}
}
if(swap == 0)
return;
}
}
void display_array(T *arr,int n)
{
for(int i = 0;i<n;i++)
cout<<arr[i]<<"\t";
printf("\n");
}
void insertion_sort(T *arr,int n)
{
for(int i = 1;i<n;i++) //perform n-1 passes
{
int j = i;
while(j>0 && arr[j]<arr[j-1])
{
T temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
j--;
}
}
}
};
int main()
{
int arr1[10] = {10,5,6,4,3,7,8,2,1,9};
float arr2[10] = {5.5,5.6,5.4,5.7,5.3,5.8,5.2,5.9,5.1,5};\
Sorting<int> s1;
Sorting<float> s2;
s1.bubble_sort(arr1,10);
s1.display_array(arr1,10);
s2.insertion_sort(arr2,10);
s2.display_array(arr2,10);
return 0;
}

STL

C++ has inbuilt code to create data structures.

Standard Template Library


It’s a library of standard templates created within C++ for us to use.

(Competitive Coding Videos)

JAVA
C++ = Object Oriented
Java = Object Oriented
Difference?

Java = More Application Oriented


C++ = More Hardware Oriented

What does Java not have that’s available in C & C++?


Pointers (You cannot create a pointer. It’s available internally)
Multiple Inheritance
Destructors

Default Arguments Reference Variable


Structures
Unions
Goto and Label

What does Java offer that’s not there in C++?


(Buzzwords / Features of Java)

Object Oriented (OOPS - Abstraction / Inh / Poly / Encaps)

Architecture Neutral
Java doesn’t change anything based on diff. Architectures (16/32/64
bits).
Size of int differs based on architectures in C & C++ unlike Java

Platform Independent
A compiled code in one platform can be executed in any other platform
as well

Compiled & Interpreted


Each java program is compiled and stored as bytecode (.class files)
The bytecode is interpreted if the code isn’t repeated. If there’s a loop /
recursion, it is compiled.
Javac (Java Compiler) - Compiles Source Code into Bytecode
JIT (Just In Time) - Compiles / Interprets bytecode to execute it based
on the scenario.

Secure
We don’t have pointers. (You cannot access random memory)
JVM (Java Virtual Machine) - Ensure that the Java program that runs
has limited access to memory.

Robust
Automatic Garbage Collector (If any var / object is no longer used in the
program, it’s automatically removed from memory). Memory
management is very strong.

Download Java => JDK & JRE

JIT (Just In Time) - Compiles / Interprets bytecode and runs the program
JVM - Allocate memory and space for a bytecode to execute
JRE - Java Runtime Environment (Consists of libraries to run Java
Program + JVM + JIT)
JDK - Java Development Kit (Consists of libraries to compile Java
Program + JRE + JVM + JIT)

Every single line of code within Java must be inside a class.


Main function must be written within a class whose name is the same as
file name.

Every class name begins with upper case characters.


A class called System => Access output stream => Use print function to
write on console.

System has 3 streams => in, out, err

class Main {
void main() {
System.out.print("Hello World");
}
}

Main function must be static to be accessed from outside of the class


without an object.

Access Specifiers in Java: private, default, protected and public

Class which consists of main function and the main function itself must
always be public (as they are accessed from outside the program)

C (int argc, char **argv)

In Java, it is compulsory to type command line arguments within the


program as input.

Basic Java Programs

public class Main {


public static void main(String args[]) {
System.out.print("Hello World");
}
}
//Hello World

public class Main {


public static void main(String args[]) {
String s = "hello world";
System.out.print(s.length());
}
}
//11

public class Main {


public static void main(String args[]) {
int a = 5,b = 10;
System.out.print("The value of a is "+a+" and value of b is "+b);
}
}
//The value of a is 5 and value of b is 10

Package: A directory which may consist of sub-directories or / and


classes which can be imported to our program.

C++: Class object; (Object is declared as well as initialized)


Java:
Class_Name object_name; //declared object.
Object_name = new Class_Name(); //initialize

Class_Name object_name = new Class_Name();

import java.util.Scanner;
public class Main {
public static void main(String args[]) {
int a,b;
Scanner sc = new Scanner(System.in);
a = sc.nextInt();
b = sc.nextInt();
int c = a+b;
System.out.print("The sum of a "+a+" and "+b+" is "+c);
}
}

https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html

Datatypes & Variables

Boolean (Only 1 bit)

import java.util.Scanner;
public class Main {
public static void main(String args[]) {
boolean b = false;
System.out.print(b);
}
}
//false

Types of integers:
Byte (1 byte)
Short int (2 bytes)
Int (4 bytes)
Long int (8 bytes)

import java.util.Scanner;
public class Main {
public static void main(String args[]) {
byte b = 100;
System.out.print(b);
}
}
//100

Decimal:
Float, double

import java.util.Scanner;
public class Main {
public static void main(String args[]) {
float b = 35.72;
System.out.print(b);
}
}
//Error

No higher sized value can be stored in a lower sized datatype without


explicit specification.

import java.util.Scanner;
public class Main {
public static void main(String args[]) {
float b = 35.72f;
System.out.print(b);
}
}
//35.72

import java.util.Scanner;
public class Main {
public static void main(String args[]) {
byte b = (byte)352;
System.out.print(b);
}
}
//96

import java.util.Scanner;
public class Main {
public static void main(String args[]) {
byte b = (byte)352;
System.out.print(b);
}
}
//Error

Only one class in a file can be public i.e. the class which consists of
main function.

Access Specifiers:

Private, default, protected, public

private default protected public


Within class Y Y Y Y
Outside class, N Y Y Y
within subclass
in same package
Outside class, N Y N Y
using object in
same package
Outside class, N N Y Y
within subclass
outside the
package
Outside class, N N N Y
using object
outside package

Private = most protected (Only within class)


Default = (Within package, subclass / object)
Protected = (Within and outside package only using subclass)
Public = (Within and outside package using subclass and objects)

import java.util.Scanner;
class A {
int var = 5;
void fun() {
System.out.print(var);
}
}
public class Main {
public static void main(String args[]) {
A a = new A();
System.out.println(a.var);
a.fun();
}
}
//
5
5

Anonymous Class

import java.util.Scanner;
class A {
int var = 5;
void fun() {
System.out.print(var);
}
}
public class Main {
public static void main(String args[]) {
new A().fun();
}
}
//5

Constructors

import java.util.Scanner;
class A {
A() { System.out.println("IN CONSTRUCTOR"); }
}
public class Main {
public static void main(String args[]) {
A[] a = new A[10]; //declares n objects.
a[0] = new A(); //initialize
a[1] = new A(); //initialize
}
}
//IN CONSTRUCTOR
IN CONSTRUCTOR

import java.util.Scanner;
class A {
A() { System.out.println("DEFAULT CONSTRUCTOR"); }
A(int a) { System.out.println("PARAMETERIZED
CONSTRUCTOR"); }
A(A a) { System.out.println("COPY CONSTRUCTOR"); }
}
public class Main {
public static void main(String args[]) {
A a = new A();
A b = new A(10);
A c = a;
}
}
//DEFAULT CONSTRUCTOR
PARAMETERIZED CONSTRUCTOR

import java.util.Scanner;
class A {
A() { System.out.println("DEFAULT CONSTRUCTOR"); }
A(int a) { System.out.println("PARAMETERIZED
CONSTRUCTOR"); }
A(A a) { System.out.println("COPY CONSTRUCTOR"); }
}
public class Main {
public static void main(String args[]) {
A a = new A();
A b = new A(10);
A c = new A(a);
}
}
//DEFAULT CONSTRUCTOR
PARAMETERIZED CONSTRUCTOR
COPY CONSTRUCTOR

This Keyword

Reference variable within Java which has replaced this pointer of C++

import java.util.Scanner;
class A {
int var = 25;
void fun() {
System.out.println(this.var);
}
}
public class Main {
public static void main(String args[]) {
A a = new A();
A b = new A();
a.var = 50;
b.var = 100;
a.fun();
}
}

Static

Static variable, method, class and block

Static variable:
There is only one copy of the variable throughout the program.
Has a def. Value of 0.

public class Main


{
static int var;
public static void main(String[] args) {
System.out.println(var);
}
}
//0

Static methods:
Methods of a class which can be accessed without an object.

class A {
static void fun() { System.out.println("IN FUN"); }
}
public class Main
{
static int var;
public static void main(String[] args) {
A.fun();
}
}
//IN FUN

Static class
Outer class cannot be static. Only inner class can be.

class Outer {
static class Inner {
void nonstatic_fun() { System.out.println("IN NON STATIC"); }
static void static_fun() { System.out.println("IN STATIC"); }
}
}
public class Main
{
public static void main(String[] args) {
Outer.Inner.static_fun();
}
}
//IN STATIC

class Outer {
static class Inner {
void nonstatic_fun() { System.out.println("IN NON STATIC"); }
static void static_fun() { System.out.println("IN STATIC"); }
}
}
public class Main
{
public static void main(String[] args) {
Outer.Inner.nonstatic_fun();
}
}
//Error
class Outer {
static class Inner {
void nonstatic_fun() { System.out.println("IN NON STATIC"); }
static void static_fun() { System.out.println("IN STATIC"); }
}
}
public class Main
{
public static void main(String[] args) {
Outer.Inner i = new Outer.Inner();
i.nonstatic_fun();
}
}
//IN NON STATIC

Static blocks & non static blocks

Static blocks are executed the first time an object’s functions are called
for a class. (Executes only one time)
Non-static blocks are executed every time a new object’s functions are
called.
Static blocks execute first, non static blocks execute second

class A {
static { System.out.println(1); }
{ System.out.println(3); }
void fun() { System.out.println(5); }
{ System.out.println(4); }
static { System.out.println(2); }

}
public class Main
{
public static void main(String[] args) {
A a = new A();
a.fun();
}
}

//
1
2
3
4
5

class A {
static { System.out.println(1); }
{ System.out.println(3); }
A() { System.out.println(5); }
{ System.out.println(4); }
static { System.out.println(2); }

}
public class Main
{
public static void main(String[] args) {
A a = new A();
}
}
//
1
2
3
4
5

class A {
static { System.out.println(1); }
{ System.out.println(3); }
A() { System.out.println(5); }
{ System.out.println(4); }
static { System.out.println(2); }
}
public class Main
{
public static void main(String[] args) {
A a = new A(); //static blocks and non static blocks execute
only for first object
A b = new A(); //only non static blocks execute for further
objects
}
}
//
1
2
3
4
5
3
4
5

Inheritance

class Base {
void fun() {
System.out.println("IN BASE");
}
}
class Derived extends Base {

}
public class Main
{
public static void main(String[] args) {
Derived d = new Derived();
d.fun();
}
}
//IN BASE

class Base1 {
void fun() {
System.out.println("IN BASE");
}
}
class Base2 {
void fun() {
System.out.println("IN BASE");
}
}
class Derived extends Base1,Base2 {

}
public class Main
{
public static void main(String[] args) {
Derived d = new Derived();
d.fun();
}
}
//Error

Compile Time Polymorphism (Operator / Method Overloading)

Operator+ (In C++) not possible within Java

public class Main


{
public static void main(String[] args) {
String str1 = "250";
String str2 = "250";
String str3 = str1+str2;
int result = 250 + 250;
System.out.println(str3+" "+result);
}
}
//250250 500

class A {
void fun() { System.out.println(1); }
void fun(int a) { System.out.println(2); }
void fun(float a) { System.out.println(3); }
}
public class Main
{
public static void main(String[] args) {
A a = new A();
a.fun();
a.fun(10);
a.fun(1.0);
}
}
//Error: Lossy Conversion Error

class A {
void fun() { System.out.println(1); }
void fun(int a) { System.out.println(2); }
void fun(float a) { System.out.println(3); }
}
public class Main
{
public static void main(String[] args) {
A a = new A();
a.fun();
a.fun(10);
a.fun(1.0f);
}
}
//1
2
3
Runtime Polymorphism (Method Overriding)

instanceof

class Base {

}
class Derived extends Base {

}
public class Main
{
public static void main(String[] args) {
Base b = new Base();
Derived d = new Derived();
System.out.println("b is object of Base: "+(b instanceof Base));
System.out.println("d is object of Derived: "+(d instanceof
Derived));
System.out.println("d is object of Base: "+(d instanceof Base));
System.out.println("b is object of Derived: "+(b instanceof
Derived));
}
}
//b is object of Base: true
d is object of Derived: true
d is object of Base: true
b is object of Derived: false

class Base {
void fun() { System.out.println("IN BASE"); }
}
class Derived extends Base {
void fun() { System.out.println("IN DERIVED"); }
}
public class Main
{
public static void main(String[] args) {
Base b; //during CT
b = new Derived(); //during RT
b.fun();
}
}
//IN DERIVED

Super Keyword

Super keyword is used to access base class data from derived class.

class Base {
int var = 5;
void fun() { System.out.println("IN BASE"); }
}
class Derived extends Base {
void fun() {
super.fun();
System.out.println(super.var);
}
}
public class Main
{
public static void main(String[] args) {
new Derived().fun();
}
}
//IN BASE
5

class Base {
Base() { System.out.println("IN BASE"); }
}
class Derived extends Base {
void fun() {
super();
}
}
public class Main
{
public static void main(String[] args) {
new Derived().fun();
}
}
//Error: Base class constructor can only be accessed by derived class
constructor’s first statement

class Base {
Base() { System.out.println("IN BASE"); }
}
class Derived extends Base {
Derived() {
super();
}
}
public class Main
{
public static void main(String[] args) {
new Derived();
}
}
//IN BASE

Final Keyword

class Base {
void fun() { System.out.println("IN BASE"); }
}
class Derived extends Base {
void fun() { System.out.println("IN DERIVED"); }
}
public class Main
{
public static void main(String[] args) {
final int a = 325;
a++;
System.out.println(a);
}
}
//Error

class Base {
void fun() { System.out.println("IN BASE"); }
}
class Derived extends Base {
void fun() { System.out.println("IN DERIVED"); }
}
public class Main
{
public static void main(String[] args) {
final int a;
a = 325;
System.out.println(a);
}
}
//Error

class Base {
final void fun() { System.out.println("IN BASE"); }
}
class Derived extends Base {
void fun() { System.out.println("IN DERIVED"); }
}
public class Main
{
public static void main(String[] args) {
Derived d = new Derived();
d.fun();
}
}
//final methods cannot be overridden

final class Base {


void fun() { System.out.println("IN BASE"); }
}
class Derived extends Base {
void fun() { System.out.println("IN DERIVED"); }
}
public class Main
{
public static void main(String[] args) {
Derived d = new Derived();
d.fun();
}
}
//Error: Cannot inherit from a final base class

Exception Handling

Compile Time Errors (Checked Errors) & Run Time Errors (Exceptions
or Unchecked Errors)

import java.util.Scanner;
public class Main
{
public static void main(String[] args) {
int a,b,c;
Scanner sc = new Scanner(System.in);
a = sc.nextInt();
b = sc.nextInt();
c = a/b;
System.out.println("Result of Division = "+c);
}
}
//Result of Division = 4

import java.util.Scanner;
public class Main
{
public static void main(String[] args) {
int a,b,c;
Scanner sc = new Scanner(System.in);
a = sc.nextInt();
b = sc.nextInt();
c = a/b;
System.out.println("Result of Division = "+c);
}
}
//20
0
Exception (Error: Runtime Error)

Try: You write the code that could have exceptions in try block
Catch: Written immediately after try and will only execute if exception is
found
Finally: Will always execute whether exception occurs or not.

If exception found: You skip remaining try block statements and go to


catch. After catch, go to next statements

If no exception found: You directly go from try to next statements after


catch

import java.util.Scanner;
public class Main
{
public static void main(String[] args) {
int a,b,c;
Scanner sc = new Scanner(System.in);
a = sc.nextInt();
b = sc.nextInt();
try {
c = a/b; //ArithmeticException
System.out.println("Result of Division = "+c);
}
catch(Exception e) {
System.out.println("Do not divide by 0");
}
finally {
System.out.println("Always executes");
}
System.out.println("Program is continuing");
}
}
//
20
10
Result of Division = 2
Always executes
Program is continuing

//
20
0
Do not divide by 0
Always executes
Program is continuing

import java.util.Scanner;
public class Main
{
public static void main(String[] args) {
int a,b,c;
Scanner sc = new Scanner(System.in);
a = sc.nextInt();
b = sc.nextInt();
try {
c = a/b; //ArithmeticException
System.out.println("Result of Division = "+c);
String s = null;
System.out.println(s.length()); //NullPointerException
}
catch(ArithmeticException e) { //execute only if
ArithmeticException occurs
System.out.println("Do not divide by 0");
}
catch(NullPointerException e) { //execute only if
NullPointerException occurs
System.out.println("Do not print length of Null String");
}
finally {
System.out.println("Always executes");
}
System.out.println("Program is continuing");
}
}
//
20
0
Do not divide by 0
Always executes
Program is continuing

//
20
2
Result of Division = 10
Do not print length of Null String
Always executes
Program is continuing

import java.util.Scanner;
public class Main
{
public static void main(String[] args) {
int a,b,c;
Scanner sc = new Scanner(System.in);
a = sc.nextInt();
b = sc.nextInt();
int arr[] = new int[5];
try {
c = a/b; //ArithmeticException
System.out.println("Result of Division = "+c);
System.out.println(arr[a]); //ArrayIndexOutOfBoundsException
String s = null;
System.out.println(s.length()); //NullPointerException
}
catch(ArithmeticException e) { //execute only if
ArithmeticException occurs
System.out.println("Do not divide by 0");
}
catch(NullPointerException e) { //execute only if
NullPointerException occurs
System.out.println("Do not print length of Null String");
}
finally {
System.out.println("Always executes");
}
System.out.println("Program is continuing");
}
}
//
20
10
Result of Division = 2
Always executes
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
Index 20 out of bounds for length 5
at Main.main(Main.java:13)

import java.util.Scanner;
public class Main
{
public static void main(String[] args) {
int a,b,c;
Scanner sc = new Scanner(System.in);
a = sc.nextInt();
b = sc.nextInt();
int arr[] = new int[5];
try {
c = a/b; //ArithmeticException
System.out.println("Result of Division = "+c);
System.out.println(arr[a]); //ArrayIndexOutOfBoundsException
String s = null;
System.out.println(s.length()); //NullPointerException
}
catch(Exception e) { //all other exceptions
System.out.println("Some other error occured");
}
catch(ArithmeticException e) { //execute only if
ArithmeticException occurs
System.out.println("Do not divide by 0");
}
catch(NullPointerException e) { //execute only if
NullPointerException occurs
System.out.println("Do not print length of Null String");
}
finally {
System.out.println("Always executes");
}
System.out.println("Program is continuing");
}
}
//
Error All exceptions are caught

import java.util.Scanner;
public class Main
{
public static void main(String[] args) {
int a,b,c;
Scanner sc = new Scanner(System.in);
a = sc.nextInt();
b = sc.nextInt();
int arr[] = new int[5];
try {
c = a/b; //ArithmeticException
System.out.println("Result of Division = "+c);
System.out.println(arr[a]); //ArrayIndexOutOfBoundsException
String s = null;
System.out.println(s.length()); //NullPointerException
}
catch(ArithmeticException e) { //execute only if
ArithmeticException occurs
System.out.println("Do not divide by 0");
}
catch(NullPointerException e) { //execute only if
NullPointerException occurs
System.out.println("Do not print length of Null String");
}
catch(Exception e) { //all other exceptions
System.out.println("Some other error occurred");
}
finally {
System.out.println("Always executes");
}
System.out.println("Program is continuing");
}
}
//
20 5
Result of Division = 4
Some other error occurred
Always executes
Program is continuing

Throw: used to send an exception from one function to another


Throws: for the same purpose (Optional)
import java.util.Scanner;
class Voting {
static void vote(int age) {
if(age>=18)
System.out.println("Continue voting process");
else
throw new ArithmeticException("Cannot vote if age is lesser than
18");
}
}
public class Main
{
public static void main(String[] args) {
try {
Voting.vote(10); //Exception is sent to the function call
}
catch(Exception e) {
System.out.println(e.getMessage());
}
}
}
//Cannot vote if age is lesser than 18

import java.util.Scanner;
class Voting {
static void vote(int age) throws ArithmeticException {
if(age>=18)
System.out.println("Continue voting process");
else
throw new ArithmeticException("Cannot vote if age is lesser than
18");
}
}
public class Main
{
public static void main(String[] args) {
try {
Voting.vote(10); //Exception is sent to the function call
}
catch(Exception e) {
System.out.println(e.getMessage());
}
}
}
//Cannot vote if age is lesser than 18

Abstraction

Abstract Class is used to hide data / implementation


Rules
1. Prefix called abstract
2. Can have abstract and non abstract method
3. Abstract means hidden (Empty method is called abstract method)
4. Abstract method must be implemented in derived class
5. You cannot have objects of abstract classes
6. You can still have constructors and static methods
7. Constructors of abstract class execute when derived class object
is created

import java.util.Scanner;
abstract class BankAccount {
abstract void createAccount();
void withdraw() { System.out.println("Performing Withdraw
Function"); }
void deposit() { System.out.println("Performing Deposit Function"); }
void check_bal() { System.out.println("Performing Check Balance
Function"); }
}
class JuniorAccount extends BankAccount {
void createAccount() { System.out.println("Creating Junior
Account"); }
}
class SeniorAccount extends BankAccount {
void createAccount() { System.out.println("Creating Senior
Account"); }
}
public class Main
{
public static void main(String[] args) {
JuniorAccount j = new JuniorAccount();
SeniorAccount s = new SeniorAccount();
j.createAccount();
s.createAccount();
j.withdraw();
s.withdraw();
}
}
//
Creating Junior Account
Creating Senior Account
Performing Withdraw Function
Performing Withdraw Function

Interface

Interface provides 100% abstraction (Everything in an interface must be


redefined within derived class).

Rules:
1. Interface isn’t a class.
2. Extends keyword is used to derive same types
3. Interface -> Class (Implements keyword instead of extends)
4. Any variable is public, static and final by default
5. Any method is public and abstract by default
6. Any method redefined from interface must be public
import java.util.Scanner;
interface BankAccount {
float interest_rate = 3.5f; //all data members are public, static and final
by default
void createAccount();
void withdraw(); //all methods are public and abstract by default
}
class JuniorAccount implements BankAccount {
public void createAccount() { System.out.println("Creating Junior
Account"); }
public void withdraw() { System.out.println("Perform Withdraw from
JuniorAccount"); }
}
class SeniorAccount implements BankAccount {
public void createAccount() { System.out.println("Creating Senior
Account"); }
public void withdraw() { System.out.println("Perform Withdraw from
SeniorAccount"); }
}
public class Main
{
public static void main(String[] args) {
JuniorAccount j = new JuniorAccount();
SeniorAccount s = new SeniorAccount();
j.createAccount();
s.createAccount();
j.withdraw();
s.withdraw();
}
}
//
Creating Junior Account
Creating Senior Account
Perform Withdraw from JuniorAccount
Perform Withdraw from SeniorAccount

Collections
(For Competitive Coding as well)
C: No implementation of DS & A
C++: STL
Java: Collections = Inbuilt implementation of all data structures &
algorithms
Stacks, queues, list, set, map, hash…

https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html

Next thing: Competitive Coding Videos

Java: Collections cannot be created using datatypes.


int => Integer
char => String
float => Float
double => Double

import java.util.Stack;
public class Main
{
public static void main(String[] args) {
Stack<Integer> s = new Stack<Integer>();
s.push(10);
s.push(20);
s.push(30);
s.pop();
System.out.println(s.peek());
}
}
//20

You might also like