CP Unit-IV - RIT CSE (1)
CP Unit-IV - RIT CSE (1)
UNIT-IV
FUNCTIONS & POINTERS
FUNCTION:
A function is a group of statements that together perform a task. Every C program has at least one
function, which is main ( ), and all the most trivial programs can define additional functions.
You can divide up your code into separate functions. How you divide up your code among different
functions is up to you, but logically the division is such that each function performs a specific task.
A function declaration tells the compiler about a function's name, return type, and parameters. A
function definition provides the actual body of the function.
Every program must have a main() function to indicate where the program has to begin its
execution. If a program was coded as a single function, the program may become too large and
complex and as a result, the task of debugging, testing and maintaining becomes difficult.
If a program is divided into functional parts then each part may be independently coded and
later combined into a single unit. These sub programs called functions are must easier to
understand, debug and test. A function is a self-contained block of code that performs a
particular task.
Function Declarations
A function declaration tells the compiler about a function name and how to call the function. The
actual body of the function can be defined separately.
SYNTAX OF function declaration:
return_type function_name( parameter list );
A function definition in C programming consists of a function header and a function body. Here are
all the parts of a function −
Return Type − A function may return a value. The return_type is the data type of the value
the function returns. Some functions perform the desired operations without returning a value.
In this case, the return_type is the keyword void.
Function Name − This is the actual name of the function. The function name and the
parameter list together constitute the function signature.
Parameters − A parameter is like a placeholder. When a function is invoked, you pass a value
to the parameter. This value is referred to as actual parameter or argument. The parameter list
refers to the type, order, and number of the parameters of a function. Parameters are optional;
that is, a function may contain no parameters.
Function Body − The function body contains a collection of statements that define what the
function does.
Calling a Function
While creating a C function, you give a definition of what the function has to do. To use a function,
you will have to call that function to perform the defined task.
When a program calls a function, the program control is transferred to the called function. A called
function performs a defined task and when its return statement is executed or when its function-
ending closing brace is reached, it returns the program control back to the main program.
To call a function, you simply need to pass the required parameters along with the function name, and
if the function returns a value, then you can store the returned value.
Example
#include <stdio.h>
int mul(a,b)
int a,b;
{
int m;
m=a*b;
return(m);
}
void main( )
{
int m,n,p; clrscr();
printf(“enter two numbers “);
scanf(“%d%d”,&m,&n);
p=mul(m,n); /*------- function call */
printf(“%d\n”,p);
}
When the compiler encounters a function call, the control is transferred to the function mul(x,y). This
function is then executed line by line and a value is returned when a return statement is encountered.
This value is assigned to p.
Points to remember:
1. A function may or may not return a value if it does, it can return only one value.
2. Functions return integer value by default.
3. When a function is supposed to return a non-integer value, its type must be explicitly specified in
the function header. Such a function should be declared at the start of the calling function.
#include <stdio.h>
void sum()
{
int a,b,c;
printf(“enter two numbers “); scanf(“%d%d”,&a,&b);
c=a+b;
printf(“Sum is %d”,c); }
void main( )
{
sum(); /*------- function call */
}
void main()
{
int a[10],i,n,large;
clrscr();
printf("enter size" ); scanf("%d",&n);
for (i=0;i<n;i++)
{
printf("enter array element "); scanf("%d",&a[i]);
}
large=largest(a,n);
printf("the largest = %d\n",large);
getch();
}
/*program to arrange array elements of a single dimensional array in sorted order using a
function*/
#include<stdio.h>
#include<conio.h>
sorting(a,n)
int a[],n;
{
int i,j,temp;
for (i=0;i<n-1;i++)
4|Page
for (j=0;j<n-i-1;j++)
if (a[j] > a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
void main()
{
int a[10],i,j,n,temp;
printf("enter size" ); scanf("%d",&n);
for (i=0;i<n;i++)
{
printf("enter array element "); scanf("%d",&a[i]);
}
There are two ways in which we can pass arguments to the functions a) call by value and b) call by
reference.
A) Call by value:
In this type, the value of actual arguments are passed to the formal arguments and the operation is
done on the formal arguments. Any change in the formal arguments does not affect the actual
arguments. Both the formal and actual arguments are allocated memory separately. Hence when the
function is called by the call by value method, it does not affect the actual arguments.
Example:
main()
{
int x,y, interchange(int,int);
printf(“Enter values of x and y”);
scanf(“%d %d”,&x,&y);
interchange(x,y);
printf(“\n In main prg x and y values are %d %d”,x,y);
return 0;
}
void interchange(int a, int b)
{
int t;
t=a;
a=b;
b=t;
printf(“\n In the function x and y values are %d %d”,a,b);
}
Output:
Enter values of x and y 5 6
In the function x and y values are 6 5
5|Page
In main prg x and y values are 5 6.
Explanation:
In the above program we are passing values of actual parameters x and y to the function interchange().
The formal arguments a, and b of the function receives these values. These values are interchanges and
printed. When the control return to the main again we are printing the values of x, y . These are printed
as they read from the keyboard. The change done in the function is not affected actual arguments.
B) Call by reference:
In this type instead of passing values, address are passed as argument. Function operates on address.
Here the formal arguments are the pointers to the actual arguments. Only one storage location is used
here i.e for actual arguments only. Hence the changes made in the formal arguments will remain with
actual arguments also.
Example:
main()
{
int x,y, interchange(int*,int*);
printf(“Enter values of x and y”);
scanf(“%d %d”,&x,&y);
interchange(&x,&y);
printf(“\n In main prg x and y values are %d %d”,x,y);
return 0;
}
Downward Communication
Upward Communication
Bi-directional Communication
6|Page
Downward Communication
In this type of inter function communication, the data is transferred from calling function to called
function but not from called function to calling function. The functions with parameters and without
return value are considered under downward communication. In the case of downward
communication, the execution control jumps from calling function to called function along with
parameters and executes the function definition, and finally comes back to the calling function without
any return value. For example consider the following program.
Example Program
#include<stdio.h>
#include<conio.h>
void main(){
int num1, num2 ;
void addition(int, int) ; // function declaration
clrscr() ;
num1 = 10 ;
num2 = 20 ;
getch() ;
}
void addition(int a, int b) // called function
{
Output:
7|Page
Upward Communication
In this type of inter-function communication, the data is transferred from called function to calling-
function but not from calling-function to called-function. The functions without parameters and with
return value are considered under upward communication. In the case of upward communication, the
execution control jumps from calling-function to called-function without parameters and executes the
function definition, and finally comes back to the calling function along with a return value. For
example, consider the following program.
Example Program
#include<stdio.h>
#include<conio.h>
void main(){
int result ;
int addition() ; // function declaration
clrscr() ;
result = addition() ; // calling function
printf("SUM = %d", result) ;
getch() ;
}
int addition() // called function
{
int num1, num2 ;
num1 = 10;
num2 = 20;
return (num1+num2) ;
}
Output:
8|Page
Bi - Directional Communication
In this type of inter-function communication, the data is transferred from calling-function to called
function and also from called function to calling-function. The functions with parameters and with
return value are considered under bi-directional communication. In the case of bi-directional
communication, the execution control jumps from calling-function to called function along with
parameters and executes the function definition and finally comes back to the calling function along
with a return value. For example, consider the following program...
Example Program
#include<stdio.h>
#include<conio.h>
void main(){
int num1, num2, result ;
int addition(int, int) ; // function declaration
clrscr() ;
num1 = 10 ;
num2 = 20 ;
result = addition(num1, num2) ; // calling function
printf("SUM = %d", result) ;
getch() ; }
int addition(int a, int b) // called function
{
return (a+b) ;
}
Output:
STANDARD FUNCTIONS
9|Page
The standard functions are built-in functions. In C programming language, the standard functions are
declared in header files and defined in .dll files. In simple words, the standard functions can be defined
as "the ready made functions defined by the system to make coding more easy". The standard
functions are also called as library functions or pre-defined functions.
In C when we use standard functions, we must include the respective header file
using #include statement. For example, the function printf() is defined in header
file stdio.h (Standard Input Output header file). When we use printf() in our program, we must
include stdio.h header file using #include<stdio.h> statement.
Some Of The Standard Functions In C Are Given Below.
time.h Provides functions to perform operations on time and date time(), localtime()
#include <stdio.h>
float calculateSum(float age[]);
int main() {
float result, age[] = {23.4, 55, 22.6, 3, 40.5, 18};
10 | P a g e
float calculateSum(float age[]) {
return sum;
}
Output
Result = 162.50
To pass an entire array to a function, only the name of the array is passed as an argument.
result = calculateSum(age);
This informs the compiler that you are passing a one-dimensional array to the function. In the above
example the array name is supplied as an argument but the size of the array is not supplied. We can
also pass the size of the array as an argument along with the array name.
#include<stdio.h>
int addition(int[],int);
void main()
int x[10],i,n,sum;
clrscr();
scanf(“%d”,&n);
printf(“enter elements”):
for(i=0;i<n;i++)
11 | P a g e
scanf(“%d”,&x[i]);
sum=addition(x,n);
printf(“sum=%d”,sum);
getch();
int sum=0,i;
for(i=0;i<n;i++)
sum=sum+x[i];
return(sum);
Output:
Enter elements: 10 20 30 40
Sum=100
NOTE: Similarly, we can pass a two dimensional array to a function as an argument. But, in 2
dimensional arrays, you need to use two subscripts during function declaration and definition.
RECURSION
A function is called recursive if a statement within the body of a function calls the same
function.
12 | P a g e
When writing recursive functions, you must have an if statement somewhere in the recursive
function to force the function to return without recursive call being executed. If you do not do this and
you call the function, you will fall in an indefinite loop, and will never return from the called function.
clrscr();
#include<stdio.h>
#include<conio.h>
int gcd(int u,int v)
{
if (v==0) return(u);
else return(gcd(v,u%v));
}
int main()
{
int m,n,g;
clrscr();
printf("enter m and n");
scanf("%d%d",&m,&n);
g=gcd(m,n); /*---------- Function Call */
printf("the gcd of %d and %d is %d\n",m,n,g);
return 0;
}
13 | P a g e
/* Program to find nth Fibonacci number using a Recursive function*/
#include<stdio.h> #include
<math.h>
int fib(n)
int n;
{
if (n==1) return(0);
else
if (n==2) return(1);
else return(fib(n-1)+fib(n-2));
}
void main()
{
int n,f; clrscr();
printf("which term you want"); scanf("%d",&n);
f=fib(n);
printf("The %d th Fibonacci term is %d \n",n,f); getch();
}
SCOPE: The scope of a variable determines over what part(s) of the program a variable is actually
available for use.
LIFETIME: Lifetime refers to the period during which a variable retains a given value during
execution of a program (alive).
A variable may also be broadly categorized depending on the place of their declaration as internal
(local) or external (global). Internal variables are those which are declared within a particular function,
while external variables are declared outside of any function.
1. AUTOMATIC VARIABLES:
Automatic variables are declared inside a function in which they are to be utilized. They are
created when the function is called and destroyed automatically when the function is exited; hence the
name automatic variables are also referred to as local or internal variables.
A variable declared inside a function without storage class specification is, by default, an automatic
variable. We may also use the keyword auto to declare automatic variables explicitly.
main( )
{
int num; auto int num;
- -
-} }
The value of automatic variable cannot be changed accidentally by what happens in some other
function in the program. This assures that we may declare and use the same variable name in different
functions in the same program without causing any confusion to the compiler.
void main( )
14 | P a g e
{
int m=1000;
function2( );
printf(“%d\n”,m);
}
function1( )
{
int m=10;
printf(“%d\n”,m);
}
Output
function2( ) 10
{
100
int m=100;
1000
function1( );
printf(“%d\n”,m);
}
A program with two sub programs function1( ) and function2( ) is shown. m is an automatic variable
and it is declared at the beginning of the each function. m is initialized to 10, 100, 1000 in function1,
function2 and main( ) respectively.
When executed, main( ) calls function2, which in turn calls function1. When main is active
m=1000, but when f2 is called the main‟s m is temporarily put on the shelf and the new local m=100
becomes active. Similarly when function1 is called both the previous values of m are put on the shelf
and the latest value of m=10 becomes active. As soon as function1 is finished, function2 takes over
again. As soon it is done, main takes over the output clearly. Shows that the value assigned to m is one
function does not effect its value in the other functions, and the local value of m is destroyed when its
leaves a function.
2. EXTERNAL VARIABLES:
Variables that are both alive and active through out the entire program are known as external
variables. They are also known as global variables. Unlike local variables, global variables can be
accessed by any function in the program. External variables are declared out side a function
Ex:
int a; int b;
main( );
{
-
-
}
Fun1()
{
}
Fun2()
{
}
The variables a and b are available for use in all the three functions. In case a local variable and global
variable have the same name, the local variable will have precedence over the global one in the
function where it is declared.
Once a variable has been declared as global, any function can use it and change its value. Then
subsequent functions can reference only that new value.
15 | P a g e
One other aspect of a global variable is that it is visible only from the point of declaration to the end of
the program. Consider a program segment as shown below.
void main()
{
y=5;
.
.}
int y;
fun1()
{
y=y+1; .
.
}
As far as main() is concerned, y is not defined. So, the compiler will issue an error message. Unlike
local variables global variables are initialized to zero by default.
In the above program segment, the main() can not access the variable y as it has been declared after
the main() function. Declaring the variable with the storage class extern can solve this problem.
main( )
{
extern int y;
-
-
}
function1( )
{
extern int y;
-
-
}
int y;
Although the variable y has been defined after both the functions, the external declaration of y inside
the functions informs the compiler that y is an integer type defined some where else in the program.
num=2; OUTPUT
printf(“num=%s\n”,num); num= 2
fun1(); num= 7
printf(“num=%s\n”,num); num=17
fun2();
printf(“num=%s\n”,num);
fun1()
{
num=num+5;
}
fun2()
{
} num=num+10;
3. STATIC VARIABLES:
As the name suggests, the value of static variables persists until the end of the program. A
variable can be declared static using the key word static like
static int x; static
float y;
A static variable may be either an internal type or an external type, depending on the place of
declaration. Internal static variables are those which are declared inside a function. The scope of
internal static variables extends up to the end of the function, in which they are defined. Therefore,
internal static variables are similar to auto variables, except that they remains in existence (alive)
throughout the remainder of the program. Therefore internal static variables can be used to retain
values between function calls.
Example for static variable Example for Auto variable
A static variable is initialized only once, when the program is compiled it is never initialized
again. During the first call to fun( ) function x is incremented to 1. Because x is static, this value
persists and therefore, the next call adds another 1 to x giving it a value of 2. The value of x
becomes 3 when the third call is made.
4. REGISTER VARIABLES:
We can tell the compiler that a variable should be kept in one of the machine‟s registers, instead of
keeping in the memory. Since a register access is much faster than a memory access, keeping the
frequently accessed variables in the register will lead to the faster execution.
register int count;
Most compilers allow only int or char variables to be placed in the register
TYPE QUALIFIERS
1. const
2. volatile
1. CONST KEYWORD:
Constants are also like normal variables. But, only difference is, their values can‟t be modified
by the program once they are defined.
They refer to fixed values. They are also called as literals.
They may be belonging to any of the data type.
Syntax:
const data_type variable_name; (or) const data_type *variable_name;
Please refer C – Constants topic in this tutorial for more details on const keyword.
2. VOLATILE KEYWORD:
When a variable is defined as volatile, the program may not change the value of the variable
explicitly.
But, these variable values might keep on changing without any explicit assignment by the
program. These types of qualifiers are called volatile.
For example, if global variable‟s address is passed to clock routine of the operating system to
store the system time, the value in this address keep on changing without any assignment by the
program. These variables are named as volatile variable.
Syntax:
volatile data_type variable_name; (or) volatile data_type *variable_name;
POINTERS
A pointer is a variable whose value is the address of another variable, i.e., direct address of the
memory location. Like any variable or constant, you must declare a pointer before you can use it to
store any variable address. The general form of a pointer variable declaration is:
type *var-name;
Here, type is the pointer's base type; it must be a valid C data type and var-name is the name
of the pointer variable. The asterisk * you used to declare a pointer is the same asterisk that you use
for multiplication. However, in this statement the asterisk is being used to designate a variable as a
pointer.
18 | P a g e
Pointers can be used to pass information back and forth between a function and its reference
point. In particular, pointers provide a way to return multiple data items from a function via function
arguments.
Pointers are also closely associated with arrays and therefore provide an alternative way to
access individual array elements. The computer memory is a sequential collection of storage cells.
Each cell commonly known as a byte, has a number called address associated with it.
Typically the addresses are numbered consecutively starting from zero. The last address
depends on memory size.
int num=50;
This statement instructs the system to find a location for the integer variable „num‟ and puts the value
50 in that location.
Let us assume that the system has chosen the address location 2000 for num.
printf(“num=%d address=%u\n”,num,&num);
Output:
num=50 address=2000
Since addresses are numeric values, they can be stored in variables, just like any other kind of
data.
Pointer variables must specify what kind of data they point to, i.e. the type of data for which they
hold the address. This becomes very important when the pointer variables are used.
When declaring variables, the asterisk, *, indicates that a particular variable is a pointer type as
opposed to a basic type.
So for example, in the following declaration:
variables i, j,and k are of type ( int ), and variables iptr, numPtr, and next are of type ( pointer to int )
Pointers can be assigned values as the program runs, just like any other variable type. For example:
For example:
int i, , j;
int *iptr = &i, *jptr = &j; // These * indicates variables of type ( pointer to int )
i = 42; // changes i to 42
*iptr = 100; // changes i from 42 to 100
j = *iptr; // Now j is 100 also
Another example:
#include <stdio.h>
int main ()
{
int var = 20; /* variable declaration */
int *ip; /* pointer variable declaration */
ip = &var; /* store address of var in pointer variable*/
clrscr();
printf("Address of var variable: %u\n", &var ); /* address stored in pointer variable */
printf("Address stored in ip variable: %u\n", ip ); /* access the address using the pointer */
printf("Value of *ip variable: %d\n", *ip ); /* access value through pointer */
return 0;
}
Output:
Address of var variable: 65492
Address stored in ip variable: 65492
Value of *ip variable: 20
Hint:
In the above program…
ip is points to address of variable.
*ip is known as „value at pointer‟.
Pointer dereferencing
Once a pointer is declared, you can refer to the thing it points to, known as the target of the
pointer, by "dereferencing the pointer". To do this, use the unary * operator:
20 | P a g e
Suppose that ptr is the above pointer. Suppose it stores the address 1234. Also suppose that the
integer stored at address 1234 has the value 99.
// Output:
// The pointer is: 1234 // exact printout here may vary
// The target is: 99
Pointer Arithmetic
There are a few very limit mathematical operations that may be performed on address data types,
i.e. pointer variables.
Most commonly, integers may be added to or subtracted from addresses.
Note that increment and decrement operations are really just special cases of addition and
subtraction.
For example
Combinations of * and ++
Pointer to pointer
A pointer to a pointer is a form of multiple indirections, or a chain of pointers. Normally, a
pointer contains the address of a variable. When we define a pointer to a pointer, the first pointer
contains the address of the second pointer, which points to the location that contains the actual value
as shown below.
A variable that is a pointer to a pointer must be declared as such. This is done by placing an
additional asterisk in front of its name. For example, following is the declaration to declare a pointer to
a pointer of type int:
int **var;
int **var;
21 | P a g e
When a target value is indirectly pointed to by a pointer to a pointer, accessing that value
requires that the asterisk operator be applied twice, as is shown below in the example:
Example program:
#include <stdio.h>
void main ()
{
int var;
int *ptr;
int **pptr;
var = 3000;
A pointer may be made to point to an element of an array by use of the address operator(*):
Output:
The array elements are (normal accessing) The array elements are (pointer accessing)
1 is stored at 404 1 is stored at 404
2 is stored at 406 2 is stored at 406
3 is stored at 408 3 is stored at 408
4 is stored at 410 4 is stored at 410
5 is stored at 412 5 is stored at 412
g o o d \0
23 | P a g e
str
We can also use the run-time assignment for giving values to a string pointer. Example
char * string1;
string1 = “good” ;
We can print the content of the string1 using either printf or puts function as follows:
printf(“%s”,string1);
puts(string1);
Note: although string1 is a pointer to the string, it is also the name of the string. Therefore, we do not
need to use indirection operator * here.
Name(404) cptr(409)
Output:
DELHI H is stored at 407
D is stored at 404 I is stored at 408
E is stored at 405 The Length of string = 5
L is stored at 406
Arrays of Pointers
One important use of pointers is in handling of a table of strings. Consider the following array of
strings:
char name [3][25];
24 | P a g e
This says that the name is a table containing three names, each with a maximum length of 25
characters (including null character). The total storage requirements for the name table are 75 bytes
(3x25).
We know that rarely the individual strings will be of equal lengths. Therefore, instead of
making each row a fixed number of characters, we can make it a pointer to a string of varying length.
For example,
char *name[3]={“India”,“New Zealand”,”Australia”};
declares name to be an array of three pointers to characters, each pointer pointing to a particular name
as:
name[0] ------- India
name[1] ------- New Zealand
name[2] ------- Australia
this declaration allocates only 28 bytes, (75-28=47 bytes saving)
I n d i a \0
N e w z e a l a n d \0
A u s t r a l i a \0
Example program :
#include <stdio.h>
void main ()
{
int i;
char *name[3]={"India","New Zealand","Australia"};
for(i=0;i<=2;i++)
printf("%s\n",name[i]);
}
Output:
India
New Zealand
Australia
*(name[i]+j)
In above example p is array of char pointers. Each pointer element is pointing one string. i.e
p[0] points to s, p[1] points to r and p[2] points to t. It is when you use array of pointers to deals with
strings.
Array elements are stored row by row. C needs to know how many columns in order that it can
jump from row to row in memory. Here is an example.
In the above figure, array is a pointer-to-pointer-to-int: at the first level, it points to a block of
pointers, one for each row.
That first-level pointer is the first one we allocate; it has nrows elements, with each element
big enough to hold a pointer-to-int, or int *. If we successfully allocate it, we then fill in the pointers
(all nrows of them) with a pointer (also obtained from malloc) to ncolumns number of ints, the storage
for that row of the array. If this isn't quite making sense, a picture should make everything clear:
Example program:
#include <stdlib.h>
#include <stdio.h>
main()
{
int **array; /* like array[][] & pointer-to-pointer-to-int */
int nrows,ncolumns,i,j;
clrscr();
printf("\nenter no of rows & columns:");
scanf("%d%d",&nrows,&ncolumns);
26 | P a g e
array = malloc(nrows * sizeof(int *)); /* Dynamically memory allocating to array*/
printf("Enter elements\n");
for(i=0;i<nrows;i++)
{
for(j=0;j<ncolumns;j++)
scanf("\n%d",&(*(*(array+i)+j)));
}
printf("output\n");
for(i=0;i<nrows;i++)
{ for(j=0;j<ncolumns;j++)
printf("\n%d", *(*(array+i)+j)); /* like array[i][j] */
}
getch();
}
Output:
27 | P a g e
Enter no of rows & columns :2
2
Enter elements
1
2
3
4
output
1
2
3
4
Previously we pass values (call by value) to the function. Now using pointers we can
pass addresses (call by address) to the functions.
Ex) Write a function using pointers to exchange the values stored in two locations in memory.
/*------------------------------------------------------------------------------------------*/
#include<stdio.h>
#include<conio.h>
void exchange(int *,int *); /* prototype */
void main()
{
int x,y;
x=100;
y=200;
printf("before exchange : x=%d y=%d \n\n",x,y);
exchange(&x,&y); /* function call & we passing addresses here*/
printf("after exchange : x=%d y=%d \n\n",x,y);
getch();
}
void exchange(int *a,int *b) /* pointers as function arguments*/
{
int t;
t=*a;
*a=*b;
*b=t;
}
We have seen so far that a function can return a single value by its name or return
multiple values through pointer parameters. Since pointers are a data type in C, we can also force
a function to return a pointer to the calling function. Consider the following code:
#include<stdio.h>
#include<conio.h>
void *large(int *,int *); /* prototype */
void main()
{
int x,y;
int *p;
x=100;
y=20;
p=large(&x,&y); /*assigning return address(from function large() function) to
pointer p */
printf("%d\n",*p);
getch();
}
void *large(int *a,int *b)
{
if(*a>*b)
return(a); /* returning address of a*/
else
return(b); /* returning address of b */
}
Output:
before exchange : x=100 y=200
after exchange : x=200 y=100
Pointers to Functions
A function, like a variable, has a type and an address location in memory. It is therefore,
possible to declare a pointer to a function, which can then be used as an argument in another
function. A pointer to a function is declared as follows:
Constant Pointers
Let‟s first understand what a constant pointer is. A constant pointer is a pointer that
cannot change the address its holding. In other words, we can say that once a constant pointer
points to a variable then it cannot point to any other variable.
#include<stdio.h>
int main(void)
{
int var1 = 0, var2 = 0;
int *const ptr = &var1;
ptr = &var2;
printf("%d\n", *ptr);
return 0;
}
So, in a nutshell, we assigned an address to a constant pointer and then tried to change the
address by assigning the address of some other variable to the same constant pointer.
So we see that while compiling the compiler complains about „ptr‟ being a read only variable.
This means that we cannot change the value ptr holds. Hence we conclude that a constant pointer
which points to a variable cannot be made to point to any other variable.
As evident from the name, a pointer through which one cannot change the value of
variable it points is known as a pointer to constant. These type of pointers can change the
address they point to but cannot change the value kept at those address.
Syntax:
#include<stdio.h>
int main(void)
{
int var1 = 0;
const int* ptr = &var1;
*ptr = 1;
printf("%d\n", *ptr);
return 0;
}
So we see that the compiler complains about „*ptr‟ being read-only. This means that we cannot
change the value using pointer „ptr‟ since it is defined a pointer to a constant.
If you have understood the above two types then this one is very easy to understand as its
a mixture of the above two types of pointers. A constant pointer to constant is a pointer that can
neither change the address its pointing to and nor it can change the value kept at that address.
for example :
#include<stdio.h>
int main(void)
{
int var1 = 0,var2 = 0;
const int* const ptr = &var1;
*ptr = 1;
ptr = &var2;
printf("%d\n", *ptr);
return 0;
}
So we see that the compiler complained about both the value and address being changed. Hence
we conclude that a constant pointer to a constant cannot change the address and value pointed by
it.
Allocating memory
There are two ways that memory gets allocated for data storage:
The malloc() function dynamically allocates memory when required. This function
allocates „size‟ byte of memory and returns a pointer to the first byte or NULL if there is some
kind of error
Format is as follows.
void * malloc (size_t size);
Specifies in bytes the size of the area you want to reserve the argument. It returns the
address as the return value of the dynamically allocated area. In addition, returns NULL if it fails
to secure the area. The failure to ensure that the situation is usually that is out of memory.
The return type is of type void *, also receive the address of any type. The fact is used as
follows.
double * p = (double *) malloc (sizeof (double));
Example:
int * p;
p = (int *) malloc (sizeof (int));
* p = 5;
Program
The calloc function is used to allocate storage to a variable while the program is running.
This library function is invoked by writing calloc(num,size).This function takes two arguments
that specify the number of elements to be reserved, and the size of each element in bytes and it
allocates memory block equivalent to num * size . The function returns a pointer to the
beginning of the allocated storage area in memory. The important difference between malloc and
calloc function is that calloc initializes all bytes in the allocation block to zero and the allocated
memory may/may not be contiguous.
calloc function is used to reserve space for dynamic arrays. Has the following form.
Number of elements in the first argument specifies the size in bytes of one element to the second
argument. A successful partitioning, that address is returned, NULL is returned on failure.
realloc()
With the function realloc, you can change the size of the allocated area once. Has the
following form.
void * realloc (void * ptr, size_t size);
The first argument specifies the address of an area that is currently allocated to the size in
bytes of the modified second argument. Change the size, the return value is returned in re-
allocated address space. Otherwise it returns NULL.
Size may be smaller but larger than the original. If you have small, reduced what was
written in part will be inaccessible. If you increase the portion of the region will remain an
indefinite increase.
The address of the source address changed, but the same could possibly be different, even if the
different areas of the old style, because it is automatically released in the function realloc, for the
older areas it is not necessary to call the free function.
However, if the function fails and returns NULL, realloc, the older area is to remain still
valid. Therefore, the first pointer argument of the function realloc, both can be NULL pointer
return value is not returned.
Example program:
free()
Free function is used to release the reserved area .It has also been declared in stdlib.h,
which has the following form.
void free (void * ptr);
The argument specifies the address of a dynamically allocated area. You can then free up the
space.
Example:
int * p;
p = (int *) malloc (sizeof (int));
* p = 150;
printf ("% d \ n", * p);
free (p)
It is possible to pass some values from the command line to your C programs when they
are executed. These values are called command line arguments and many times they are
important for your program especially when you want to control your program from outside
instead of hard coding those values inside the code.
The command line arguments are handled using main() function arguments
where argc refers to the number of arguments passed, and argv[] is a pointer array which points
to each argument passed to the program. Argv is called as argument vector and argc is called as
argument counter.
Following is a simple example which checks if there is any argument supplied from the
command line and take action accordingly:
#include <stdio.h>
Output:
$./a.out testing
The argument supplied is testing
When the above code is compiled and executed with a two arguments, it produces the following
result.
$./a.out
One argument expected
argv[0] holds the name of the program itself and argv[1] is a pointer to the first command line
argument supplied, and *argv[n] is the last argument. If no arguments are supplied, argc will be
one, otherwise and if you pass one argument then argc is set at 2.