You are on page 1of 53

Each C program goes through a number of steps:

Preprocessor:
1. To remove the # lines, which are called preprocessor directive:
2. #include -> include header files, contain library functions,
<stdio.h> - printf, scanf, getchar, gets, puts
<stdlib.h> - exit(0), malloc(),calloc(),free()
<math.h> - sqrt, pow
<string.h> - strcpy, strcmp, strcat
<ctype.h> - islower, isupper, isdigit
3. #define - MACROS
a. Define objects, #define PI 3.14
b. Define functions #define max(a,b) a>b?a:b
4. Preprocessor only to replace, before compilation
5. Preprocess also removes all comments before compilation
6. Converts source code to expanded source code
7. File.c becomes file.i

Compiler:
1. Grammar of a programming language is called syntax
2. Responsible for checking the syntax of the code, and throwing errors
3. Only responsible for syntax errors.
4. Converts the expanded source code into assembly code
5. File.i becomes file.s

Assembler:
1. Converts the assembly code into object code
2. File.s becomes file.obj

Linker:
1. Converts object code and links the respective files needed
2. Converts object code into executable code
3. File.obj becomes file.exe

Loader:
1. Loads the executable file into the RAM and executes it

When the file.exe is loaded into RAM and each line is executed, the memory layout of that
program is created in RAM. Data Segment, Text Segment, Heap, Stack.

After program finishes execution, all of its allocated memory is destroyed and memory is freed
up for other applications

#include<stdio.h>
void func(int); //Function Declaration,Prototype
int main()
{
int a=50;
printf("%d: ",a);
func(a); //Function Call
return 0;
}
void func(int a) //Function Definition
{
printf("%d: ",a);
}

Keywords
main
scanf
printf
int
long
char
return
if
else
for
while
do
double
short
switch
break
continue
void
float
struct
union
const
static
auto
register
extern

All variables/function calls,etc is done at runtime


No memory is allocated at compile time
Runtime
At the time of execution, information is known at run time ie when program executed

Compiletime
At the time of compilation, information is known at compile time ie when program compiled

Sizeof returns the size of any datatype, structure, array, variable, function or pointer

Data Types:

Primitive: int, char, float, double, void

16 bit compiler:
int - 2 bytes
char - 1 byte
float - 4 bytes
double - 8 bytes

32 bit compiler:
int - 4 bytes
char - 1 byte
float - 4 bytes
double - 8 bytes

Derived: array, pointer, structure, union

Data Type modifiers: long, short, signed, unsigned

short int, long int, long double, no long float(double)

32 bit compiler:
int - 4 bytes
short int - short - 2 bytes
long int - long - 8 bytes
signed int - int - both +ve and -ve integers
unsigned int - only +ve numbers and 0

Range: 16 bit compiler:

signed int - int - 2 bytes - 16 bits - 2^16 - 65536

-32768 <---------0--------->32767

unsigned int - 2 bytes - 16 bits - 2^16 - 65536


0---------->65535

Rollback - Rollover

#include<stdio.h>
int main()
{
int a=32767,b;
unsigned int c=65535,d;
b=a+1;
printf("%d+1=%d\n",a,b);
a=-32768;
b=a-1;
printf("%d-1=%d\n",a,b);
d=c+1;
printf("%u+1=%u\n",c,d);
c=0;
d=c-1;
printf("%u-1=%u\n",c,d);
return 0;
}

Comments
//single line
/* multi
line */

Variables:

1. Types
a. Global
Created outside all functions
Available throughout the program, even if the program is in different files

b. Local
Created inside each block
Block is { }
Available inside its own block

c. Formal (Local)
Variable created in function declaration and behave as local to that function

2. Storage Class
a. Static
Does not get destroyed, even if thefunction returns, stays same across all
function calls
Keyword: static

b. External
Variable can be initialized anywherer and used anywhere
Keyword: extern

c. Automatic
Local variable itself are called automatic
Keyword: auto

d. Register
All variables are created in RAM.
Register variable is created in register
Becase access is faster

3. Scope
a. Block
Anything available within a block
For eg: local variables

b. File
Anything available throughout files
For eg: global variables, functions

c. Function
Applies only to label for goto statement

d. Function Prototype
Within function prototype

4. Linkage
a. External
Applies: global, external variables

b. Internal
Applies: global static

c. None
Applies: local variables
#include <stdio.h>
int var1; //global,data,default=0,file scope,external linkage
static int var2; //global static,data,default=0,file scope,internal linkage
void func();
int main()
{
func(); //1 1 1 1 1 , var3 destroyed
func(); //2 2 1 2 2 , var3 destroyed
return 0;

}
void func()
{
auto int var3=0; //local,automatic,stack,default=garbage,block scope,no linkage
extern int var4; //extern,global,data,file scope,external linkage
static int var5; //local static,data,default=0,block scope,no linkage
var1++; //var1=1,2
var2++; //var2=1,2
var3++; //var3=1,1
var4++; //var4=1,2
var5++; //var5=1,2
printf("%d %d %d %d %d",var1,var2,var3,var4,var5);
}
int var4=0;

Constants:

character 'c' - default is char


if('c'>'d') 'd' is char, 'c' is char(1byte)

integer - default is int


switch(h)
case 1:
case 2: 1,2 will be stored as int(2bytes)
case 32768: it will be stored as long int(bytes)

floating point - default is double


#define PI 3.14

area=3.14*r*r; //3.14 will be stored as double(8bytes)

float - 2.3F
area=3.14F*r*r; 3.14 will be stored as float(4bytes)
long int - 10L

unsigned int - 100U

octal - 012 //prefix as 0

hexadecimal - 0x80 //prefix with 0x


int ch=0x80//0x80 is 128 in decimal

string constants
printf("Hello World %s","Technical %s");//Hello World is a printable statement, "Technical"

is a string constant being printed in place of %s

backslash constants/escape sequences


\b Backspace
\f Form feed
\n New line
\r Carriage return
\t Horizontal tab
\" Double quote
\' Single quote
\\ Backslash
\v Vertical tab
\a Alert
\? Question mark

%%

Operators:

Assignment =

Type conversion with assignment

int x=65;
char ch='A';//65
float f=65.5;
void func(void)
{
ch = x; //int (2bytes) is converted to char (1byte),
x = f; //float (4bytes) is converted to int (2bytes)
f = ch; //char is converted to float
f = x; //int is converted to float
}

Multiple assignment
int x=0,y=0,z=0;

int x,y,z;
x=y=z=0;

Shorthand assignment
x=x+y //x+=y
x=x-y //x-=y
x=x*y //x*=y
x=x/y //x/=y

Arithmetic
binary: (two operands) + - * / %
unary: (one operand) ++ -- - (unary minus) int a=-5; //5*-1

Increment/Decrement: (post/pre)
#include<stdio.>
void main()
{
int a,b,c,d;
a=5;b=6;
c= a++ + a-- + ++a + --a;
d= b++ + b-- - ++b + --b;
}

#include<stdio.>
void main()
{
int a,b,c,d;
a=5;b=6;
c= a++ + a-- + ++a + --a;
// c= 5(a=6) + 6(a=5) + (a=6)6 + (a=5)5 = 22
d= b++ + b-- - ++b + --b;
// d= 6(b=7) + 7(b=6) - (b=7)7 + (b=6)6 = 12
}

c=20 , 22 , 10, 20
d=10 , 12 , 12, 12

Post ++/-- has higher precedence pre ++/--


Arithmetic operators are after ++/--
b=a++ ---> b=a; a=a+1;
b=++a ---> a=a+1; b=a;

while(a++) --> while(a) a=a+1;

Relational (binary)
< > <= >= == !=

C doesn’t support boolean values, 0 and 1 are taken as false and true respectively
0 and 1 is what the compiler outputs as false and true.
But for a user, any non-zero and non-null value will be true, which the compiler will convert to 1.
And all zero and null values will be false, which compiler will convert to 0

a=5, b=0

5>0, both 5 and 0 will be treated as integers


5>0 = 1 where 1 stands for true

Logical
&& || !

Result of any logical operator between two operands is going to be either 0 or 1 where 0 is false
and 1 is true.
The input for logical operators is going to 0 or 1 based on true or false

1&&2 = 1&&1 = 1
1||2 = 1||1 = 1
2&&0 = 1&&0 = 0
2||0 = 1||0 = 1
!(2) = !(1) = 0

13&&14 = 1&&1 = 1
-34||-78 1||1 = 1

int a,b,c,d,e;
a=b=c=d=5;
e=(a==b)&&(c==d);
e=(5==5)&&(5==5);
e=1&&1;
e=1;

Bitwise (int/char) & | ~ ^ << >>


int a=4,b=2,c;

c=a&b;//4&2
a= 0b000 0000 0000 0100 =4 &
b= 0b000 0000 0000 0010 =2
c= 0b000 0000 0000 0000 =0

c=a|b;//4|2
a= 0b000 0000 0000 0100 =4 |
b= 0b000 0000 0000 0010 =2
c= 0b000 0000 0000 0110 =6

c=a^b;//returns 1 if both bits not same


a= 0b000 0000 0000 0100 =4 ^
b= 0b000 0000 0000 0010 =2
c= 0b000 0000 0000 0110 =6

int a=6,b=6;
if(a==b)

if(!(a^b))
printf("equal");

//a=0b000 0000 0000 0110


//b=0b000 0000 0000 0110
// 0b000 0000 0000 0000

c=~a;
a= 0b000 0000 0000 0100 =4
c= 0b111 1111 1111 1011 =32763

c=~b;
b= 0b000 0000 0000 0010 =2
c= 0b111 1111 1111 1101 =32765

c=a<<b; //4<<2, left shift, a*2pow(b)=4*2pow(2)=4*4=16


a= 0000 0000 0000 0100 =4
0|000 0000 0000 01000 =8
00|00 0000 0000 010000 =16

c=a>>b; //4>>2, right shift, a/2pow(b)=4/2pow(2)=4/4=1


a= 0000 0000 0000 0100 =4
00000 0000 0000 010|0=2
000000 0000 0000 01|00=1
4<<3 = 4*2pow(3)=4*8=32

8>>3 = 8/2pow(3)=8/8=1

8>>2 = 8/2pow(2)=8/4=2

16>>3 = 16/2pow(3)=16/8=2

1<<2 = 1*2pow(2)=1*4=4

1<<4 = 1*2pow(4)=1*16=16

Type Conversion:
When constants and variables of different types are mixed in an expression, they are all
converted to the same type. The compiler converts all operands up to the type of the largest
operand, which is
called type promotion.

c=10.5+10+'A';

c=double+int+char;

c=double+int+int;

c=10.5+10+65;

c=double+double+double;

c=10.5+10.0+65.0;

c=85.500000

char ch;
int i;
float f;
double d;

ch=i; int is 16 bits, it was made 8 bits and converted to char

result=(ch/i)+(f*d)-(f+i)

result= (char/int) + (float*double) - (float+int)


result= (int/int) + (double*double) - (float+float)
result= int + double - float
result= double + double - float
result= double - float
result= double - double
result= double

Type Casting: (type) - unary operator - changes the datatype

#include <stdio.h>
int main(void)
{
int i;
for(i=l; i<=5; ++i)
printf("%d/2 is: %f\n",i,i/2);
return 0;
}

Ternary Operator:
condition? true statement: false statement;
int a=6,b=5;
printf("%d",(a>b?a:b)); //6
int a=6,b=9;
printf("%d",(a>b?a:b)); //9

sizeof operator - returns size in bytes of the element given


comma(,) operator - separate a list. int a=5,6,7;//a=5

int a;
a=(5,6); //a=6
a=5,6; //a=5

for(i=0,j=0;i<10,j<5;i++,j++) //any no of initializations & iterations but only one condition


{
printf("Hello World");
}

dot operator(.) (directly reference structures and unions)


arrow operator(->) (indirectly reference structures and unions through pointers

[] and ()
[] are used to denote indices in an array
() are used for parameter list, function calls
{} are used for array list, blocks, function definitions
& and * for pointers

& address operator


* dereference/indirection operator

Category Operator Associativity


Postfix () [] -> . ++ -- Left to right
Unary + - ! ~ ++ -- (type) * & sizeof Right to left
Multiplicative */% Left to right
Additive +- Left to right
Shift << >> Left to right
Relational < <= > >= Left to right
Equality == != Left to right
Bitwise AND & Left to right
Bitwise XOR ^ Left to right
Bitwise OR | Left to right
Logical AND && Left to right
Logical OR || Left to right
Ternary ?: Right to left
Assignment = += -= *= /= %= >>= <<= &= ^= |= Right to left
Comma , Left to right

Control Statements:

• Selection/Branch (if and switch)


if, if-else,if-else-if ladder, switch
case is a label statement
default is executed if no case matches
if no default, no action
switch cases cannot be identical
character constants in case are converted to integer

• Iteration/Loop
pre-determined(for), open-ended(while,do-while)
for(initialization;condition;iteration)
statement;
infinite loops
loop control variable
while loop
do while loop

• Jump
return goto used anywhere
break continue used with loops (break with switch)
return has to be used with value with non void functions
void functions don't require return as they do return at }
but return without value can be used to return from a func

goto not used anymore, label

break terminates a loop or a switch

exit(returncode) from stdlib.h, acts as if it were breaking out of the entire program.
The value of return_code is returned to the calling process, which is usually the operating
system.Zero is commonly used as a return code to indicate normal program termination. Other
arguments are used to indicate some sort of error.
continue forces iteration of a loop.
For the for loop, continue causes the increment and then the
conditional test portions of the loop to execute. For the while and do-while loops, program
control passes to the conditional tests

• Expression
Expression statement is simply a valid expression followed by a semicolon

• Block
Block statements are simply groups of related statements that are treated as a unit. The
statements that make up a block are logically bound together. Block statements are also called
compound statements. A block is begun with a { and terminated by its matching }.

Functions:

#include<stdio.h>
int add(int,int); //Function Declaration

int main()
{
int p=10,q=20,sum;
sum=add(p,q); //Function Call
printf("Sum is %d",sum);
return 0;
}

int add(int a,int b) //Function Definition


{
return a+b;
} //Function Body
Pass by value:

#include<stdio.h>
void swap(int a,int b) //a=10,b=4
{
int temp;
temp=a;
a=b;
b=temp;
} //a=4,b=10
int main()
{
int p=10,q=4;
printf("Before Swapping: p=%d q=%d\n",p,q);
swap(p,q); //Passed by value ==> swap(10,4)
printf("After Swapping: p=%d q=%d",p,q);
return 0;
}

Pass by reference (pass by address/pointer)

#include<stdio.h>
void swap(int *a,int *b) //a=&p, b=&q
{
int temp;
temp=*a; //a=&p, *a=*(&p)=p
*a=*b;
*b=temp;
}
int main()
{
int p=10,q=4;
printf("Before Swapping: p=%d q=%d\n",p,q);
swap(&p,&q); //Passed by reference
printf("After Swapping: p=%d q=%d",p,q);
return 0;
}

Scanf/Printf

Scanf return the number of characters successfully scanned


And print returns the number of characters succesfully printed
#include <stdio.h>
int main()
{
int x;
printf("%d",scanf("%d",&x));
//inner scanf will scan 20 and return 1
//printf("%d",1);
//1

printf("%d",printf("Hello"));
//inner printf will print Hello and return 5
//printf("%d",5);
//Hello5

//1Hello5
return 0;
}

#include <stdio.h>
int main()
{
printf("Hello %s","Hello %s");

//printf("Printable",arguments);
//format specifiers only work in printable statement
//printf("Hello %s"-->printable,"Hello %s"-->argument)
//%s in printable expects a string argument
//Hello %s argument replaces the %s in printable
//printf("Hello Hello %s");
return 0;
}

Recursion

Function calling itself is called recursion.


Main also can be called recursively

Factorial:

#include <stdio.h>
int factorial(int n)
{
if(n<0)
return -1;
else if(n==0)
return 1;
else
return n*factorial(n-1);
}
int main()
{
int n,fact;
printf("Enter a number: ");
scanf("%d",&n);
fact=factorial(n);
printf("\nFactorial of %d is %d",n,fact);
return 0;
}

Fibonacci 0 1 1 2 3 5 8 13 21

n1=0
n2=1
print(n1,n2)
for(i=2;i<n;i++)
n3=n1+n2
print(n3)
n1=n2
n2=n3

Reverse

while(n!=0)
rem=n%10
rev=rev*10+rem
n=n/10

Palindrome

num=n
while(n!=0)
rem=n%10
rev=rev*10+rem
n=n/10
if(num==rev)
It is palindrome
Sum of digits

while(n!=0)
rem=n%10
sum=sum+rem
n=n/10

Leap

if(year%400 == 0)
It is leap year
Else if(year%100==0)
It is not a leap year
Else if(year%4==0)
It is leap year
Else
It is not a leap year

Binary vs Decimal vs Octal vs Hexadecimal

Binary:

128%2 = 0
128/2 = 64

64%2 = 0
64/2 = 32

32%2 = 0
32/2 = 16

16%2 = 0
16/2 = 8

8%2 = 0
8/2 = 4

4%2 = 0
4/2 = 2

2%2 = 0
2/2 = 1

1/2 = 1
1/2 = 0

10000000

1*2pow7+0*2pow6+0*2pow5+0*2pow4+0*2pow3+0*2pow2+0*2pow1+0*2pow0

=128

Octal:

128%8 = 0
128/8 = 16

16%8 = 0
16/8 = 2

2%8 = 2
2/8 = 0

=200

200

2*8pow2+0*8pow1+0*8pow0

=128

Hexadecimal:

128%16 = 0
128/16 = 8

8%16 = 8
8/16 = 0

=80

80

8*16pow1+0*16pow0

=128

Binary to decimal
long long int bin
i=0
while(bin!=0)
rem=bin%10
dec+=rem*pow(2,i)
bin=bin/10
i++

Octal to decimal

int oct
i=0
while(oct!=0)
rem=oct%10
dec+=rem*pow(8,i)
oct=oct/10
i++

Hexadecimal to decimal

int hex
i=0
while(hex!=0)
rem=hex%10
dec+=rem*pow(16,i)
hex=hex/10
i++

Decimal to Binary

int bin[32];
i=0
while(n>0)
bin[i]=n%2
n=n/2
i++
for(j=i;j>=0;j--)
bin[i]

Decimal to Octal

int oct[32];
i=0
while(n>0)
oct[ii]=n%8
n=n/8
i++
for(j=i;j>=0;j--)
oct[i]

Decimal to Hexadecimal

int hex[32];
i=0
while(n>0)
hex[i]=n%16
n=n/16
i++
for(j=i;j>=0;j--)
hex[i]

Arrays:

#include <stdio.h>
void printarray(int a[100],int n)
{
int i;
for(i=0;i<n;i++)
printf("%d ",a[i]);
}
void scanarray(int a[100],int n)
{
int i;
for(i=0;i<n;i++)
scanf("%d",&a[i]);
}
int main()
{
int a[100],n;
printf("\nEnter the number of elements: ");
scanf("%d",&n);
printf("\nEnter the array: ");
scanarray(a,n);
printf("\nEntered array is: ");
printarray(a,n);
return 0;
}
Array name is also a pointer, to the starting location of the array. It can be used as a pointer an
pointers can be used as arrays with index values

int a[3]={1,2,3}

a[0]=1, &a[0]=0x1000
a[1]=2, &a[1]=0x1002
a[2]=3, &a[2]=0x1004

a=&a[0]=0x1000
*a = a[0] = 1

#include<stdio.h>
int main()
{
int a[]={45,62,34,25,21};
int *p;
p=a;
printf("\nAddresses: \n&a[0]=%p\na=%p\np=%p\n",&a[0],a,p);
printf("\nValues: \na[0]=%d\n*a=%d\n*p=%d",a[0],*a,*p);
return 0;
}

Returning an array:

#include<stdio.h>
int* scanarray(int n)
{
static int a[100];
int i;
for(i=0;i<n;i++)
scanf("%d",&a[i]);
return a;
}
int main()
{
int *ptr,n,i;
printf("\nEnter the number of elements: ");
scanf("%d",&n);
printf("\nEnter the array: ");
ptr=scanarray(n);
for(i=0;i<n;i++)
printf("%d ",ptr[i]);
return 0;
}

2D Array

#include<stdio.h>
void scanarray(int a[100][100],int row,int col)
{
int i,j;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
scanf("%d",&a[i][j]);
}
}
void printarray(int a[100][100],int row,int col)
{
int i,j;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
printf("%d ",a[i][j]);
printf("\n");
}
}
int main()
{
int a[100][100],row,col,i;
printf("\nEnter the number of rows: ");
scanf("%d",&row);
printf("\nEnter the number of columns: ");
scanf("%d",&col);
printf("\nEnter the array:\n");
scanarray(a,row,col);
printf("\nEntered array is:\n");
printarray(a,row,col);
return 0;
}

Matrix Addition/Subtraction

For two matrix A (mxn) and B(pxq)


m==p && n==q
#include<stdio.h>
void scanarray(int a[100][100],int row,int col)
{
int i,j;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
scanf("%d",&a[i][j]);
}
}
void printarray(int a[100][100],int row,int col)
{
int i,j;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
printf("%d ",a[i][j]);
printf("\n");
}
}
void matrixaddition(int A[100][100],int B[100][100],int C[100][100],int row, int col)
{
int i,j;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
C[i][j]=A[i][j]+B[i][j];
}
}
int main()
{
int A[100][100],B[100][100],C[100][100],row,col;
printf("\nEnter the number of rows: ");
scanf("%d",&row);
printf("\nEnter the number of columns: ");
scanf("%d",&col);
printf("\nEnter the matrix A:\n");
scanarray(A,row,col);
printf("\nEnter the matrix B:\n");
scanarray(B,row,col);
matrixaddition(A,B,C,row,col);
printf("\nMatrix after addition is:\n");
printarray(C,row,col);
return 0;
}

Matrix Multiplication:

For two matrix A (mxn) and B(pxq)


n==p, resultant matrix C = mxq

4x3 3x2 4x2


A 0 1 2 * B 0 1 = C 0 1
0 2 1 3 0 4 2 0 19 14
1 2 5 4 1 5 1 1 41 21
2 3 2 1 2 2 3 2 24 11
3 1 3 4 3 27 17

Operations

C[0][0]= A[0][0] *B[0][0] + A[0][1] *B[1][0] + A[0][2] *B[2][0] = 2*4 + 1*5 + 3*2 = 19
C[0][1]= A[0][0] *B[0][1] + A[0][1] *B[1][1] + A[0][2] *B[2][1] = 2*2 + 1*1 + 3*3 = 14

C[1][0]= A[1][0] *B[0][0] + A[1][1] *B[1][0] + A[1][2] *B[2][0] = 2*4 + 5*5 + 4*2 = 41
C[1][1]= A[1][0] *B[0][1] + A[1][1] *B[1][1] + A[1][2] *B[2][1] = 2*2 + 5*1 + 4*3 = 21

C[2][0]= A[2][0] *B[0][0] + A[2][1] *B[1][0] + A[2][2] *B[2][0] = 3*4 + 2*5 + 1*2 = 24
C[2][1]= A[2][0] *B[0][1] + A[2][1] *B[1][1] + A[2][2] *B[2][1] = 3*2 + 2*1 + 1*3 = 11

C[3][0]= A[3][0] *B[0][0] + A[3][1] *B[1][0] + A[3][2] *B[2][0] = 1*4 + 3*5 + 4*2 = 27
C[3][1]= A[3][0] *B[0][1] + A[3][1] *B[1][1] + A[3][2] *B[2][1] = 1*2 + 3*1 + 4*3 = 17

Logic: i=4 loops =rowA, j=2 loops =colB, k=3 loops =colA =rowB

i=0 C[0][0]= A[0][0] *B[0][0] + A[0][1] *B[1][0] + A[0][2] *B[2][0]


j=0,1 C[0][1]= A[0][0] *B[0][1] + A[0][1] *B[1][1] + A[0][2] *B[2][1]
k=0,1,2 C[i][j] A[i][k] *B[k][j] A[i][k] *B[k][j] A[i][k] *B[k][j]
i=1 C[1][0]= A[1][0] *B[0][0] + A[1][1] *B[1][0] + A[1][2] *B[2][0]
j=0,1 C[1][1]= A[1][0] *B[0][1] + A[1][1] *B[1][1] + A[1][2] *B[2][1]
k=0,1,2 C[i][j] A[i][k] *B[k][j] A[i][k] *B[k][j] A[i][k] *B[k][j]
i=2 C[2][0]= A[2][0] *B[0][0] + A[2][1] *B[1][0] + A[2][2] *B[2][0]
j=0,1 C[2][1]= A[2][0] *B[0][1] + A[2][1] *B[1][1] + A[2][2] *B[2][1]
k=0,1,2 C[i][j] A[i][k] *B[k][j] A[i][k] *B[k][j] A[i][k] *B[k][j]
i=3 C[3][0]= A[3][0] *B[0][0] + A[3][1] *B[1][0] + A[3][2] *B[2][0]
j=0,1 C[3][1]= A[3][0] *B[0][1] + A[3][1] *B[1][1] + A[3][2] *B[2][1]

Program:

#include<stdio.h>
void scanarray(int arr[][100],int row,int col)
{
int i,j;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
scanf("%d",&arr[i][j]);
}
}
void printarray(int arr[][100],int row,int col)
{
int i,j;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
printf("%d ",arr[i][j]);
printf("\n");
}
}
void multiplymatrix(int A[][100],int B[][100],int C[][100],int rowA,int colA,int rowB,int colB)
{
int i,j,k;
for(i=0;i<rowA;i++)
{
for(j=0;j<colB;j++)
{
C[i][j]=0;
for(k=0;k<colA;k++)
C[i][j]+=A[i][k]*B[k][j];
}
}
}
int main()
{
int i,j,rowA,colA,rowB,colB;
int A[100][100],B[100][100],C[100][100];
printf("\nEnter the rows for matrix A: ");
scanf("%d",&rowA);
printf("\nEnter the columns for matrix A: ");
scanf("%d",&colA);
printf("\nEnter the matrix A:\n");
scanarray(A,rowA,colA);
printf("\nEnter the rows for matrix B: ");
scanf("%d",&rowB);
printf("\nEnter the columns for matrix B: ");
scanf("%d",&colB);
printf("\nEnter the matrix B:\n");
scanarray(B,rowB,colB);
if(colA!=rowB)
{
printf("\nError! Not compatible for multiplication.\n");
return 0;
}
multiplymatrix(A,B,C,rowA,colA,rowB,colB);
printf("\nThe resultant matrix C is:\n");
printarray(C,rowA,colB);
return 0;
}

Transpose of a Matrix:

A 0 1 2 Transpose A 0 1 2 3
0 8 4 3 0 8 12 6 1
1 12 15 18 1 4 15 9 7
2 6 9 25 2 3 18 25 21
3 1 7 21

#include<stdio.h>
void scanarray(int arr[][100],int row,int col)
{
int i,j;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
scanf("%d",&arr[i][j]);
}
}
void printarray(int arr[][100],int row,int col)
{
int i,j;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
printf("%d ",arr[i][j]);
printf("\n");
}
}
void transposematrix(int A[][100],int row,int col)
{
int i,j;
for(i=0;i<col;i++)
{
for(j=0;j<row;j++)
printf("%d ",A[j][i]);
printf("\n");
}
}
int main()
{
int i,j,row,col;
int A[100][100];
printf("\nEnter the rows for matrix: ");
scanf("%d",&row);
printf("\nEnter the columns for matrix: ");
scanf("%d",&col);
printf("\nEnter the matrix:\n");
scanarray(A,row,col);
printf("\nThe entered matrix is:\n");
printarray(A,row,col);
printf("\nThe transpose of matrix is:\n");
transposematrix(A,row,col);
return 0;
}

Find the diagonals of a given matrix:

A 0 1 2 3 4
0 0,0 0,4
1 1,1 1,3
2 2,2
3 3,1 3,3

4 4,0 4,4

#include<stdio.h>
void scanarray(int arr[][100],int n)
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
scanf("%d",&arr[i][j]);
}
}
void printarray(int arr[][100],int n)
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
printf("%d ",arr[i][j]);
printf("\n");
}
}
void diagonalsofmatrix(int A[][100],int n)
{
int i,j;
printf("\nUpper Diagonal: ");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(i==j)
printf("%d ",A[i][j]);
}
}
printf("\nLower Diagonal: ");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(i+j==n-1)
printf("%d ",A[j][i]);
}
}
}
int main()
{
int i,j,n;
int A[100][100];
printf("\nEnter the size of matrix: ");
scanf("%d",&n);
printf("\nEnter the matrix:\n");
scanarray(A,n);
printf("\nThe entered matrix is:\n");
printarray(A,n);
printf("\nThe diagonals of matrix are:\n");
diagonalsofmatrix(A,n);
return 0;
}

Print the sums of each row and column:

#include<stdio.h>
void scanarray(int arr[][100],int row,int col)
{
int i,j;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
scanf("%d",&arr[i][j]);
}
}
void printarray(int arr[][100],int row,int col)
{
int i,j;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
printf("%d ",arr[i][j]);
printf("\n");
}
}
void sumrowcolofmatrix(int A[][100],int row,int col)
{
int i,j,rowsum,colsum;
for(i=0;i<row;i++)
{
rowsum=0;
for(j=0;j<col;j++)
rowsum+=A[i][j];
printf("\nSum of row %d is %d ",i,rowsum);
}
for(i=0;i<col;i++)
{
colsum=0;
for(j=0;j<row;j++)
colsum+=A[j][i];
printf("\nSum of column %d is %d ",i,colsum);
}
}
int main()
{
int i,j,row,col;
int A[100][100];
printf("\nEnter the rows of matrix: ");
scanf("%d",&row);
printf("\nEnter the columns of matrix: ");
scanf("%d",&col);
printf("\nEnter the matrix:\n");
scanarray(A,row,col);
printf("\nThe entered matrix is:\n");
printarray(A,row,col);
printf("\nThe sums of each row and column in matrix are:\n");
sumrowcolofmatrix(A,row,col);
return 0;
}

Strings:

Declaration:

char str1[]={'H','e','l','l','o','\0'};
char str2[]="Hello";
char *str3="Hello";

Scanning and Printing a string:

#include<stdio.h>
int main()
{
char str[100];
printf("\nEnter a string: ");
gets(str);
printf("\nEntered string is: ");
puts(str);
return 0;
}

String functions:

#include<stdio.h>
#include<string.h>
int main()
{
char str1[100],str2[100];
int cmp;
printf("\nEnter string1: ");
gets(str1);
printf("\nEnter string2: ");
gets(str2);
if(strlen(str1)==strlen(str2))
printf("\nLengths are equal %d %d\n",strlen(str1),strlen(str2));
cmp=strcmp(str1,str2);
printf("Comparison: %d\n",cmp);
strcat(str1,str2);
printf("Concatenation: %s %s\n",str1,str2);
strcpy(str1,str2);
printf("Copy: %s %s\n",str1,str2);
return 0;
}

Output:

Enter string1: Hello

Enter string2: World

Lengths are equal 5 5


Comparison: -15
Concatenation: HelloWorld World
Copy: World World

String is a 1D character array terminated by a null character


#include<stdio.h>
int main()
{
char ch[]={'H','e','l','l','o','\0'};
printf("%s",ch);
return 0;
}
Character Array will not have null at the end. String will have the null.

String constant:

String constants are enclosed in double quotes “ “ without null character at end, as the compiler
automatically adds the null character for a string constant.

#include<stdio.h>
int main()
{
char ch[]="Hello";
printf("%s",ch);
return 0;
}

String using char pointer:

#include<stdio.h>
int main()
{
char *ch="Hello";
printf("%s",ch);
return 0;
}

We can create a string either using a character array or using a character pointer. String
constants created using character pointers are stored in a data segment.

#include<stdio.h>
char* getString()
{
char str[] = "Will I be printed?";
return str;
}
int main()
{
printf("%s", getString());
return 0;
}

Output: (null)

#include<stdio.h>
char* getString()
{
char* str = "Will I be printed?";
return str;
}
int main()
{
printf("%s", getString());
return 0;
}

Output: “Will I be printed?”

Character Handling Functions:


<ctype.h>

Works only on a single character

toupper() - converts to uppercase

tolower() - converts to lowercase

islower() - check if lowercase

isupper() - check if uppercase

isalnum() - checks if alphanumeric character

isalpha() - check if alphabet character

isdigit() - check if numeric value, digit

isspace() - check if it is a space

isblank() - check if it is a blank character


Example
:
#include<stdio.h>
#include<ctype.h>
int main()
{
char ch,res;
ch='a';
res=toupper(ch); //converts to uppercase
printf("toupper(%c): %c\n",ch,res);
if(isupper(res))
printf("%c is uppercase\n",res);
res=tolower(ch); //converts to lowercase
printf("tolower(%c): %c\n",ch,res);
if(islower(res))
printf("%c is lowercase\n",res);
ch='A';
res='9';
if(isalnum(ch)&&isalnum(res))
printf("%c and %c are alphanumeric\n",ch,res);
if(isalpha(ch))
printf("%c is alphabet\n",ch);
if(isdigit(res))
printf("%c is numeric\n",res);
res=' ';
ch=' ';
if(isspace(res)&&isblank(ch))
printf("%c and %c are spaces and blanks\n",ch,res);
return 0;
}

Write a program to count the number of uppercase, lowercase alphabets, digits, spaces
and special characters in a given input string:

#include<stdio.h>
#include<string.h>
#include<ctype.h>
int main()
{
char s[50];
int i,upper=0,lower=0,digit=0,space=0,special=0;
char ch;
printf("Enter a string: ");
gets(s);
for(i=0;i<strlen(s);i++)
{
ch=s[i];
if(isalpha(ch))
{
if(isupper(ch))
upper++;
else
lower++;
}
else if(isdigit(ch))
digit++;
else if(isblank(ch)||isspace(ch))
space++;
else
special++;
}
printf("Count of Uppercase: %d\n",upper);
printf("Count of Lowercase: %d\n",lower);
printf("Count of Digits: %d\n",digit);
printf("Count of Spaces: %d\n",space);
printf("Count of Special Characters: %d\n",special);
return 0;
}

Convert a string into uppercase:

#include<ctype.h>
#include<string.h>
#include<stdio.h>
int main()
{
char s[100];
char ch;
int i;
printf("\nEnter a String: ");
gets(s);
for(i=0;i<strlen(s);i++)
{
ch=s[i];
if(islower(ch))
s[i]=toupper(ch);
}
printf("\nString in UPPERCASE: %s",s);
}

Convert a string into lowercase

#include<ctype.h>
#include<string.h>
#include<stdio.h>
int main()
{
char s[100];
char ch;
int i;
printf("\nEnter a String: ");
gets(s);
for(i=0;i<strlen(s);i++)
{
ch=s[i];
if(isupper(ch))
s[i]=tolower(ch);
}
printf("\nString in lowercase: %s",s);
}

Print the reverse of a string:

#include<ctype.h>
#include<string.h>
#include<stdio.h>
int main()
{
char s[100],p[100];
int i,n,j;
printf("\nEnter a String: ");
gets(s);
n=strlen(s);
for(i=n-1,j=0;i>=0;i--,j++)
{
p[j]=s[i];
}
p[j]='\0';
printf("\nReverse of string %s: %s",s,p);
}

Reverse the cases of a string:


#include<ctype.h>
#include<string.h>
#include<stdio.h>
int main()
{
char s[100];
char ch;
int i;
printf("\nEnter a String: ");
gets(s);
for(i=0;i<strlen(s);i++)
{
ch=s[i];
if(isupper(ch))
s[i]=tolower(ch);
if(islower(ch))
s[i]=toupper(ch);
}
printf("\nString in lowercase: %s",s);
}

String Program to check if a given string is palindrome or not

#include<stdio.h>
#include<string.h>
#include<ctype.h>
int main()
{
char s[50];
int n,i,j,flag=0;
printf("Enter a string: ");
gets(s);
n=strlen(s);
for(i=0,j=n-1;i<n&&j>=0;i++,j--)
{
if(toupper(s[i])!=toupper(s[j]))
{
flag=1;
break;
}
}
if(flag==0)
printf("String is Palindrome");
else
printf("String is not Palindrome");
return 0;
}

Structure & Union

#include<stdio.h>
struct student {
int id;
float cgpa;
};
int main()
{
struct student s1,*s2;
s1.id=1123;
s1.cgpa=4.5;
s2->id=1453;
s2->cgpa=7.6;
printf("Student 1:\nID: %d\nCGPA: %0.2f\n",s1.id,s1.cgpa);
printf("Student 2:\nID: %d\nCGPA: %0.2f\n",s2->id,s2->cgpa);
return 0;
}

#include<stdio.h>
union student {
int id;
float cgpa;
};
int main()
{
union student s;
s.id=1005;
s.cgpa=7.6; //Will replace s.id
printf("Student:");
printf("\nID: %d",s.id);
printf("\nCGPA: %0.2f\n",s.cgpa);
return 0;
}
Pointers:
Variable that holds addresses instead of values.

int a=56;
int *p;
p=&a;

int *p
int a=56; & - address Gives address of a given value
p=&a

*-
int a int *p Gives value at a given address
dereference

56 <------- 0x1000 variable holds value of a datatype

0x1000 0x2000 pointer holds address of a variable

a=56 p=&a=0x1000 *(address)= Value

&a=0x1000 *p=*(&a)=*(0x1000)=56 &(value)= Address

&p=0x2000

#include <stdio.h>
int main()
{
int a=50;
int *p;
p=&a;
printf("%d %d %p %p",a,*p,&a,p);
return 0;
}

Summary:
*p=a=50
p=&a=0x100

Pointer Methodologies

1. Cannot assign a value/variable to a pointer

2. Can assign address of a value/variable


3. Can assign another pointer to a pointer

4. Dereference operator(*) can only be used with pointers

5. Pointers hold addresses hence * gives the value at address pointed by pointer

6. Array name is also a pointer to the starting location

7. Since pointers hold address, they are used as pass by reference in functions

8. Pointers can be incremented or decremented with ++ --

Incrementing a pointer points to the next location

Decrementing a pointer points to the previous location

9. Pointers can be added or subtracted with an integer only, need to be assigned

Adding or subtracting an integer moves the pointer that many locations ahead or behind

10. Two pointers can be subtracted

This returns the number of locations between them

11. Two pointers can be compared using relational operators

This helps us understand which pointer is at lower address

12. No other operators can be used with pointers

Pointers and arrays:

#include <stdio.h>
int main()
{
int a[]={1,2,3,4,5};
int *p;
p=a;
printf("%p %p %p",p,a,&a[0]);
return 0;
}

Array as a pointer:
0 1 2 3

0x100 0x102 0x104 0x106

a ==> 12 45 67 21

a[0] a[1] a[2] a[3]

&a[0]=0x100 &a[1]=0x102 &a[2]=0x104 &a[3]=0x106

a+0=0x100 a+1=0x102 a+2=0x104 a+3=0x106

*(a+0)=12 *(a+1)=45 *(a+2)=67 *(a+3)=21

*(0x100)=12 *(0x102)=45 *(0x104)=67 *(0x106)=21

#include<stdio.h>
int main()
{
int a[]={12,45,67,21};
int i;
for(i=0;i<4;i++)
printf("a[%d]=%d\n",i,a[i]);
for(i=0;i<4;i++)
printf("*(a+%d)=%d\n",i,*(a+i));
return 0;

}
Pointers in pass by reference:

#include <stdio.h>
void swap(int* a,int* b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}
int main()
{
int p=10,q=30;
printf("Before Swapping: p=%d q=%d\n",p,q);
swap(&p,&q);
printf("After Swapping: p=%d q=%d\n",p,q);
return 0;
}

Pointer Operations

#include<stdio.h>
int main()
{
int a[]={3,5,1,2,9,11,4,8,6,0,7};
int *p,*s;
p=a;
s=p+8;
printf("Value at p: %d\n",*p);
printf("Value at s: %d\n",*s); //6
p++; //5
s--; //8
printf("Value at p: %d\n",*p); //5
printf("Value at s: %d\n",*s); //8
p+4; //No change
s-1; //No change
printf("Value at p: %d\n",*p); //5
printf("Value at s: %d\n",*s); //8
if(s>p)
printf("Items between s and p: %ld\n",s-p); //6
else
printf("Items between s and p: %ld\n",p-s);
return 0;
}

Pointers can be used with

1. Variables

2. Arrays

3. Structures

4. Functions
5. Pointers

6. Files

7. Constants

Pointer with Structure:

#include<stdio.h>
struct student {
int id;
float cgpa;
};
int main()
{
struct student s;
struct student *p;
s.id=12;
s.cgpa=8.1;
p->id=15;
p->cgpa=9.2;
printf("Student 1:\nID: %d\nCGPA: %f\n",s.id,s.cgpa);
printf("Student 2:\nID: %d\nCGPA: %f\n",p->id,p->cgpa);
return 0;
}

Pointer to a function:

#include<stdio.h>
int addition(int a,int b)
{
return a+b;
}
int subtraction(int a,int b)
{
return a-b;
}
int main()
{
int p,q,result;
int (*ptr)();
printf("\nEnter two numbers: ");
scanf("%d %d",&p,&q);
ptr=&addition; //*ptr=addition
result=(*ptr)(p,q); //adition(p,q)
printf("\nAddition of %d and %d is %d\n",p,q,result);
ptr=&subtraction;
result=(*ptr)(p,q);
printf("\nSubtraction of %d and %d is %d\n",p,q,result);
return 0;
}

Pointer to a pointer:

int a=50; Variable

int *p Pointer

int **pp Pointer to Pointer

p=&a Address of a

pp=&p Address of p

int a int *p int **pp

50 <===== 0x1000 <====== 0x2000

0x1000 0x2000 0x3000

a=50 p=&a=0x1000 pp=&p=0x2000

&a=0x1000 *p=*(&a)=*(0x1000)=50 *pp=*(&p)=p=&a=0x1000

&p=0x2000 **pp=*(*(&p))=*p=*(&a)=a=50

*(&p)=*(0x2000)=0x1000=&a &pp=0x3000
#include<stdio.h>
int main()
{
int a=100;
int *p;
int **pp;
p=&a;
pp=&p;
printf("\nValues: %d %d %d\n",a,*p,**pp);
printf("\nAddress of a: %p %p %p\n",&a, p,*pp);
printf("\nAddress of p: %p %p\n",&p,pp);
printf("\nAddress of pp: %p\n",&pp);
return 0;
}

Pointer to a Constant
(When you don’t allow original value to be modified through pointer)

#include<stdio.h>
int main()
{
int a=100,b=200;
const int* ptr; //Pointer to Constant,*ptr becomes constant
ptr=&b; //*ptr becomes constant
printf("Value at ptr: %d",*ptr);
ptr=&a; //*ptr becomes constant
printf("Value at ptr: %d",*ptr);
return 0;
}
Const Pointer
(When you don’t allow pointer to be reassigned)

#include<stdio.h>
int main()
{
int a=100,b=200;
int* const ptr=&b; //Constant Pointer, ptr becomes constant, has to be assigned here
only
printf("Value at ptr: %d",*ptr);
return 0;
}

#include<stdio.h>
int main()
{
int a=100,b=200;
const int* ptr1; //Pointer to Constant, *ptr1 will be constant, can be reassigned
int* const ptr2=&b; //Constant Pointer, ptr2 will be constant, value can be changed
ptr1=&a; //Can be assigned to any variable
printf("Value at ptr1: %d\n",*ptr1);
ptr1=&b; //Can be assigned to any variable
printf("Value at ptr1: %d\n",*ptr1);
//*ptr1=300; Error, cannot modify *ptr1
printf("Value at ptr2: %d\n",*ptr2);
*ptr2=500;
printf("Value at ptr2: %d\n",*ptr2);
//ptr2=&a; Error, cannot reassign ptr2
return 0;
}
Null Pointer
(All pointers should be initialized to NULL before using them)

#include<stdio.h>
int main()
{
int a=100,b=200;
int *p=NULL;
printf("%d %d\n",a,b);
p=&a;
printf("%d ",*p);
p=&b;
printf("%d ",*p);
return 0;
}

Dangling Pointer
(Pointer which is pointing to a deallocated memory)

#include<stdio.h>
int* func()
{
int a=35;
int *p;
p=&a;
return p;
}
int main()
{
int *p;
p=func();
printf("\nThe value at p is: %d",*p);
return 0;
}

Void Pointer

#include<stdio.h>
int main()
{
int i=9;
void *ptr;
int *p;
float *fp;
p=fp; //assign float pointer to int point - error
fp=&i; //assign int variable address to float pointer - error
ptr=p; //assign int pointer to void pointer
ptr=fp; //assign float pointer to void pointer
ptr=&i; //assign int variable address to void pointer
}
Different pointer types:

#include<stdio.h>
int main()
{
int i=5,*p;
float f=3.4,*fp;
double d=4.56,*dp;
p=&i;
fp=&f;
dp=&d;
printf("%p %p %d\n%p %p %f\n%p %p %lf\n",&i, p,*p, &f, fp,*fp, &d, dp,*dp);
return 0;
}

Accessing value through void pointer

#include<stdio.h>
int main()
{
int i=5; //0x1000
float f=3.4; //0x2000
double d=4.56; //0x3000
void *ptr;
ptr=&i; //ptr doesn't know i is of int type
printf("%p %p %d\n",&i,ptr,*(int*)ptr);
ptr=&f; //ptr doesn't know f is of float type
printf("%p %p %f\n",&f,ptr,*(float*)ptr);
ptr=&d; //ptr doesn't know d is of double type
printf("%p %p %lf\n",&d,ptr,*(double*)ptr);
return 0;
}

Pointers and Increment/Decrement and Dereference:

Operator Precedence Associativity

post ++ Highest Left to Right


pre ++ Right to Left
Equal
dereference * Right to Left

assignment = Lowest Right to Left

Code:
int a[]={12,45,67,21}
int *p;
p=a;
*p++;
*++p;
++*p

*p++:
0x100 0x102 0x104 0x106
a===> 12 45 67 21
|| ||
p p

*p++
= *(p++)
= *(p), p=p+1
= *(0x101),p=0x102
= 12

*++p:
0x100 0x102 0x104 0x106

a===> 12 45 67 21

|| ||

p p
*++p

= *(++p)

= p=p+1,*(p)

= p=0x104,*(0x104)

= 67

++*p:

0x100 0x102 0x104 0x106

a===> 12 45 67 21

a===> 12 45 68 21

||

++*p

= ++(*p)

= ++(*0x104)

= ++(67)

= 68

Program:
#include<stdio.h>
int main()
{
int a[]={12,45,67,21},i;
int *p;
p=a;
printf("*p=%d\n",*p);
printf("*p++=%d\n",*p++);
printf("*p=%d\n",*p);
printf("*++p=%d\n",*++p);
printf("++*p=%d\n",++*p);
printf("*p=%d\n",*p);
for(i=0;i<4;i++)
printf("%d ",a[i]);
return 0;
}
*p=12
*p++=12
*p=45
*++p=67
++*p=68
*p=68
12 45 68 21

Dynamic Memory Allocation:

Static Memory:
#include<stdio.h>
int main()
{
int a[10],n,i;
printf("\nEnter the number of elements: ");
scanf("%d",&n);
printf("\nEnter the array: ");
for(i=0;i<n;i++)
scanf("%d",a+i);
printf("\nEntered array is: ");
for(i=0;i<n;i++)
printf("%d ",*(a+i));
return 0;
}

If the n value is lesser than 10, memory is wasted, if it greater than 10, we cannot
allocate the number of elements plus compiler knows at compilation time that the max
memory for array a should be 10.

Dynamic memory allocation - malloc(), calloc(), realloc() and free() -> stdlib.h
These functions return void pointers to the allocated memory, need to be typecast
ptr=(typecast*)malloc(bytesize);
ptr=(int*)malloc(50); //50 bytes of int

//calloc initializes everything to 0


ptr=(typecast*)calloc(bytesize);
ptr=(int*)calloc(5,10); //50 bytes of int

free(ptr)
//freeing the dynamically allocated memory

#include<stdio.h>
#include<stdlib.h>
int main()
{
int *a,n,i;
printf("\nEnter the number of elements: ");
scanf("%d",&n);
a=(int*)malloc(n*sizeof(int));
printf("\nEnter the array: ");
for(i=0;i<n;i++)
scanf("%d",a+i);
printf("\nEntered array is: ");
for(i=0;i<n;i++)
printf("%d ",*(a+i));
return 0;
}

You might also like