Unit 4
Unit 4
CHENNAI.
⚫ Formal Parameters:
within the function body
void add(int a[])
{
....
}
int a[] - is a formal parameter, since it is a on dimensional
array size doesn’t matter.
Formal and Actual Parameters
Two-Dimensional Array
⚫ Actual Parameters:
int a[10][10];
Function call:
add(a);
here,
a is the base address of the array ‘a’ b is
the base address of the array ‘b’ add is
the function
Formal and Actual Parameters One-
Dimensional Array
⚫ Formal Parameters:
within the function
body void add(int a[]
[10])
{
....
}
int a[][10] - is a formal parameter, the first
dimension is omitted only column value is taken
into the account.
Passing Single element
⚫ Example
int a[5]={0,1,2,3,4};
Function call:
add(a[1
]); Here,
add is the function name,
a[1] is the second element of the array, value 1 is
passed to the array.
Adding Constant five to the given array
using functions(One-Dimensional)
⚫Main Function
int main()
{
int a[50],i,n;
scanf(“%d”,&n);
for(i=0;i<n;i++)
scanf(“%d”,
&a[i]);
add(a,n);
for(i=1;i<=n;i++)
printf(“%d\
n”,a[i]);
return 0;
}
Adding Constant five to the given array
using functions(One-Dimensional)
⚫Add Function:
void add(int a[],int n)
{
int r;
for(r=0;r<n;r++)
{
a[r]=a[r]+5;
}
}
Oututput
⚫ Input:
5
2 4 6 8 10
⚫ Output:
7
9
11
13
15
Main
Function
int main()
{
int num[2][2], i, j;
printf("Enter 4
numbers:\n"); for (i =
0; i < 2; ++i)
{
for (j = 0; j < 2; ++j)
{
scanf("%d", &num[i][j]);
}
}
// passing multi-dimensional array to
displayNumbers function
displayNumbers(num);
return 0;
}
Display Numbers
Function
void displayNumbers(int num[2][2])
{
// Instead of the above line,
// void displayNumbers(int num[][2])
is also valid int i, j;
printf("Displaying:\n");
for (i = 0; i < 2; ++i)
{
for (j = 0; j < 2; ++j)
{
printf("%d\n", num[i][j]);
}
}
}
The advantages of using functions are:
#include
#define
#undef
#ifdef
#ifndef
#if
#else
#elif
#endif
#error
#pragma
#include
three variants:
#include <file>
• This variant is used for system header files.
• It searches for a file named file in a list of directories
specified by us, then in a standard list of system directories.
#include "file"
⚫ This variant is used for header files of your own program.
⚫ It searches for a file named file first in the current directory, then in
the same directories used for system header files.
⚫The current directory is the directory of the current input file. #include
anything else
⚫ This variant is called a computed #include.
⚫ Any #include directive whose argument does not fit the above two forms
is a computed include.
Macro's (#define)
#define token value There are two types of macros:
1. Object-like Macros
2. Function-like Macros
Object-like Macros
⚫ The object-like macro is an identifier that is replaced by value.
⚫ It is widely used to represent numeric constants.
For example:
#include <stdio.h>
#define PI 3.1415
main()
{
printf("%f",PI);
}
Output:
3.14000
Function-like Macros
• The function-like macro looks like function call.
• For example:#define MIN(a,b) ((a)<(b)?(a):(b))
•Here, MIN is the macro name.
#include <stdio.h>
#define MIN(a,b) ((a)<(b)?(a):(b))
void main()
{
printf("Minimum between 10 and 20 is: %d\n",
MIN(10,20));
}
Output:
Minimum between 10 and 20 is: 10
#undef
⚫ To undefine a macro means to cancel its definition. This is done with
the #undef directive.
Syntax:
#undef token
define and undefine example #include
<stdio.h>
#define PI 3.1415
#undef PI
main()
{ printf("%f",PI); }
Output
Compile Time Error: 'PI' undeclared
#ifdef
The #ifdef preprocessor directive checks if macro is defined by
#define.
If yes, it executes the code.
Syntax:
#ifdef MACRO //code #endif
#ifndef
The #ifndef preprocessor directive checks if macro is not defined by
#define. If yes, it executes the code.
Syntax:
#ifndef MACRO //code #endif
#if
The #if preprocessor directive evaluates the expression or condition. If condition
is true, it executes the code.
Syntax:
#if expression //code #endif
#else
The #else preprocessor directive evaluates the expression or condition if condition of
#if is false. It can be used
with #if, #elif, #ifdef and #ifndef
directives.
Syntax:
#if expression //if code #else //else code #endif
Syntax with #elif
#if expression //if code #elif expression //elif code #else
//else code #endif
Example
#include <stdio.h>
#include <conio.h>
#define NUMBER 1
void main()
{
#if NUMBER==0
printf("Value of Number is: %d",NUMBER);
#else print("Value of Number is non-zero");
#endif getch();
}
Output
Value of Number is non-zero
#error
⚫ The #error preprocessor directive indicates error.
⚫ The compiler gives fatal error if #error directive is found and
skips further compilation process.
C #error example
#include<stdio.h> #ifndef
MATH_H
#error First include then compile #else
void main(){
float a; a=sqrt(7);
printf("%f",a);
}
#endif
#pragma
⚫ The #pragma preprocessor directive is used to
provide additional information to the compiler.
⚫ The #pragma directive is used by the compiler to offer
machine or operating-system feature.
⚫ Different compilers can provide different usage of
#pragma directive.
Syntax:
#pragma token
Example
#include<stdio.h>
#include<conio.h>
void func() ;
#pragma startup func
#pragma exit func
void main()
{
printf("\nI am in main");
Output
getch(); } I am in func
void func(){
I am in
printf("\nI am in func");
main I am
getch();
} in func
Nested Preprocessor Macros
1. These are Macros having Arguments
Output :
Square of 3 : 9
CUBE of 3 : 27
Advantages of Macros
⚫ Time efficiency.
⚫ Not need to pass arguments like
function.
⚫ It's preprocessed.
⚫ Easier to Read
Disadvantages of
Macros
• Very hard to debug in large code.
• Take more memory compare to function
POINTERS
Definition
A pointer is a variable whose value is the
address of another variable, i.e., direct
address of the memory location. This is done
by using unary operator * that returns the
value of the variable located at the address
specified by its operand.
POINTERS
POINTERS
POINTERS
⚫ Syntax
Datatype *pointervariable;
⚫ Syntax Example
int main()
{
int num = 45 , *ptr ,
**ptr2ptr ; ptr =
# //3000
ptr2ptr = &ptr; //4000
printf("%d",**ptr
2ptr); return(0);
}
Output 45
Pointer to Constant
Objects
These type of pointers are the one which cannot
change the value they are pointing to. This means
they cannot change the value of the variable whose
address they are holding.
int* const
ptr=&variable;
(or)
int *const ptr=&variable // ptr is a constant
pointer to int
Constant Pointers
#include <stdio.h>
int main()
{ main.c: In function ‘main’:
main.c:15:8: error: assignment of read-only variable ‘ptr’
15 | ptr=&a;
int a=1; |^
datatype *pointer_variable=0;
datatype
*pointer_variable=NULL;
size of
• pointer
Any type of pointer variable takes the same memory bytes
in the memory, because they are used to store the memory
addresses on other type of variables.
/*C program to print size of different types of pointer variables.*/
#include <stdio.h>
int main()
Output
{ size of char pointer: 4
printf("\nsize of char pointer: %d" ,sizeof(char*)); size of int pointer: 4
size of float pointer: 4
printf("\nsize of int pointer: %d" ,sizeof(int*)); size of long int pointer: 4
size of double pointer: 4
printf("\nsize of float pointer: %d" ,sizeof(float*));
printf("\nsize of long int pointer: %d" ,sizeof(long int*));
printf("\nsize of double pointer: %d\n" ,sizeof(double*));
return 0;
}
Exampl
e
Pointer Arithmetic
⚫C allows you to perform some
arithmetic operations on pointers.
⚫Incrementing a pointer
Incrementing a pointer is one which
increases the number of bytes of its
data type.
int *ptr;
int a[]={1,2,3};
ptr=&a;
ptr++;
ptr=&a;
ptr=ptr+1;
Pointer Arithmetic
⚫Decrementing a Pointer
OUTPUT
3. A void pointer cannot be
dereferenced
Relational operations
⚫A pointer can be compared with a pointer
of same type or zero.
⚫Various relational operators are ==.,!
=,<,<=,>,>=
⚫Ex: float a=1.0,b=2.0,*fptr1,*fptr2;
⚫fptr1=&a;fptr2=&b;
⚫int result;
result=fptr1!=fptr2;
Example
Pointers and Arrays
⚫Pointers and arrays are closely related ,
An array variable is actually just a
pointer to the first element in the array.
⚫Accessing array elements using pointers is
efficient way than using array notation.
⚫When an array is declared, compiler
allocates sufficient amount of memory to
contain all the elements of the array.
⚫Base address i.e address of the first
Pointers and Arrays
Cont…
Suppose we declare an array arr,
int arr[5]={ 1, 2, 3, 4, 5 };Assuming that
the base address of arr is 1000 and each
integer requires two bytes, the five
elements will be stored as follows
Pointers and Arrays
Cont…
⚫ Here variable arr will give the base
address, which is a constant pointer
pointing to the element, arr[0].
⚫Therefore arr is containing the address of
arr[0] i.e 1000. In short, arr has two
purpose- it is the name of an array and it
acts as a pointer pointing towards the first
element in the array.
Pointers and Arrays
Cont…
int
*p; p
= arr;
or
p = &arr[0];
Now we can access every element of array
arr using p++ to move from one
element to another.
Pointers and Arrays
Cont…
⚫ a[0] is the same as *a
⚫a[1] is the same as *(a + 1)
⚫a[2] is the same as *(a + 2)
⚫If pa points to a particular element of an
array, (pa + 1) always points to the next
element, (pa + i) points i elements after pa
and (pa - i) points i elements before.
Example 1
#include<stdio.
h> void main()
{
int a[10],i,n;
printf("Enter
n");
scanf("%d",&n)
;
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<n;i++)
printf("a[%d]=%d\
n",i,*(a+i));
}
Outp
ut
Enter
n5
123
45
a[0]=
1
a[1]=
2
a[2]=
3
a[3]=
Pointer to Multidimensional
⚫Array
A multidimensional array is of form, a[i][j]. Lets see how we
can make a pointer point to such an array.
#define ROWS
4
#define
COLS 3 int
main ()
{
int i,j;
// declare 4x3 array
int matrix[ROWS][COLS] =
{{1, 2, 3},
{4, 5,
6},
{7, 8,
9},
{10, 11,
12}};
for (i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
Outp
ut
1 2 3
4 5 6
7 8 9
10 11 1
2
matrix[0][0] = *(*(matrix))
matrix[i][j] = *((*(matrix)) + (i * COLS + j))
matrix[i][j] = *(*(matrix + i) + j)
matrix[i][j] = *(matrix[i] + j)
matrix[i][j] = (*(matrix + i))[j]
&matrix[i][j] = ((*(matrix)) + (i * COLS + j))
Example 3
&pmat[0][0] = 1
Passing an array to a
function
⚫ Single element of an array can be passed in similar manner as passing
variable to a function
⚫ C program to pass a single element of an array to
function
#include <stdio.h>
void display(int age)
{
printf("%d", age);
}
int main()
{
int ageArray[] = { 2, 3, 4 };
display(ageArray[2]); //Passing array element ageArray[2] only.
return 0;
}
OUTPUT
4
Passing an entire one-dimensional array to a function
#include<stdio.h>
int total(int[],int);
void main()
{
int a[10],n,sum,i;
printf("Enter n\n");
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
sum=total(a,n);
printf("Sum=
%d",sum);
}
int total(int a[],int n)
{
int sum=0,i;
for(i=0;i<n;i++)
sum=sum+a[i
]; return sum;
}
Output
Enter
n
Sum=
15
Passing Multi-dimensional Arrays to
Function
To pass two-dimensional array to a
function as an argument, starting
address of memory area reserved is
passed as in one dimensional array
Example 4
#include <stdio.h> void displayNumbers(int
void displayNumbers(int num[2][2])
{
num[2][2]); int main()
// Instead of the above line,
{ // void displayNumbers(int num[][2]) is
also valid
int num[2][2], i, j;
int i, j;
printf("Enter 4
printf("Displaying:
numbers:\n"); for (i =
\n"); for (i = 0; i <
0; i < 2; ++i)
2; ++i)
for (j = 0; j < 2; ++j)
for (j = 0; j < 2; ++j)
scanf("%d", &num[i] printf("%d\n",
[j]);
num[i][j]);
// passing multi-dimensional array to
displayNumbers function }
displayNumbers(
num); return 0;
}
Outp
ut 4
Enter
numbers:
1
2
3
4
Displayi
ng: 1
2
3
4
Pointers and Strings
⚫Strings as arrays:In C, the abstract idea
of a string is implemented with just an
array of characters. For example, here is
a string:
⚫char label[] = "Single";What this array looks
like in memory is the following:
S i n g l e \0
Pointers and Strings cont...
⚫ where the beginning of the array is at some location in
computer memory, for example, location 1000.
⚫ A character array can have more characters than the
abstract string held in it, as below:
⚫ char label[10] = "Single"; giving an array that looks like:
S i n g l e \0
Output:
Passing Strings
Below is the definition of a function that prints a
label and a call to that function:
void PrintLabel(char the_label[])
{
printf("Label: %s\n", the_label);
}
...
int main(void)
{
char label[] = "Single";
...
PrintLabel(label);
...
}
Passing Strings
Cont...
⚫Since label is a character array, and
the function PrintLabel() expects a
character array, the above makes
sense.
⚫However, if we have a pointer to the
character array label, as in:
char *labelPtr = label;
then we can also pass the pointer to the
function, as in:
⚫PrintLabel(labelPtr);
Array of
⚫Pointers
Pointers are very helpful in handling character
array with rows of varying length.
char *name[3]={ "Adam", "chris", "Deniel" };
//Now see same array without using pointer
char name[3][20]= { "Adam", "chris", "Deniel" };
Example 1
#include
<stdio.h>
#define SIZE 3
int main()
{
char president[SIZE]
[8] = { "Clinton",
"Bush",
"Obama
"
};
int x,index;
for(x=0;x<SIZE;x+
+)
{
index = 0;
while(president[x][index] !=
'\0')
{
putchar(president[x] Output:
[index]);
index++;
}
ClintonnBushnOba
putchar('n');
}
man
return(0);
}
Function Pointers
⚫In C, like normal data pointers (int *, char *,
etc), we can have pointers to functions.
⚫Initialization
return_type
function_pointer(argu)=&function_nam
e void (*fun_ptr)(int) = &fun;
⚫Function Definition
void fun(int a)
{
printf("Value of a is %d\n", a);
}
Exampl
e1
#include<std
io.h> void
fun(int a)
{
printf("a=%d\
n",a);
}
void main()
{ Output:
void (*fun1)
a=15
(int)=&fun;
Function Pointers Cont...
If we remove bracket, then the expression
“void (*fun_ptr)(int)”
becomes
“void *fun_ptr(int)”
which is declaration of a function that returns void pointer.
Interesting facts
⚫ Unlike normal pointers, a function pointer points to code,
not data. Typically a function pointer stores the start of
executable code.
⚫ Unlike normal pointers, we do not allocate de-
allocate memory using function pointers.
⚫ A function’s name can also be used to get functions’
address.
Passing Function Pointer as an
argument
#include<stdio.
h>
void
fun1(void(*test)
())
{
int
a=20;
test(a)
;
}
void
void test(int a)
main() Output:
{
printf("a=%d\
fun1(&te
n",a);
st); a=20
}
Array of Function
Pointer
#include<stdio void main()
.h> void {
add(int a,int b) void (*fun[])
{ (int,int)={add,sub,mul}
;
printf("add=%d\
int ch;
n",a+b); int a,b;
} printf("Enter a and
void sub(int a,int b) b\n"); scanf("%d
{ %d",&a,&b);
printf("sub=%d\ printf("Enter the
n",a-b); operation\n");
} scanf("%d",&
void mul(int a,int b) ch); if(ch>2)
{ printf("Wrong
Input\n"); else
printf("mul=%d\
(*fun[ch])(a,b);
n",a*b); }
}
Output
Enter a
and b 4
5
Enter the
operation 2
mul=20
Structures created and accessed using
pointers
⚫Structures can be created and
accessed using pointers. A pointer
variable of a structure can be created
as below:
struct name
{
member1;
member2;
..
};
int main()
{
struct name *ptr;
}
Here, the pointer variable of type struct
name is created.
Accessing structure's member through
pointer
typedef struct
listnode { void
*data;
struct listnode *next;
Self-Referential Structure Cont...
typedef struct
listnode { void
*data;
struct listnode
*next;
} linked_list;