Bx4002 Unit 4
Bx4002 Unit 4
Bx4002 Unit 4
Department of MCA
BX4002 - Problem Solving and Programming in C
Array
An array is a variable that can store multiple values. For example, if you want to store
100 integers, you can create an array for it.
int data[100];
dataType arrayName[arraySize];
For example,
float mark[5];
Here, we declared an array, mark, of floating-point type. And its size is 5. Meaning, it
can hold 5 floating-point values.
It's important to note that the size and type of an array cannot be changed once it is
declared.
Suppose you declared an array mark as above. The first element is mark[0], the
second element is mark[1] and so on.
1
Declare an Array
Few keynotes:
• Arrays have 0 as the first index, not 1. In this example, mark[0] is the first
element.
• If the size of an array is n, to access the last element, the n-1 index is used. In
this example, mark[4]
• Suppose the starting address of mark[0] is 2120d. Then, the address of the
mark[1] will be 2124d. Similarly, the address of mark[2] will be 2128d and so
on.
This is because the size of a float is 4 bytes.
Here, we haven't specified the size. However, the compiler knows its size is 5 as we
are initializing it with 5 elements.
Initialize an Array
Here,
mark[0] is equal to 19
mark[1] is equal to 10
mark[2] is equal to 8
mark[3] is equal to 17
mark[4] is equal to 9
2
// make the value of the fifth element to 0
mark[4] = 0;
Here's how you can take input from the user and store it in an array element.
// Program to take 5 values from the user and store them in an array// Print the
elements stored in the array#include <stdio.h>
int main() {
int values[5];
Output
Enter 5 integers: 1
-3
34
0
3
Displaying integers: 1
-3
34
3
0
3
Here, we have used a for loop to take 5 inputs from the user and store them in an array.
Then, using another for loop, these elements are displayed on the screen.
average = sum / n;
printf("Average = %d", average);
return 0;
}
Output
Enter n: 5
Enter number1: 45
Enter number2: 35
Enter number3: 38
Enter number4: 31
Enter number5: 49
Average = 39
int testArray[10];
4
Now let's say if you try to access testArray[12]. The element is not available. This
may cause unexpected output (undefined behavior). Sometimes you might get an error
and some other time your program may run correctly.
Hence, you should never access elements of an array outside of its bound.
String is a sequence of characters that are treated as a single data item and terminated
by a null character '\0'. Remember that the C language does not support strings as a
data type. A string is actually a one-dimensional array of characters in C language.
These are often used to create meaningful and readable programs.
For example: The string "home" contains 5 characters including the '\0' character
which is automatically added by the compiler at the end of the string.
But scanf() function, terminates its input on the first white space it encounters.
5
edit set conversion code %[..] that can be used to read a line containing a
variety of characters, including white spaces.
The gets() function can also be used to read character string with white spaces
C language supports a large number of string handling functions that can be used to
carry out many of the string manipulations. These functions are packaged in the
string.h library. Hence, you must include string.h header file in your programs to use
these functions.
The following are the most commonly used string handling functions.
Method Description
strcat() function in C:
Syntax:
strcat("hello", "world");
6
strcat() will add the string "world" to "hello" i.e ouput = helloworld.
strlen() will return the length of the string passed to it and strcmp() will return the
ASCII difference between first unmatching character of two strings.
int j = strlen("studytonight");
int i=strcmp("study ", "tonight");printf("%d %d",j,i);
12 -1
strcpy() function:
#include<stdio.h>#include<string.h>
int main(){
char s1[50], s2[50];
strcpy(s1, "StudyTonight");
strcpy(s2, s1);
printf("%s\n", s2);
return(0);}
StudyTonight
strrev() function:
7
It is used to reverse the given string expression.
#include <stdio.h>
int main(){
char s1[50];
Multidimensional Arrays
In C programming, you can create an array of arrays. These arrays are known as
multidimensional arrays. For example,
float x[3][4];
Here, x is a two-dimensional (2d) array. The array can hold 12 elements. You can
think the array as a table with 3 rows and each row has 4 columns.
8
Two dimensional Array
float y[2][4][3];
Initialization of a 2d array
Initialization of a 3d array
int test[2][3][4] = {
{{3, 4, 2, 3}, {0, -3, 9, 11}, {23, 12, 23, 2}},
{{13, 4, 56, 3}, {5, 9, 3, 5}, {3, 1, 4, 9}}};
9
{
printf("City %d, Day %d: ", i + 1, j + 1);
scanf("%d", &temperature[i][j]);
}
}
printf("\nDisplaying values: \n\n");
Output
City 1, Day 1: 33
City 1, Day 2: 34
City 1, Day 3: 35
City 1, Day 4: 33
City 1, Day 5: 32
City 1, Day 6: 31
City 1, Day 7: 30
City 2, Day 1: 23
City 2, Day 2: 22
City 2, Day 3: 21
City 2, Day 4: 24
City 2, Day 5: 22
City 2, Day 6: 25
City 2, Day 7: 26
Displaying values:
City 1, Day 1 = 33
City 1, Day 2 = 34
City 1, Day 3 = 35
City 1, Day 4 = 33
City 1, Day 5 = 32
City 1, Day 6 = 31
City 1, Day 7 = 30
City 2, Day 1 = 23
City 2, Day 2 = 22
City 2, Day 3 = 21
City 2, Day 4 = 24
City 2, Day 5 = 22
City 2, Day 6 = 25
10
City 2, Day 7 = 26
if (j == 1)
printf("\n");
}
return 0;
}
Output
11
Enter a11: 2;
Enter a12: 0.5;
Enter a21: -1.1;
Enter a22: 2;
Enter elements of 2nd matrix
Enter b11: 0.2;
Enter b12: 0;
Enter b21: 0.23;
Enter b22: 23;
Sum Of Matrix:
2.2 0.5
-0.9 25.0
printf("\nDisplaying values:\n");
for (int i = 0; i < 2; ++i)
{
for (int j = 0; j < 3; ++j)
{
for (int k = 0; k < 2; ++k)
{
printf("test[%d][%d][%d] = %d\n", i, j, k, test[i][j][k]);
}
}
}
return 0;
}
12
Output
Enter 12 values:
1
2
3
4
5
6
7
8
9
10
11
12
Displaying Values:
test[0][0][0] = 1
test[0][0][1] = 2
test[0][1][0] = 3
test[0][1][1] = 4
test[0][2][0] = 5
test[0][2][1] = 6
test[1][0][0] = 7
test[1][0][1] = 8
test[1][1][0] = 9
test[1][1][1] = 10
test[1][2][0] = 11
test[1][2][1] = 12
Arrays of Strings
scanf( ) is the input function with %s format specifier to read a string as input from
the terminal. But the drawback is it terminates as soon as it encounters the space. To
avoid this gets( ) function which can read any number of strings including white
spaces.
Sting is an array of characters terminated with the special character known as the null
character (“\0”).
Syntax
13
Syntax
datatype name_of_the_array[size_of_elements_in_array];
char str_name[size];
Example
Str_name is the string name and the size defines the length of the string (number of
characters).
Syntax
char str_name[size][max];
Syntax
Syntax
From the given syntax there are two subscripts first one is for how many strings to
declare and the second is to define the maximum length of characters that each string
can store including the null character. C concept already explains that each character
takes 1 byte of data while allocating memory, the above example of syntax occupies 2
* 6 =12 bytes of memory.
Example
0 1 2 3 4 5 6 7 Index
Variables 2000 2001 2002 2003 2004 2005 2006 2007 Address
This is a representation of how strings are allocated in memory for the above-declared
string in C.
14
Each character in the string is having an index and address allocated to each character
in the string. In the above representation, the null character (“\0”) is automatically
placed by the C compiler at the end of every string when it initializes the
above-declared array. Usually, strings are declared using double quotes as per the
rules of strings initialization and when the compiler encounters double quotes it
automatically appends null character at the end of the string.
From the above example as we know that the name of the array points to the 0th index
and address 2000 as we already know the indexing of an array starts from 0.
Therefore,
As the above example is for one-dimensional array so the pointer points to each
character of the string.
Example:
#include <stdio.h>
int main()
{
char name[10];
printf("Enter the name: ");
fgets(name, sizeof(name), stdin);
printf("Name is : ");
puts(name);
return 0;
}
Output:
Now for two-dimensional arrays, we have the following syntax and memory
allocation. For this, we can take it as row and column representation (table format).
char str_name[size][max];
In this table representation, each row (first subscript) defines as the number of strings
to be stored and column (second subscript) defines the maximum length of the strings.
15
Alternatively, we can even declare it as
Syntax:
Index
0 1 2 3 4 5 6 7
Rows
0 g o u r i \0 \0 \0
1 r a m \0 \0 \0 \0 \0
From the above example as we know that the name of the array points to the 0th
string. Therefore,
As the above example is for two-dimensional arrays so the pointer points to each
string of the array.
Example:
#include <stdio.h>
int main()
{
int i;
char name[2][8] = {
“gouri”,
“ram”
};
for (i = 0; i < 2; i++)
{
printf(“String = %s \n”, name + i, name + i);
}
return 0;
}
Output:
Functions of strings
16
char s2 [10] = “ram”;
char s3 [10] ;
strcpy(s3,s2);
result => strcpy(s3,s2) : ram
strchr(s1, ch); these functions find the first occurrence of the given character ch in
the string s1 and the pointer points to this character in the string.
strstr(s1,s2); this finds the first occurrence of string s2 in the string s1 and the pointer
points to the string s2 in the string s1.
With some invalid operations are str_arr[0] = “gouri”; in this operation pointer of the
string is assigned to the constant pointer which is invalid and is not possible, because
the name of the array is a constant pointer.
We have successfully learned the basic concepts and different library functions that C
Programming offers. Another interesting concept is the use of 2D character arrays. In
the previous tutorial, we already saw that string is nothing but an array of characters
that ends with a ‘\0’.
2D character arrays are very similar to 2D integer arrays. We store the elements and
perform other operations in a similar manner. A 2D character array is more like a
String array. It allows us to store multiple strings under the same name.
17
2. How to Declaration and Initialization a 2D character array?
char name[5][10];
The order of the subscripts is important during declaration. The first subscript [5]
represents the number of Strings that we want our array to contain and the second
subscript [10] represents the length of each String. This is static memory allocation.
We are giving 5*10=50 memory locations for the array elements to be stored in the
array.
char name[5][10]={
"tree",
"bowl",
"hat",
"mice",
"toon"
};
Let’s see the diagram below to understand how the elements are stored in the memory
location:
The areas marked in green show the memory locations that are reserved for the array
but are not used by the string. Each character occupies 1 byte of storage from the
memory.
In order to take string data input from the user we need to follow the following
syntax:
18
Here we see that the second subscript remains [0]. This is because it shows the length
of the string and before entering any string the length of the string is 0.
The way a 2D character array is printed is not the same as a 2D integer array. This
is because we see that all the spaces in the array are not occupied by the string entered
by the user.
If we display it in the same way as a 2D integer array we will get unnecessary garbage
values in unoccupied spaces. Here is how we can display all the string elements:
This format will print only the string contained in the index numbers specified and
eliminate any garbage values after ‘\0’. All the string library functions that we have
come across in the previous tutorials can be used for the operations on strings
contained in the string array. Each string can be referred to in this form:
name[i][0];
where [i] is the index number of the string that needs to be accessed by library
functions.
Let’s implement a program to search for a string(a char array) entered by the user in
a 2D char array or a string array(also entered by the user):
#include <stdio.h>
#include <string.h>
int main() {
char name[5][10],
item[10]; // declaring the string array and the character
// array that will contain the string to be matched
int i, x, f = 0;
/*taking 5 string inputs*/
printf("Enter 5 strings:\n");
for (i = 0; i < 5; i++)
scanf("%s", &name[i][0]);
/*entering the item to be found in the string array*/
printf("Enter the string to be searched:\n");
scanf("%s", &item);
/*process for finding the item in the string array*/
for (i = 0; i < 5; i++) {
x = strcmp(&name[i][0],
item); // compares the string in the array with the item and if
// match is found returns 0 and stores it in variable x
if (x == 0)
19
f = i;
}
/*if match is not found*/
if (f == 0)
printf("the item does not match any name in the list");
/*If the match is found*/
else
printf("Item Found. Item in the array exists at index - %d", f);
return 0;
}
Output:-
Enter 5 strings:
tree
bowl
hat
mice
toon
Enter the string to be searched:
mice
Item Found. Item in the array exists at index - 3
Functions
Suppose, you need to create a program to create a circle and color it. You can create
two functions to solve this problem:
Dividing a complex problem into smaller chunks makes our program easy to
understand and reuse.
Types of function
20
the stdio.h header file.
Hence, to use the printf() function, we need to include the stdio.h header file
using #include <stdio.h>.
• The sqrt() function calculates the square root of a number. The function is
defined in the math.h header file.
User-defined function
You can also create functions as per your need. Such functions created by the user are
known as user-defined functions.
#include <stdio.h>
void functionName()
{
... .. ...
... .. ...
}
int main()
{
... .. ...
... .. ...
functionName();
... .. ...
... .. ...
}
void functionName()
The control of the program jumps back to the main() function once code inside the
function definition is executed.
21
Working of C Function
This is just an overview of user-defined functions. Visit these pages to learn more on:
22
Parameter passing mechanism scope
When a function gets executed in the program, the execution control is transferred
from calling-function to called function and executes function definition, and finally
comes back to the calling function. When the execution control is transferred from
calling-function to called-function it may carry one or number of data values. These
data values are called as parameters.
Parameters are the data values that are passed from calling function to called function.
• Actual Parameters
• Formal Parameters
The actual parameters are the parameters that are speficified in calling function. The
formal parameters are the parameters that are declared at called function. When a
function gets executed, the copy of actual parameter values are copied into formal
parameters.
In C Programming Language, there are two methods to pass parameters from calling
function to called function and they are as follows...
• Call by Value
• Call by Reference
Call by Value
In call by value parameter passing method, the copy of actual parameter values are
copied to formal parameters and these formal parameters are used in called function.
The changes made on the formal parameters does not effect the values of actual
parameters. That means, after the execution control comes back to the calling
function, the actual parameter values remains same. For example consider the
following program...
Example Program
#include<stdio.h>
#include<conio.h>
void main(){
int num1, num2 ;
void swap(int,int) ; // function declaration
clrscr() ;
num1 = 10 ;
num2 = 20 ;
23
swap(num1, num2) ; // calling function
Output:
In the above example program, the variables num1 and num2 are called actual
parameters and the variables a and b are called formal parameters. The value of num1
is copied into a and the value of num2 is copied into b. The changes made on
variables a and b does not effect the values of num1 and num2.
Call by Reference
In Call by Reference parameter passing method, the memory location address of the
actual parameters is copied to formal parameters. This address is used to access the
memory locations of the actual parameters in called function. In this method of
parameter passing, the formal parameters must be pointer variables.
That means in call by reference parameter passing method, the address of the actual
parameters is passed to the called function and is recieved by the formal parameters
(pointers). Whenever we use these formal parameters in called function, they directly
access the memory locations of actual parameters. So the changes made on the
formal parameters effects the values of actual parameters. For example consider
the following program...
Example Program
#include<stdio.h>
#include<conio.h>
24
void main(){
int num1, num2 ;
void swap(int *,int *) ; // function declaration
clrscr() ;
num1 = 10 ;
num2 = 20 ;
Output:
In the above example program, the addresses of variables num1 and num2 are copied
to pointer variables a and b. The changes made on the pointer variables a and b in
called function effects the values of actual parameters num1 and num2 in calling
function.
25
Storage classes
Storage Classes are used to describe the features of a variable/function. These features
basically include the scope, visibility and life-time which help us to trace the
existence of a particular variable during the runtime of a program.
C language uses 4 storage classes, namely:
1. auto: This is the default storage class for all the variables declared inside a
function or a block. Hence, the keyword auto is rarely used while writing
programs in C language. Auto variables can be only accessed within the
block/function they have been declared and not outside them (which defines
their scope). Of course, these can be accessed within nested blocks within the
parent block/function in which the auto variable was declared. However, they
can be accessed outside their scope as well using the concept of pointers given
here by pointing to the very exact memory location where the variables resides.
They are assigned a garbage value by default whenever they are declared.
2. extern: Extern storage class simply tells us that the variable is defined
elsewhere and not within the same block where it is used. Basically, the value
is assigned to it in a different block and this can be overwritten/changed in a
different block as well. So an extern variable is nothing but a global variable
initialized with a legal value where it is declared in order to be used elsewhere.
It can be accessed within any function/block. Also, a normal global variable
can be made extern as well by placing the ‘extern’ keyword before its
declaration/definition in any function/block. This basically signifies that we
are not initializing a new variable but instead we are using/accessing the
global variable only. The main purpose of using extern variables is that they
can be accessed between two different files which are part of a large
program.
3. static: This storage class is used to declare static variables which are popularly
used while writing programs in C language. Static variables have a property of
preserving their value even after they are out of their scope! Hence, static
26
variables preserve the value of their last use in their scope. So we can say that
they are initialized only once and exist till the termination of the program.
Thus, no new memory is allocated because they are not re-declared. Their
scope is local to the function to which they were defined. Global static
variables can be accessed anywhere in the program. By default, they are
assigned the value 0 by the compiler.
4. register: This storage class declares register variables which have the same
functionality as that of the auto variables. The only difference is that the
compiler tries to store these variables in the register of the microprocessor if a
free register is available. This makes the use of register variables to be much
faster than that of the variables stored in the memory during the runtime of the
program. If a free register is not available, these are then stored in the memory
only. Usually few variables which are to be accessed very frequently in a
program are declared with the register keyword which improves the running
time of the program. An important and interesting point to be noted here is
that we cannot obtain the address of a register variable using pointers.
To specify the storage class for a variable, the following syntax is to be followed:
Syntax:
Functions follow the same syntax as given above for variables. Have a look at the
following C example for further clarification :
27
printf("--------------------------------");
}
void registerStorageClass()
{
printf("\nDemonstrating register class\n\n");
// declaring a register variable
register char b = 'G';
// printing the register variable 'b'
printf("Value of the variable 'b'"
" declared as register: %d\n",
b);
printf("--------------------------------");
}
void externStorageClass()
{
printf("\nDemonstrating extern class\n\n");
// telling the compiler that the variable
// x is an extern variable and has been
// defined elsewhere (above the main
// function)
extern int x;
// printing the extern variables 'x'
printf("Value of the variable 'x'"
" declared as extern: %d\n",
x);
// value of extern variable x modified
x = 2;
// printing the modified values of
// extern variables 'x'
printf("Modified value of the variable 'x'"
" declared as extern: %d\n",
x);
printf("--------------------------------");
}
28
void staticStorageClass()
{
int i = 0;
printf("\nDemonstrating static class\n\n");
// using a static variable 'y'
printf("Declaring 'y' as static inside the loop.\n"
"But this declaration will occur only"
" once as 'y' is static.\n"
"If not, then every time the value of 'y' "
"will be the declared value 5"
" as in the case of variable 'p'\n");
printf("\nLoop started:\n");
for (i = 1; i < 5; i++) {
// Declaring the static variable 'y'
static int y = 5;
// Declare a non-static variable 'p'
int p = 10;
// Incrementing the value of y and p by 1
y++;
p++;
// printing value of y at each iteration
printf("\nThe value of 'y', "
"declared as static, in %d "
"iteration is %d\n",
i, y);
// printing value of p at each iteration
printf("The value of non-static variable 'p', "
"in %d iteration is %d\n",
i, p);
}
printf("\nLoop ended:\n");
printf("--------------------------------");
}
29
int main()
{
printf("A program to demonstrate"
" Storage Classes in C\n\n");
// To demonstrate auto Storage Class
autoStorageClass();
// To demonstrate register Storage Class
registerStorageClass();
// To demonstrate extern Storage Class
externStorageClass();
// To demonstrate static Storage Class
staticStorageClass();
// exiting
printf("\n\nStorage Classes demonstrated");
return 0;
}
Output:
30
The value of non-static variable ‘p’, in 4 iteration is 11
Loop ended:
——————————–
Storage Classes demonstrated
Recursion
The C programming language offers various features which help the programmers in
making their code efficient and simple. In C, Recursion is one of the most complex
and useful concepts.
With the help of recursion, you can solve complex mathematical problems such as
factorial of a number and generating fibonacci series etc.
Recursion in C
In C, When a function calls a copy of itself then the process is known as Recursion.
To put it short, when a function calls itself then this technique is known as Recursion.
And the function is known as a recursive function.
You have to be more careful when you are using recursion in your program. You just
cannot use recursion in all your problems because it will make your program more
complex and difficult.
Recursion can be used in case of similar subtasks like sorting, searching, and traversal
problems. While using recursion, you will have to define an exit condition on that
function, if not then it will go into an infinite loop.
NOTE:- Problems that can be solved recursively, can also be solved iteratively.
void do_recursion()
{
... .. ...
do_recursion();
... .. ...
}
int main()
{
... .. ...
do_recursion();
... .. ...
}
31
Working of recursion in C:-
The recursion will go in an infinite loop until some condition is met. So, to prevent it
from going into an infinite loop, you can make use of the if…else statement or define
an exit condition in the recursive function.
#include<stdio.h>
int main()
{
printf("TechVidvan Tutorial: Infinite loop through Recursive Function!\n");
main();
return 0;
}
32
The above example will result in an infinite loop. In the above program, we are doing
recursion by calling main() from main(). And also we have not provided any
condition for the program to exit. That’s why it will print the output infinitely.
Types of recursion in C
• Direct Recursion
• Indirect Recursion
1. Direct Recursion in C
If a function calls itself directly then the function is known as direct recursive
function.
In the above example, fib() function is direct recursive. Because the statements inside
the fib() function calls the fib() function directly.
2. Indirect Recursion in C
A function that does not call itself directly then function is known as an indirect
recursive function.
33
In the above example, first_function() calls the new_function(), which is indeed a new
function. Then this new_function() calls the first_function(). So, it is an indirect
recursive function.
#include <stdio.h>
int factorial(int);
int main()
{
int num=5,fact;
printf("TechVidvan Tutorial: Factorial of a number using recursion!\n\n");
fact = factorial(num);
printf("Factorial of %d is: %d\n",num,fact);
}
int factorial(int num)
{
if (num==0)
{
return 0;
}
else if (num==1)
{
return 1;
}
else
{
return num*factorial(num-1);
}
}
Output:-
Recursive Function in C
For Example:-
if (condition1)
{
return value1;
}
else if (condition2)
34
{
return value2;
}
else
{
// Statements;
recursive call;
}
#include<stdio.h>
int fib(int);
void main ()
{
int num=15,fibo;
printf("TechVidvan Tutorial: Fibonacci series using recursive function!\n\n");
fibo = fib(num);
printf("Result is: %d",fibo);
}
int fib(int num)
{
if (num==0)
{
return 0;
}
else if (num == 1)
{
return 1;
}
else
{
return fib(num-1)+fib(num-2);
}
}
Output:-
In C, each recursive function call creates a copy of it in memory. When some data is
returned from the recursive call then the memory releases the copy.
As we all know that all variables, arguments and other things of function get stored in
the stack. And for each recursive call, a separate stack is maintained.
35
Let’s take an example to understand the memory allocation of recursive method.
Let’s analyze the above example for num=4. At first, all stacks are maintained. We
have used the if condition in the above example. If the value of num reaches 0 then
the stacks will be deleted one by one by returning 0 to its calling stack.
Advantages of Recursion in C
Disadvantages of Recursion in C
36
Significance of Recursion in C
In C, programmers use recursion many times on their programs due to its ability to
keep the code short and simple. It also enhances the code readability.
Recursion also helps in reducing the run-time of the program code. But you can also
use iteration, it provides much faster functionality than recursion.
You can solve several problems using the recursion in C. Problems like factorial of a
number, fibonacci series in a given range, tree algorithm problems etc. can be solved
easily with recursion.
In recursion, if you don’t specify or define the base case then you can face stack
overflow problems.
Example:-
In the above example, if you provide factorial(5) then first it will call factorial(4),
factorial(3) and so on but the number will never reach 10. So, here the base case is not
reached then the memory will get exhausted by the factorial() functions on the stack
and it will cause a stack overflow error.
In a recursive function, if the recursive call is the last thing executed by the recursive
function then the recursive function is known as tail-recursive. And if it is not then it
is called a non-tailed recursive.
Now, let's see the comparison between iteration and recursion. We are comparing
both terms based on some characteristics.
On the basis
Recursion Iteration
of
Basic Recursion is the process of In iteration, there is a repeated
37
calling a function itself within execution of the set of instructions. In
its own code. Iteration, loops are used to execute the
set of instructions repetitively until the
condition is false.
The format of iteration includes
There is a termination
Syntax initialization, condition, and
condition is specified.
increment/decrement of a variable.
The termination condition is
Here, the termination condition is
Termination defined within the recursive
defined in the definition of the loop.
function.
The code size in recursion is
The code size in iteration is larger than
Code size smaller than the code size in
the code size in recursion.
iteration.
If the recursive function does
not meet to a termination Iteration will be infinite, if the control
condition, it leads to an condition of the iteration statement
Infinite
infinite recursion. There is a never becomes false. On infinite loop, it
chance of system crash in repeatedly used CPU cycles.
infinite recursion.
It is always applied to
Applied It is applied to loops.
functions.
Speed It is slower than iteration. It is faster than recursion.
Recursion is generally used
It is used when we have to balance the
where there is no issue of time
Usage time complexity against a large code
complexity, and code size
size.
requires being small.
The time complexity in iteration is
Time relatively lower. We can calculate its
It has high time complexity.
complexity time complexity by finding the no. of
cycles being repeated in a loop.
It has to update and maintain
Stack There is no utilization of stack.
the stack.
It uses more memory as It uses less memory as compared to
Memory
compared to iteration. recursion.
There is an extensive
Overhead overhead due to updating and There is no overhead in iteration.
maintaining the stack.
Pointers
The pointer in C language is a variable which stores the address of another variable.
This variable can be of type int, char, array, function, or any other pointer. The size of
the pointer depends on the architecture. However, in 32-bit architecture the size of a
pointer is 2 byte.
38
Consider the following example to define a pointer which stores the address of an
integer.
1. int n = 10;
2. int* p = &n; // Variable p of type pointer is pointing to the address of the varia
ble n of type integer.
Declaring a pointer
The pointer in c language can be declared using * (asterisk symbol). It is also known
as indirection pointer used to dereference a pointer.
Pointer Example
An example of using pointers to print the address and value is given below.
As you can see in the above figure, pointer variable stores the address of number
variable, i.e., fff4. The value of number variable is 50. But the address of pointer
variable p is aaa3.
By the help of * (indirection operator), we can print the value of pointer variable p.
Let's see the pointer example as explained for the above figure.
1. #include<stdio.h>
2. int main(){
3. int number=50;
4. int *p;
5. p=&number;//stores the address of number variable
6. printf("Address of p variable is %x \n",p); // p contains the address of the num
ber therefore printing p gives the address of number.
7. printf("Value of p variable is %d \n",*p); // As we know that * is used to deref
erence a pointer therefore if we print *p, we will get the value stored at the add
ress contained by p.
39
8. return 0;
9. }
Output
Pointer to array
1. int arr[10];
2. int *p[10]=&arr; // Variable p of type pointer is pointing to the address of an i
nteger array arr.
Pointer to a function
Pointer to structure
1. struct st {
2. int i;
3. float f;
4. }ref;
5. struct st *p = &ref;
Advantage of pointer
1) Pointer reduces the code and improves the performance, it is used to retrieving
strings, trees, etc. and used with arrays, structures, and functions.
3) It makes you able to access any memory location in the computer's memory.
Usage of pointer
40
1) Dynamic memory allocation
Pointers in c language are widely used in arrays, functions, and structures. It reduces
the code and improves the performance.
The address of operator '&' returns the address of a variable. But, we need to use %u
to display the address of a variable.
1. #include<stdio.h>
2. int main(){
3. int number=50;
4. printf("value of number is %d, address of number is %u",number,&number);
5. return 0;
6. }
Output
NULL Pointer
A pointer that is not assigned any value but NULL is known as the NULL pointer. If
you don't have any address to be specified in the pointer at the time of declaration,
you can assign NULL value. It will provide a better approach.
int *p=NULL;
Pointer Program to swap two numbers without using the 3rd variable.
1. #include<stdio.h>
2. int main(){
3. int a=10,b=20,*p1=&a,*p2=&b;
4.
5. printf("Before swap: *p1=%d *p2=%d",*p1,*p2);
6. *p1=*p1+*p2;
7. *p2=*p1-*p2;
8. *p1=*p1-*p2;
9. printf("\nAfter swap: *p1=%d *p2=%d",*p1,*p2);
10.
11. return 0;
41
12. }
Output
There are several things which must be taken into the consideration while reading the
complex pointers in C. Lets see the precedence and associativity of the operators
which are used regarding pointers.
• (): This operator is a bracket operator used to declare and define the function.
• []: This operator is an array subscript operator
• * : This operator is a pointer operator.
• Identifier: It is the name of the pointer. The priority will always be assigned to
this.
• Data type: Data type is the type of the variable to which the pointer is intended
to point. It also includes the modifier like signed int, long, etc).
To read the pointer, we must see that () and [] have the equal precedence. Therefore,
their associativity must be considered here. The associativity is left to right, so the
priority goes to ().
Inside the bracket (), pointer operator * and pointer name (identifier) p have the same
precedence. Therefore, their associativity must be considered here which is right to
left, so the priority goes to p, and the second priority goes to *.
Assign the 3rd priority to [] since the data type has the last precedence. Therefore the
pointer will look like following.
• char -> 4
• * -> 2
• p -> 1
• [10] -> 3
42
Example
Explanation
This pointer will be read as p is a pointer to such function which accepts the first
parameter as the pointer to a one-dimensional array of integers of size two and the
second parameter as the pointer to a function which parameter is void and return type
is the integer.
Pointer operators
There are two pointer operators :
1. value at address operator ( * )
2. address of operator ( & )
Value at address operator ( * )
The * is a unary operator. It gives the value stored at a particular address. The ‘value
at address’ operator is also called ‘indirection’ operator.
q = *m;
if m contains the memory address of the variable count, then preceding assignment
statement can places the value of count into q.
Address of operator ( & )
The & is a unary operator that returns the memory address of its operand.
m = & count;
The preceding assignment statement can be “The memory address of the variable
count is places into m”.
int a = 25 ;
int *b ;
b = &a ;
printf("\n Address of a = %u ", & a) ;
43
printf("\n Address of a = %u ", b) ;
printf("\n Address of b = %u ", & b) ;
printf("\n Value of b = %u ", b) ;
printf("\n Value of a = %d ", a) ;
printf("\n Value of a = %d ", *( &a ) )) ;
printf("\n Value of a = %d ", *b) ;
return ( 0 );
Address of a = 12345
Address of a = 12345
Address of b = 12345
Value of b = 12345
Value of a = 5
Value of a = 5
Value of a = 5
Uses of pointers
Features of Pointers:
Uses of pointers:
44
5. To implement data structures
6. To do system level programming where memory addresses are useful
An array is a block of sequential data. Let's write a program to print addresses of array
elements.
return 0;
}
Output
&x[0] = 1450734448
&x[1] = 1450734452
&x[2] = 1450734456
&x[3] = 1450734460
Address of array x: 1450734448
Notice that, the address of &x[0] and x is the same. It's because the variable name x
points to the first element of the array.
From the above example, it is clear that &x[0] is equivalent to x. And, x[0] is
equivalent to *x.
Similarly,
45
• &x[1] is equivalent to x+1 and x[1] is equivalent to *(x+1).
• &x[2] is equivalent to x+2 and x[2] is equivalent to *(x+2).
• ...
• Basically, &x[i] is equivalent to x+i and x[i] is equivalent to *(x+i).
return 0;
}
Enter 6 numbers: 2
3
4
4
12
4
Sum = 29
In most contexts, array names decay to pointers. In simple words, array names are
converted to pointers. That's the reason why you can use pointers to access elements
of arrays. However, you should remember that pointers and arrays are not the
same.
There are a few cases where array names don't decay to pointers.
46
Example 2: Arrays and Pointers
return 0;
}
*ptr = 3
*(ptr+1) = 4
*(ptr-1) = 2
In this example, &x[2], the address of the third element, is assigned to the ptr pointer.
Hence, 3 was displayed when we printed *ptr.
And, printing *(ptr+1) gives us the fourth element. Similarly, printing *(ptr-1) gives
us the second element.
Creating a string
In the following example we are creating a string str using char character array of size
6.
47
Each character in the string str takes 1 byte of memory space.
The variable name of the string str holds the address of the first element of the array
i.e., it points at the starting memory address.
So, we can create a character pointer ptr and store the address of the string str variable
in it. This way, ptr will point at the string str.
In the following code we are assigning the address of the string str to the pointer ptr.
The pointer variable ptr is allocated memory address 8000 and it holds the address of
the string variable str i.e., 1000.
48
Accessing string via pointer
To access and print the elements of the string we can use a loop and check for the \0
null character.
In the following example we are using while loop to print the characters of the string
variable str.
#include <stdio.h>
int main(void) {
// string variable
char str[6] = "Hello";
// pointer variable
char *ptr = str;
return 0;
}
We can achieve the same result by creating a character pointer that points at a string
value stored at some memory location.
In the following example we are using character pointer variable strPtr to store string
value.
#include <stdio.h>
int main(void) {
49
// move the t pointer to the next memory location
t++;
}
return 0;
}
Note! In the above code we are using another character pointer t to print the
characters of the string as because we don't want to lose the starting address of the
string "Hello" which is saved in pointer variable strPtr.
In the above image the string "Hello" is saved in the memory location 5000 to 5005.
The pointer variable strPtr is at memory location 8000 and is pointing at the string
address 5000.
The temporary variable is also assigned the address of the string so, it too holds the
value 5000 and points at the starting memory location of the string "Hello".
Array of strings
We can create a two dimensional array and save multiple strings in it.
For example, in the given code we are storing 4 cities name in a string array city.
char city[4][12] = {
"Chennai",
"Kolkata",
"Mumbai",
"New Delhi"
};
50
We can represent the city array as follows.
The problem with this approach is that we are allocating 4x12 = 48 bytes memory to
the city array and we are only using 33 bytes.
We can save those unused memory spaces by using pointers as shown below.
char *cityPtr[4] = {
"Chennai",
"Kolkata",
"Mumbai",
"New Delhi"
};
In the above code we are creating an array of character pointer cityPtr of size 4 to
store the name of the four cities.
51
The above array of pointers can be represented in memory as follows.
The cityPtr pointer variable is allocated the memory address 8000 to 8007. Assuming
integer address value takes 2 bytes space. So, each pointer gets 2 bytes.
Name of the cities are saved in locations 1000, 2000, 3000 and 4000.
To access and print the values pointed by the array of pointers we take help of loop as
shown in the following example.
52
#include <stdio.h>
int main(void) {
// array of pointers
char *cityPtr[4] = {
"Chennai",
"Kolkata",
"Mumbai",
"New Delhi"
};
// temporary variable
int r, c;
// print cities
for (r = 0; r < 4; r++) {
c = 0;
while(*(cityPtr[r] + c) != '\0') {
printf("%c", *(cityPtr[r] + c));
c++;
}
printf("\n");
}
return 0;
}
Output:
Chennai
Kolkata
Mumbai
New Delhi
In the above code we are using the r variable to access each row of the pointer. And
we are using the c variable to access each character in a selected row.
Pointers have two uses. The first is to store a memory address. The second is to use
the stored memory address to access that points using an indirection.
53
memory address contained in a pointer is correct, nor that the pointed data is correct.
This feature makes the design of programs using pointer a complex task.
The following program shows the use of the indirection operator (file
pointer_example_2.c):
#include <stdio.h>
int main(int argc, char** argv)
{
int num1, num2;
int *ptr1, *ptr2;
ptr1 = &num1;
ptr2 = &num2;
num1 = 10;
num2 = 20;
*ptr1 = 30;
*ptr2 = 40;
*ptr2 = *ptr1;
return 0;
}
Line 13 assigns the value 30 to the memory location stored in ptr1 through an
indirection. The pointer has the address of num1, thus it is equivalent to assign the
value 30 directly to num1. Analogously, line 14 assigns the value 40 to the address
pointed by ptr2. This assignment is equivalent to assign the value 40 to num2. Line 16
contains two indirections. The right hand side of the assignment obtains the data from
the memory address stored in ptr1 (the address of num1), and this data is assigned to
the memory address stored in ptr2 (the address of num2). Upon program termination,
variable num2 contains the value 30 although it has not been directly assigned.
The following figure shows the evolution of these four variables throughout the
program execution. Again, the memory addresses where they are stored are arbitrary.
54
The coincidence between the indirection operator and the definition of the pointer
type “*” may pose a difficulty when understanding code. For example, the following
line
int *r = *p;
contains two “*” operands. The first defines the type “pointer to integer” and is
followed by a declaration of variable “r”. The second is an indirection and is applied
to the address stored in pointer “p”.
Let us suppose that a data structure with name “struct s” has been defined. Applying
the rule to define the pointer types, a pointer to this structure has type “struct s *”. In
the following code fragment a structure is defined and declared, and a pointer is then
declared containing its address.
struct s
{
int x;
char c;
}
struct s element;
struct s *pointer;
pointer = &element;
An indirection with pointer is used only to access the structure fields. This operation
require two operators, the indirection (operator “*”) and the access to the structure
fields (operator “.”). The syntax is then:
(*pointer).x = 10;
(*pointer).c = 'l';
These two operations in C are grouped by the operator “->” that is placed between the
pointer and the name of the field structure. The equivalent notation is then:
pointer->x = 10;
pointer->c = 'l';
The operator “->” is always written next to a pointer pointing to a structure, and
precedes the name of one of the fields of that structure. The following program shows
the use of this operator to copy the content from one structure to another.
55
float z;
};
int main()
{
/* Declaring two structures */
struct coordinates location1, location2;
/* Declaring two pointers */
struct coordinates *ptr1, *ptr2;
return 0;
}
int **var;
#include <stdio.h>
int main () {
56
int var;
int *ptr;
int **pptr;
var = 3000;
return 0;}
When the above code is compiled and executed, it produces the following result −
Pointers to functions
A pointer to a function points to the address of the executable code of the function.
You can use pointers to call functions and to pass functions as arguments to other
functions. You cannot perform pointer arithmetic on pointers to functions.
For z/OS® XL C/C++, use the __cdecl keyword to declare a pointer to a function as a
C linkage.
The type of a pointer to a function is based on both the return type and parameter
types of the function.
57
In this example, fp is a pointer to a function that returns int. You can rewrite the
declaration of fp without using a trailing return type as int (*fp)(void).
Under z/OS XL C/C++, if you pass a function pointer to a function, or the function
returns a function pointer, the declared or implied linkages must be the same. Use the
extern keyword with declarations in order to specify different linkages.
The following example illustrates the correct and incorrect uses of function pointers
under z/OS XL C/C++ :
#include <stdlib.h>
extern "C" {
typedef void (*cfp_T)();
typedef int (*cf_pT)();
void cfn();
void (*cfp)();
}
extern "C++" {
typedef int (*cxxf_pT)();
void cxxfn();
void (*cxxfp)();
}
58
main() {
For z/OS, linkage compatibility affects all C library functions that accept a function
pointer as a parameter.
References to functions
int x = bar(g);
You can also use a trailing return type in the declaration or definition of a reference to
a function. In the following example, fp is a reference to a function that returns int.
auto(&fp)()->int;
59
Dynamic memory allocation
Since C is a structured language, it has some fixed rules for programming. One of
them includes changing the size of an array. An array is a collection of items stored at
contiguous memory locations.
As it can be seen that the length (size) of the array above made is 9. But what if there
is a requirement to change this length (size). For Example,
1. malloc()
2. calloc()
3. free()
4. realloc()
C malloc() method
60
Syntax:
Example:
#include <stdio.h>
#include <stdlib.h>
int main()
{
// This pointer will hold the
// base address of the block created
int* ptr;
int n, i;
// Get the number of elements for the array
printf("Enter number of elements:");
scanf("%d",&n);
printf("Entered number of elements: %d\n", n);
// Dynamically allocate memory using malloc()
ptr = (int*)malloc(n * sizeof(int));
// Check if the memory has been successfully
61
// allocated by malloc or not
if (ptr == NULL) {
printf("Memory not allocated.\n");
exit(0);
}
else {
// Memory has been successfully allocated
printf("Memory successfully allocated using malloc.\n");
// Get the elements of the array
for (i = 0; i < n; ++i) {
ptr[i] = i + 1;
}
// Print the elements of the array
printf("The elements of the array are: ");
for (i = 0; i < n; ++i) {
printf("%d, ", ptr[i]);
}
}
return 0;
}
Output:
C calloc() method
Syntax:
62
For Example:
Example:
#include <stdio.h>
#include <stdlib.h>
int main()
{
63
// Get the elements of the array
for (i = 0; i < n; ++i) {
ptr[i] = i + 1;
}
return 0;
}
Output:
Enter number of elements: 5
Memory successfully allocated using calloc.
The elements of the array are: 1, 2, 3, 4, 5,
C free() method
Syntax:
free(ptr);
64
Example:
#include <stdio.h>
#include <stdlib.h>
int main()
{
return 0;
}
65
Output:
Enter number of elements: 5
Memory successfully allocated using malloc.
Malloc Memory successfully freed.
C realloc() method
Syntax:
Example:
#include <stdio.h>
#include <stdlib.h>
int main()
{
66
// base address of the block created
int* ptr;
int n, i;
67
for (i = 0; i < n; ++i) {
printf("%d, ", ptr[i]);
}
free(ptr);
}
return 0;
}
Output:
Enter number of elements: 5
Memory successfully allocated using calloc.
The elements of the array are: 1, 2, 3, 4, 5,
#include <stdio.h>
#include <stdlib.h>
int main()
{
int index = 0, i = 0, n,
*marks; // this marks pointer hold the base address
// of the block created
int ans;
marks = (int*)malloc(sizeof(
int)); // dynamically allocate memory using malloc
// check if the memory is successfully allocated by
// malloc or not?
if (marks == NULL) {
printf("memory cannot be allocated");
}
else {
// memory has successfully allocated
printf("Memory has been successfully allocated by "
"using malloc\n");
printf("\n marks = %pc\n",
marks); // print the base or beginning
// address of allocated memory
do {
printf("\n Enter Marks\n");
scanf("%d", &marks[index]); // Get the marks
printf("would you like to add more(1/0): ");
scanf("%d", &ans);
if (ans == 1) {
index++;
68
marks = (int*)realloc(
marks,
(index + 1)
* sizeof(
int)); // Dynamically reallocate
// memory by using realloc
// check if the memory is successfully
// allocated by realloc or not?
if (marks == NULL) {
printf("memory cannot be allocated");
}
else {
printf("Memory has been successfully "
"reallocated using realloc:\n");
printf(
"\n base address of marks are:%pc",
marks); ////print the base or
///beginning address of
///allocated memory
}
}
} while (ans == 1);
// print the marks of the students
for (i = 0; i <= index; i++) {
printf("marks of students %d are: %d\n ", i,
marks[i]);
}
free(marks);
}
return 0;
}
Output:
69