Beruflich Dokumente
Kultur Dokumente
The C programming language is a standardized programming language developed in the early 1970s by Ken Thompson and Dennis Ritchie
for use on the UNIX operating system. C is the most popular programming language used for writing system software as well as for business
packages.
What are the features of C?
1.C
is
a
2.C
is
3.C is a middle-level language.
4.C uses the top-down approach
5.Programs written in C are efficient and fast.
6.C is highly portable language.
procedural-Oriented
a
programming
compiler-based
language
.
language.
Terminology:-
Character Set: A character denotes any alphabet, digit, white space or any special symbol that is used to represent information. A
character set is collection of characters.
Program: A program is a well-organized collection of instructions that is used to communicate with the computer system to accomplish
desired objective.
How many files are created when a C program is written using Borland c compiler?
When a C program is written, four files will be created:
1.
Source file (e.g., first.c)
2.
3.
4.
exit()
1) It is used to come out of entire program.
2) It is a pre-defined function that is available
inprocess.h or stdlib.h header files. It takes an argument: 0 or
1. exit(0) means a clean exit without an error message. exit(1) means
an abrupt exit with an error message.
When does the goto statement is used compulsary? Why should we avoid the use of goto statement?
goto statement is the best option when one wants the control jumps from inner most loop to outer most loop at once.
goto statement causes the loss of sequentiality in order of execution of instructions. Often, this leads us to difficulty in understanding the program.
Hence, it is suggested that one should avoid the use of goto statement.
Type Qualifiers:Type qualifiers are the keywords that add new meanings to existing data types. There are two type qualifiers: const,volatile.
Making a variable as read-only variable: In order to make the value of variable as unchanged during the execution of a program,
initialize the variable with the type qualifier const as follows:
Ex:
const
double
PI=3.1412;
This initialization tells the compiler that the value of PI must not be modified by the program. However, it can be used on the right hand side of
assignment
statement
like
other
variable.
Ex:
x=PI;
double
x;
Making a variable as modifiable externally: In order to make variables value modifiable at any time by some external sources (from
outside program), we use type qualifier volatile. For example,
volatile int
x;
The value of x may be altered by some external factors even if it does not appear on the left-hand side of an assignment statement. When we
declare a variable as volatile, the compiler will examine the value of the variable each time it is encountered to see whether any external alteration
has
changed
the
value.
Some
Interview
Questions:
1. What is Scope?
Scope refers to the visibility of a function or variable.
If the function or variable is visible outside of the current source file, it is said to have global, or external, scope.
If the function or variable is not visible outside of the current source file, it is said to have local, or static, scope.
2. What is modular programming?
If a program is large, it is subdivided into a number of smaller programs that are called modules or subprograms. If a complex problem is solved
using more modules, this approach is known as modular programming.
3. Is using exit() the same as using return?
No. The exit() function is used to exit your program and return control to the operating system. The return statement is used to return from a
function and return control to the calling function. If you issue a return from the main() function, you are essentially returning control to the calling
function, which is the operating system. In this case, the return
statement and exit() function are similar.
4. What is dangling else problem?
Dangling else problem is an ambiguous situation in which one can not judge the else statement to which if statement it belongs to. E.g., in the
above syntax, we can not judge the else statement whether it belongs to outer if statement or inner if statement.
In order to solve this problem, it is better to include the outer-if-body in curly braces. Hence, the above syntax can be redefined as:
9.
What
are
There are 4 storage classes in C.
1.Auto
2. static
3.extern
4.
the
different
storage
classes
in
C?
register
Static-duration variables are allocated in main memory, usually along with the executable code of the program, and persist for the lifetime of the
program. Global variables (i.e, file scope) with or without the static specifier also have static scope.
Automatic-duration variables are allocated on the stack and come and go as functions are called and return. Variable having block scope and
without
static
specifier
have automatic
storage
duration.
Dynamic memory allocation in which memory is more explicitly (but more flexibly) managed, typically, by allocating it from the heap, an area of
memory structured for this purpose.
Register variables uses processor registers to store their contents if available. If not they will be converted to auto variables automatically.
Array consists of homogenous collection of elements. That is, all the data items stored in array are of same type.
All elements are stored in contiguous locations. That is, all elements are stored one after other in successive
locations of memory (based on size of type of data items). Of course, fixed amount of memory is allocated to an
array.
All elements refer to same name. That is, each element can be identified with the same name including different index value
(subscript value). Hence, an array is also called as a subscripted variable. By using, these index values, an element in the
array
can
be
accessed
directly.
Based on number of square brackets (subscripts or dimensions), arrays are broadly classified into two categories:
I.
II.
One-dimensional
Multi-dimensional
arrays.
arrays.
One-dimensional array consists of only one subscript. Multi-dimensional arrays consist of more than one subscript. E.g., twodimensional array consists of 2 subscripts; 3-dimensional array consists of 3 subscripts and so on. Usually, one-dimensional
numeric array consists of numbers as individual elements where as multi-dimensional numeric array consists of arrays as
individual
elements.
Hence,
multi-dimensional
array
is
also
called
as
array
of
arrays.
One-Dimensional
array:
Declaring
Just
like
an
ordinary
variable,
an
A one-dimensional array can be declared as follows:
$ < $storage class$ > $
one-dimensional
array
should
be
declared
before
it
is
array:
used.
$ > $[size];
In this syntax, $ < $ storage class $ > $ is any one of auto, static, extern or register. It specifies the storage location of an
array,
the
default
values
of
all
elements,
scope
and
life
time
of
an
array.
$ < $ data type $ > $ is any basic data type such as int, float, char or double or any derived data type such as long int, short
int and so on.
$< $array_name$ > $ is any valid identifier.
Size is any non-negative integer constant or integer expression.
1.
2.
int
a[20];
float
//
one-dimensional
#
b[MAXSIZE];
//1-D
3.
int
c[k];
array
capable
define
array
capable
int
//Error:
Array
Initializing
of
of
size
holding
holding
cant
20
elements
MAXSIZE
30
elements
be
declared
one-dimensional
of
of
as
type
int
30
type
float
k=20;
a
variable.
array:
Initializing One-dimensional array is the process of assigning values to its all contiguous locations or to some of them with
some initial values for avoiding garbage values those are already in it. It can be directly done with the help of assignment
operator.
A one-dimensional array is initialized as follows: array declaration follows assignment operator and a list of values that are
separated by commas enclosed with in curly braces. This process is also called as initialization at compile-time.
Ex:
int
a[7]={12,45,54,2,87,76,3};
Once the above array gets initialized, the memory map for it will be as follows:
From this memory map, we can observe that an array subscript value (or index) starts from 0 and ends with n-1, where n is
the size of the array. Usually, the first elements location is called the base address of the array. Each element is uniquely
identified with the help of array name and its subscript value 1 or base address+ (pos-1) * sizeof(type). . e.g., 4th element
of
array
a
is
identified
with
a[3]
or
1000+(4-1)*2=1006.
Reading
and
printing
one-dimensional
array:
A One-Dimensional arrays locations can be filled with input values from keyboard with the help of scanf() statement. Because
an array consists of more than one element, we should require a loop counter for keeping track of index values. The loop
counter is always an integer value that begins with 0 and ends with n-1. The loop counter should be incremented by 1 for
keeping track of next immediate indexes. For each indexed element, scanf() statement expects an input value from
programmer.
This
process
can
be
depicted
with
the
help
of
the
following
statement:
for(i=0;i$
<
$;i++)
scanf(%d,&a[i]);
The above statement first reads a[0], then a[1], a[2], a[3]and so on. This process is also called as initialization at run-time.
Once an array is read, it can be accessed directly or sequentially with the help of printf() statement. If we want an element at
particular
position,
then
we
should
give
the
following
argument
to
printf()
:
a[position-1].
E.g.,
we
want
the
element
at
5th
position,
then
printf(Element
we
should
at
5th
give
a[4]
to
position
printf()
statement:
is
%d,a[4]);
If we want to access all the elements in the array sequentially, then we can use printf() statement along with a loop as follows:
printf(\n
The
for(i=0;i$
array
elements
>
Two-Dimensional
are:);
$n;i++)
printf(%d\t,a[i]);
arrays:
A Two-Dimensional array looks like array name followed by two subscripts. It is very helpful to represent matrices in
mathematics or tables in business. The first subscript is used to denote the Number of rows and second is used to denote the
number of columns. The total number of elements a two-dimensional array holds is the product of values of both subscript
values.
Declaring
Two-Dimensional
array:
Just like an ordinary variable, an array should be declared before it is used. A two-dimensional array can be declared as
follows:
In
this
syntax,
is any basic data type such as int, float, char or double or any derived data type such as long int, short int and so on.
$ < $data type$ > $ is any basic data type such as int, float, char or double or any derived data type such as long int, short int
and so on.
$ < $array_name$ > $ is any valid identifier.
row
Ex:
float
and
column
values
are
any
non-negative
integer
constants
or
integer
expressions.
int
a[5][3];
//
two-dimensional
array
capable
of
holding
15
(5*3)
elements
of
type
int
#
define
ROW
10
#
define
COLUMN
5
b[ROW][COLUMN];
//2-D
array
capable
of
holding
15
elements
of
type
float
Initializing
Two-Dimensional
array:
Initializing Two-dimensional array is the process of assigning values to its all contiguous locations or to some of them with
some initial values for avoiding garbage values those are already in it. It can be directly done with the help of assignment
operator.
A Two-dimensional array is initialized as follows: array declaration follows assignment operator and a list of values that are
separated
by
commas
enclosed
with
in
curly
braces.
Ex:
int
a[3][4]={{12,45,54,2},{87,76,3,4},{54,64,34,23}};
Once the above array gets initialized, the values will be stored in memory. The following memory map depicts this thing:
From this memory map, we can observe that a Two-Dimensional arrays rows subscript value as well as columns subscripts
value
start
from
0
and
end
with
n-1.
Reading
and
printing
Two-Dimensional
array:
A Two-Dimensional arrays locations can be filled with input values from keyboard with the help of scanf() statement. Because
an array consists of more than one element, we should require loop counters for keeping track of index values for both rows
and columns. The loop counters are always integer values those begin with 0 and ends with n-1. The loop counters should be
incremented by 1 for keeping track of next immediate indexes. For each indexed element, scanf() statement expects an input
value from programmer. This process can be depicted with the help of the following statement:
for(i=0;i$ < $m;i++)
// m: No.of rows i: loop counter for rows
for(j=0;j$ < $n;j++)
// n: No.of columns j: loop counter for columns
scanf(%d,&a[i][j]);
The
above
statement
first
reads
a[0][0],
then
a[0][1],
a[0][2],
a[0][3]and
so
on.
Once an array is read, it can be accessed directly or sequentially with the help of printf() statement. If we want an element at
particular position, then we should give the following argument to printf() : a[row-1][column-1]. E.g., we want the element at
3rd
row
and
2nd
column
position,
then
we
should
give
a[2][1]
to
printf()
statement:
printf(Element
at
3rd
row
and
2nd
column
position
is
%d,a[2][1]);
We can access all the elements in the array sequentially. For this, we use printf() statement along with two loops as follows:
printf(\n The array elements are:);
for(i=0;i$ < $m;i++)
for(j=0;j$ < $n;j++)
printf(%d\t,a[i][j]);
Pointers
A Pointer is a special type of variable that holds the address as a data item in it. The address may be of one of these: variable, array, function, structure or another pointer.
Usually, an ordinary variable holds a number or a character as a data item in it. Instead, pointer holds the address. If a variable occupies more than one byte, pointer holds the first byte
(or byte0) address. As this is a variable, the address in a pointer can be changed. Mostly, pointer uses 2 or 4 bytes to hold the addresses. In short, a pointer variable is a group of cells
Advantages of pointers
Pointers are used frequently in C, as they offer a number of benefits to the programmers. These include:
Pointers can be used to access and manipulate data stored in memory directly.
Pointers provide an efficient way to create and manipulate efficient data structures such as stacks, queues, linked lists, trees and graphs.
Pointers increase the execution speed and thus reduce the programs execution time.
The use of pointer arrays to strings results in saving of data storage space in memory.
Pointers allow to change the calling functions arguments and to return multiple values from called function.
Pointers permit references to functions and thereby facilitating passing of functions as arguments to other functions.
The real power of C lies in the proper use of pointers. The misuse of pointers causes serious problems such as system crash.
Referencing operator is a unary operator. It acts on one operand at a time. It returns the address of operand. The operand must be a named region of storage (like int variable, array
variable, pointer variable etc.) for which a value may be assigned. The operand must not be a constant or an expression or a register variable. This operator is also called as address of
operator.
The & operator should be preceded with the operand in order to return the address.
Valid expressions:
&a
&c
int a=20;
Suppose that the variable a occupies 2 bytes on 16-bit computer. This can be represented as follows:
From this memory map, it is clear that the data item 20 can be accessed with the help of name of variable as well as address of variable (or memory location or reference).
The conversion character %x is used to print address in hexa-decimal notation. The conversion character %u is used to print the address in decimal notation (especially, a positive
Program to print the address of variable in hexa decimal and decimal notations
#include
main()
int a=20;
printf(\n The address of a=%u,&a); // prints the address as a positive long integer
Dereferencing operator is a unary operator. It acts on one operand at a time. It returns the value stored at the address of operand. The operand must be an address, a pointer that holds
address or a pointer expression. This operator is also called as value at address operator or indirection operator.
The * operator should be preceded with the operand in order to return the value at address of operand.
$**\& $num
Invalid expressions:
*2009
*num
2. Initialize it.
3. Access the original value through a pointer or perform any other operation on it.
Declaration of a pointer variable: Just like an ordinary variable, a pointer variable should be declared before it is used. This declaration has the following form:
In this syntax,
$ < $storage_class$ > $ is any one of the auto, static, extern or register.
$ < $data typte$ > $ is any one of int, float, char, double or void or data types such as signed int, long int etc,
The symbol * should be preceded with the name(s) of pointer(s).
<$ < $pointer_name$ > $ is any valid identifier. If there are more pointer_names, those should be separated with commas.
Ex:
int *iptr;
//pointer-to-int
float *fptr; //pointer-to-float
char *cptr; //pointer-to-char
The declaration int *iptr; does not mean that iptr is going to contain integer value. What it means is, iptr is a pointer variable that is going to hold the address of an integer value.
Hence, iptr is a pointer that points to integer value. In short, iptr is a pointer-to-int.
In the same way, the pointer fptr is going to contain the address of floating point value. Hence, fptr is a pointer that points to a floating point value. In short, fptr is a pointer-tofloat.
Similarly, the pointer cptr is going to contain the address of a character. Hence, cptr is a pointer that points to a character. In short, cptr is a pointer-to-char.
Initialization of a pointer variable: A pointer variable should be initialized with an address before it is used. The initialization of a pointer variable takes the following form:
Where Lvalue is any pointer variable and Rvalue is a variable preceded with an ampersand or a pointer of same type of LValue.
Ex:
int a=40;
int *iptr1,*iptr2;
//Declaring pointer variables: iptr1,iptr2
iptr1=&a;
//Initializing pointer variable: iptr1
iptr2=iptr1;
//Initializing pointer variable: iptr2
Whenever a pointer variable is initialized with the address of an ordinary variable or a pointer variable, we can say that the pointer variable points to that ordinary variable or pointer
variable. This can be represented as follows:
Once a pointer variable is initialized, it can be used to access the address as well as content of object to which it is pointed to. The following program demonstrates this:
main()
int a=40;
int *iptr;
//Declaration: pointer-to-int
iptr=&a;
}
Operations on pointers:
Pointer arithmetic
Pointer
Expression
Ptr+n
Ptr-n
Ptr++
Description
Ptr=Ptr+n*sizeof(data_type_of_pointer)
Use the original value of ptr and then n*sizeof(data_type_of_pointer) is
added to ptr after statement execution.
Ptr=Ptr-n*sizeof(data_type_of_pointer)
Use the original value of ptr and then n*sizeof(data_type_of_pointer) is
subtracted from ptr after statement execution.
Ptr=Ptr+ sizeof(data_type_of_pointer)
Use the original value of ptr and then ptr is incremented after statement
Ptr-++Ptr
--Ptr
*Ptr++
*Ptr-*++Ptr
*--Ptr
(*Ptr)++
(*Ptr)--
execution.
Ptr=Ptr- sizeof(data_type_of_pointer)
Use the original value of ptr and then ptr is decremented after statement
execution.
Ptr=Ptr+ sizeof(data_type_of_pointer)
Original Ptr is incremented before the execution of statement.
Ptr=Ptr- sizeof(data_type_of_pointer)
Original Ptr is decremented before the execution of statement.
*(Ptr++)
Retrieve the content of the location pointed to by pointer and then
increment ptr.
*(Ptr--)
Retrieve the content of the location pointed to by pointer and then
decrement ptr.
*(++ptr)
Increment pointer and then retrieve the content of the new location
pointed to by Ptr.
*(--Ptr)
Decrement pointer and then retrieve the content of the new location
pointer to by Ptr.
Retrieve the content of *Ptr of the location pointed to by Ptr, and then
Increment content of the location pointed to by Ptr. For pointer type
content, use pointer arithmetic of standard arithmetic.
Retrieve the content *Ptr of the location pointed to by Ptr, then decrement
the content of that location; Ptr is not changed.
Pointer comparisons:
Two pointers can be compared by using relational operators as well as logical operators. When these operators encountered, these expressions may return either true or false. program
main()
int a=40,b=34;
int *iptr1,*iptr2;
iptr1=&a;
iptr2=&b;
* Comparing two pointers those point to different types of objects lead to error, although they have addresses as data items in them.
float x;
float a[10];
Declare a function that takes a character as argument and returns a character as return value?
char fun(char);
Declare a pointer-to-float?
float *fptr;
float * fun(void);
Declare a pointer-to-function that takes a double argument and returns a double value?
double (*fun)(double);
int (*arrptr)[10];
int *a[10];
char *cptr;
char **cptr;
char ***cptr;
float (*fun())[10];
float (*f[10])();
This generally means that a program tried to access the memory it shouldnt have, invariably as a result of improper pointer use. The most likely causes could be inadvertent use of null
pointers or uninitialized, misaligned, or otherwise improperly allocated pointers, corruption of malloc area and mismatched function arguments, especially involving pointers; two possible
cases are scanf(%d,i) (without ampersand) and fprintf(invalid FILE* argument).
A segmentation fault occurs when an attempt is made to access memory whose address is well-formed, but to which access cant be granted. This might be due to either a
protection fault or an invalid page fault.
2) Un-initialized pointer:
This generally occurs when we declared a pointer, forgot to initialize it with an address and tried to access the content through pointer. E.g.,
int *ptr, val=300;
*ptr=val; /*Error*/
3) When we want to assign a value to a pointer variable, then that assignment leads to an error.
E.g.,
int *p, val=24;
p=val; /*Error*/
4) When we want to assign the address of un-initialized variable to a pointer, then that assignment also leads to an error.
E.g., int val,*ptr;
ptr=&val; /*Error*/
5) When we want to compare pointers those point to different objects, that comparison lead to an error
E.g., char name1[20],name2[20];
char *p1=name1;
char *p2=name2;
if(p1>p2).
/*Error*/
Pointers
A Pointer is a special type of variable that holds the address as a data item in it. The address may be of one of these: variable, array, function, structure or another pointer.
Usually, an ordinary variable holds a number or a character as a data item in it. Instead, pointer holds the address. If a variable occupies more than one byte, pointer holds the first byte
(or byte0) address. As this is a variable, the address in a pointer can be changed. Mostly, pointer uses 2 or 4 bytes to hold the addresses. In short, a pointer variable is a group of cells
Advantages of pointers
Pointers are used frequently in C, as they offer a number of benefits to the programmers. These include:
Pointers can be used to access and manipulate data stored in memory directly.
Pointers provide an efficient way to create and manipulate efficient data structures such as stacks, queues, linked lists, trees and graphs.
Pointers increase the execution speed and thus reduce the programs execution time.
The use of pointer arrays to strings results in saving of data storage space in memory.
Pointers allow to change the calling functions arguments and to return multiple values from called function.
Pointers permit references to functions and thereby facilitating passing of functions as arguments to other functions.
The real power of C lies in the proper use of pointers. The misuse of pointers causes serious problems such as system crash.
Referencing operator is a unary operator. It acts on one operand at a time. It returns the address of operand. The operand must be a named region of storage (like int variable, array
variable, pointer variable etc.) for which a value may be assigned. The operand must not be a constant or an expression or a register variable. This operator is also called as address of
operator.
The & operator should be preceded with the operand in order to return the address.
Valid expressions:
&a
&c
int a=20;
Suppose that the variable a occupies 2 bytes on 16-bit computer. This can be represented as follows:
From this memory map, it is clear that the data item 20 can be accessed with the help of name of variable as well as address of variable (or memory location or reference).
The conversion character %x is used to print address in hexa-decimal notation. The conversion character %u is used to print the address in decimal notation (especially, a positive
Program to print the address of variable in hexa decimal and decimal notations
#include
main()
int a=20;
printf(\n The address of a=%u,&a); // prints the address as a positive long integer
Dereferencing operator is a unary operator. It acts on one operand at a time. It returns the value stored at the address of operand. The operand must be an address, a pointer that holds
address or a pointer expression. This operator is also called as value at address operator or indirection operator.
The * operator should be preceded with the operand in order to return the value at address of operand.
$**\& $num
Invalid expressions:
*2009
*num
2. Initialize it.
3. Access the original value through a pointer or perform any other operation on it.
Declaration of a pointer variable: Just like an ordinary variable, a pointer variable should be declared before it is used. This declaration has the following form:
In this syntax,
$ < $storage_class$ > $ is any one of the auto, static, extern or register.
$ < $data typte$ > $ is any one of int, float, char, double or void or data types such as signed int, long int etc,
The symbol * should be preceded with the name(s) of pointer(s).
<$ < $pointer_name$ > $ is any valid identifier. If there are more pointer_names, those should be separated with commas.
Ex:
int *iptr;
//pointer-to-int
float *fptr; //pointer-to-float
char *cptr; //pointer-to-char
The declaration int *iptr; does not mean that iptr is going to contain integer value. What it means is, iptr is a pointer variable that is going to hold the address of an integer value.
Hence, iptr is a pointer that points to integer value. In short, iptr is a pointer-to-int.
In the same way, the pointer fptr is going to contain the address of floating point value. Hence, fptr is a pointer that points to a floating point value. In short, fptr is a pointer-tofloat.
Similarly, the pointer cptr is going to contain the address of a character. Hence, cptr is a pointer that points to a character. In short, cptr is a pointer-to-char.
Initialization of a pointer variable: A pointer variable should be initialized with an address before it is used. The initialization of a pointer variable takes the following form:
Where Lvalue is any pointer variable and Rvalue is a variable preceded with an ampersand or a pointer of same type of LValue.
Ex:
int a=40;
int *iptr1,*iptr2;
//Declaring pointer variables: iptr1,iptr2
iptr1=&a;
//Initializing pointer variable: iptr1
iptr2=iptr1;
//Initializing pointer variable: iptr2
Whenever a pointer variable is initialized with the address of an ordinary variable or a pointer variable, we can say that the pointer variable points to that ordinary variable or pointer
variable. This can be represented as follows:
main()
int a=40;
int *iptr;
//Declaration: pointer-to-int
iptr=&a;
}
Operations on pointers:
Pointer arithmetic
Pointer
Expression
Ptr+n
Ptr-n
Ptr++
Ptr-++Ptr
--Ptr
*Ptr++
*Ptr-*++Ptr
*--Ptr
(*Ptr)++
(*Ptr)--
Description
Ptr=Ptr+n*sizeof(data_type_of_pointer)
Use the original value of ptr and then n*sizeof(data_type_of_pointer) is
added to ptr after statement execution.
Ptr=Ptr-n*sizeof(data_type_of_pointer)
Use the original value of ptr and then n*sizeof(data_type_of_pointer) is
subtracted from ptr after statement execution.
Ptr=Ptr+ sizeof(data_type_of_pointer)
Use the original value of ptr and then ptr is incremented after statement
execution.
Ptr=Ptr- sizeof(data_type_of_pointer)
Use the original value of ptr and then ptr is decremented after statement
execution.
Ptr=Ptr+ sizeof(data_type_of_pointer)
Original Ptr is incremented before the execution of statement.
Ptr=Ptr- sizeof(data_type_of_pointer)
Original Ptr is decremented before the execution of statement.
*(Ptr++)
Retrieve the content of the location pointed to by pointer and then
increment ptr.
*(Ptr--)
Retrieve the content of the location pointed to by pointer and then
decrement ptr.
*(++ptr)
Increment pointer and then retrieve the content of the new location
pointed to by Ptr.
*(--Ptr)
Decrement pointer and then retrieve the content of the new location
pointer to by Ptr.
Retrieve the content of *Ptr of the location pointed to by Ptr, and then
Increment content of the location pointed to by Ptr. For pointer type
content, use pointer arithmetic of standard arithmetic.
Retrieve the content *Ptr of the location pointed to by Ptr, then decrement
the content of that location; Ptr is not changed.
Pointer comparisons:
Two pointers can be compared by using relational operators as well as logical operators. When these operators encountered, these expressions may return either true or false. program
main()
int a=40,b=34;
int *iptr1,*iptr2;
iptr1=&a;
iptr2=&b;
* Comparing two pointers those point to different types of objects lead to error, although they have addresses as data items in them.
float x;
float a[10];
Declare a function that takes a character as argument and returns a character as return value?
char fun(char);
Declare a pointer-to-float?
float *fptr;
float * fun(void);
Declare a pointer-to-function that takes a double argument and returns a double value?
double (*fun)(double);
int (*arrptr)[10];
int *a[10];
char *cptr;
char **cptr;
char ***cptr;
float (*fun())[10];
float (*f[10])();
This generally means that a program tried to access the memory it shouldnt have, invariably as a result of improper pointer use. The most likely causes could be inadvertent use of null
pointers or uninitialized, misaligned, or otherwise improperly allocated pointers, corruption of malloc area and mismatched function arguments, especially involving pointers; two possible
cases are scanf(%d,i) (without ampersand) and fprintf(invalid FILE* argument).
A segmentation fault occurs when an attempt is made to access memory whose address is well-formed, but to which access cant be granted. This might be due to either a
protection fault or an invalid page fault.
2) Un-initialized pointer:
This generally occurs when we declared a pointer, forgot to initialize it with an address and tried to access the content through pointer. E.g.,
int *ptr, val=300;
*ptr=val; /*Error*/
3) When we want to assign a value to a pointer variable, then that assignment leads to an error.
E.g.,
int *p, val=24;
p=val; /*Error*/
4) When we want to assign the address of un-initialized variable to a pointer, then that assignment also leads to an error.
E.g., int val,*ptr;
ptr=&val; /*Error*/
5) When we want to compare pointers those point to different objects, that comparison lead to an error
E.g., char name1[20],name2[20];
char *p1=name1;
char *p2=name2;
if(p1>p2).
/*Error*/
Pointers
A Pointer is a special type of variable that holds the address as a data item in it. The address may be of one of these: variable, array, function, structure or another pointer.
Usually, an ordinary variable holds a number or a character as a data item in it. Instead, pointer holds the address. If a variable occupies more than one byte, pointer holds the first byte
(or byte0) address. As this is a variable, the address in a pointer can be changed. Mostly, pointer uses 2 or 4 bytes to hold the addresses. In short, a pointer variable is a group of cells
Advantages of pointers
Pointers are used frequently in C, as they offer a number of benefits to the programmers. These include:
Pointers can be used to access and manipulate data stored in memory directly.
Pointers provide an efficient way to create and manipulate efficient data structures such as stacks, queues, linked lists, trees and graphs.
Pointers increase the execution speed and thus reduce the programs execution time.
The use of pointer arrays to strings results in saving of data storage space in memory.
Pointers allow to change the calling functions arguments and to return multiple values from called function.
Pointers permit references to functions and thereby facilitating passing of functions as arguments to other functions.
The real power of C lies in the proper use of pointers. The misuse of pointers causes serious problems such as system crash.
Referencing operator is a unary operator. It acts on one operand at a time. It returns the address of operand. The operand must be a named region of storage (like int variable, array
variable, pointer variable etc.) for which a value may be assigned. The operand must not be a constant or an expression or a register variable. This operator is also called as address of
operator.
The & operator should be preceded with the operand in order to return the address.
Valid expressions:
&a
&c
int a=20;
Suppose that the variable a occupies 2 bytes on 16-bit computer. This can be represented as follows:
From this memory map, it is clear that the data item 20 can be accessed with the help of name of variable as well as address of variable (or memory location or reference).
The conversion character %x is used to print address in hexa-decimal notation. The conversion character %u is used to print the address in decimal notation (especially, a positive
Program to print the address of variable in hexa decimal and decimal notations
#include
main()
int a=20;
printf(\n The address of a=%u,&a); // prints the address as a positive long integer
Dereferencing operator is a unary operator. It acts on one operand at a time. It returns the value stored at the address of operand. The operand must be an address, a pointer that holds
address or a pointer expression. This operator is also called as value at address operator or indirection operator.
The * operator should be preceded with the operand in order to return the value at address of operand.
$**\& $num
Invalid expressions:
*2009
*num
2. Initialize it.
3. Access the original value through a pointer or perform any other operation on it.
Declaration of a pointer variable: Just like an ordinary variable, a pointer variable should be declared before it is used. This declaration has the following form:
In this syntax,
$ < $storage_class$ > $ is any one of the auto, static, extern or register.
$ < $data typte$ > $ is any one of int, float, char, double or void or data types such as signed int, long int etc,
The symbol * should be preceded with the name(s) of pointer(s).
<$ < $pointer_name$ > $ is any valid identifier. If there are more pointer_names, those should be separated with commas.
Ex:
int *iptr;
//pointer-to-int
float *fptr; //pointer-to-float
char *cptr; //pointer-to-char
The declaration int *iptr; does not mean that iptr is going to contain integer value. What it means is, iptr is a pointer variable that is going to hold the address of an integer value.
Hence, iptr is a pointer that points to integer value. In short, iptr is a pointer-to-int.
In the same way, the pointer fptr is going to contain the address of floating point value. Hence, fptr is a pointer that points to a floating point value. In short, fptr is a pointer-tofloat.
Similarly, the pointer cptr is going to contain the address of a character. Hence, cptr is a pointer that points to a character. In short, cptr is a pointer-to-char.
Initialization of a pointer variable: A pointer variable should be initialized with an address before it is used. The initialization of a pointer variable takes the following form:
Where Lvalue is any pointer variable and Rvalue is a variable preceded with an ampersand or a pointer of same type of LValue.
Ex:
int a=40;
int *iptr1,*iptr2;
//Declaring pointer variables: iptr1,iptr2
iptr1=&a;
//Initializing pointer variable: iptr1
iptr2=iptr1;
//Initializing pointer variable: iptr2
Whenever a pointer variable is initialized with the address of an ordinary variable or a pointer variable, we can say that the pointer variable points to that ordinary variable or pointer
variable. This can be represented as follows:
main()
int a=40;
int *iptr;
//Declaration: pointer-to-int
iptr=&a;
}
Operations on pointers:
Pointer arithmetic
Pointer
Expression
Ptr+n
Ptr-n
Ptr++
Ptr-++Ptr
--Ptr
*Ptr++
*Ptr--
Description
Ptr=Ptr+n*sizeof(data_type_of_pointer)
Use the original value of ptr and then n*sizeof(data_type_of_pointer) is
added to ptr after statement execution.
Ptr=Ptr-n*sizeof(data_type_of_pointer)
Use the original value of ptr and then n*sizeof(data_type_of_pointer) is
subtracted from ptr after statement execution.
Ptr=Ptr+ sizeof(data_type_of_pointer)
Use the original value of ptr and then ptr is incremented after statement
execution.
Ptr=Ptr- sizeof(data_type_of_pointer)
Use the original value of ptr and then ptr is decremented after statement
execution.
Ptr=Ptr+ sizeof(data_type_of_pointer)
Original Ptr is incremented before the execution of statement.
Ptr=Ptr- sizeof(data_type_of_pointer)
Original Ptr is decremented before the execution of statement.
*(Ptr++)
Retrieve the content of the location pointed to by pointer and then
increment ptr.
*(Ptr--)
*++Ptr
*--Ptr
(*Ptr)++
(*Ptr)--
Pointer comparisons:
Two pointers can be compared by using relational operators as well as logical operators. When these operators encountered, these expressions may return either true or false. program
main()
int a=40,b=34;
int *iptr1,*iptr2;
iptr1=&a;
iptr2=&b;
* Comparing two pointers those point to different types of objects lead to error, although they have addresses as data items in them.
float x;
float a[10];
Declare a function that takes a character as argument and returns a character as return value?
char fun(char);
Declare a pointer-to-float?
float *fptr;
float * fun(void);
Declare a pointer-to-function that takes a double argument and returns a double value?
double (*fun)(double);
int (*arrptr)[10];
int *a[10];
char *cptr;
char **cptr;
char ***cptr;
float (*fun())[10];
float (*f[10])();
This generally means that a program tried to access the memory it shouldnt have, invariably as a result of improper pointer use. The most likely causes could be inadvertent use of null
pointers or uninitialized, misaligned, or otherwise improperly allocated pointers, corruption of malloc area and mismatched function arguments, especially involving pointers; two possible
cases are scanf(%d,i) (without ampersand) and fprintf(invalid FILE* argument).
A segmentation fault occurs when an attempt is made to access memory whose address is well-formed, but to which access cant be granted. This might be due to either a
protection fault or an invalid page fault.
2) Un-initialized pointer:
This generally occurs when we declared a pointer, forgot to initialize it with an address and tried to access the content through pointer. E.g.,
int *ptr, val=300;
*ptr=val; /*Error*/
3) When we want to assign a value to a pointer variable, then that assignment leads to an error.
E.g.,
int *p, val=24;
p=val; /*Error*/
4) When we want to assign the address of un-initialized variable to a pointer, then that assignment also leads to an error.
E.g., int val,*ptr;
ptr=&val; /*Error*/
5) When we want to compare pointers those point to different objects, that comparison lead to an error
E.g., char name1[20],name2[20];
char *p1=name1;
char *p2=name2;
if(p1>p2).
/*Error*/
Pointer as an argument
Pointers can also be passed as arguments to a function as normal values are being passed. This method is also known as call by reference. By using these pointers, the calling
functions arguments can be changed from called function. Whenever we want to pass a pointer as an argument, these things should be carried out:
In function prototype, place an * after the type of argument to specify that we are passing a pointer as an argument.
In function call, place the argument- the address of operator followed by name of argument or the pointer that is declared earlier.
//function call
Pointers can also be returned to the calling function from called function as normal values. When we want to return a pointer to the calling function from called function, we should do
these:
In function prototype, place an * after the return type to indicate that the function returns a pointer.
In calling function, there should be a pointer variable that is declared to hold the pointer that is returned. However, both types should be the same to avoid ambiguities.
Develop the function definition as specified in function prototype. In function definition, the return statement, at end, should consist of an & before the return value or a pointer that is
declared earlier.
* Returning a pointer to local argument of called function to calling function gives you a warning.
A program that demonstrates pointer as return value
Assign the name of the function to that pointer. The name of the function itself acts as an address of function.
E.g., addptr=add; // add should be the name of function
3. Call the function by using pointer in the same way as we call a function.
E.g., x=(*addptr)(10,20);
The above statement is used to call that function which is already assigned to pointer-to-function.
A program that demonstrates pointer-to-function
#include$ < $stdio.h$ > $
int add(int,int); //function prototype No change, give prototype normally.
main()
{
int a,b,c;
int (*addptr)(int,int); //step-1: pointer-to-function declaration
printf(\n Enter the values of a and b: );
scanf(%d%d,&a,&b);
addptr=add; //step-2: Assign name of function to the pointer
c=(*addptr)(a,b); //step-3 call the function using pointer
printf(\n The result=%d,c);
}
int add(int x,int y) //function definition- No change, give definition normally
{
int z;
z=x+y;
return z;
}
Output:
Enter the values of a and b: 10
12
The result=22
A pointer-to-function can be passed to another function as an argument. This allows one function to be transferred to another function. Let us refer to the first function as the guest
function and the second function as host function. Thus the guest function is passed to the host function, where it can be accessed. When we want to pass a function as an argument
to another function, do the following:
1)
2)
3)
4)
While calling the host function, place the name of the guest function as an argument. The name itself serves as a pointer to guest function.
Give the definition of guest function as usual.
In the definition of host function, place a pointer to guest function as an argument.
In the definition of host function, call guest function for further process.
//step-1
b=32
Casting pointers
A pointer always has a type associated with it. As we can convert a variable of one type to another, we can also convert one type of pointer to another type of pointer. This process of
conversion is called as casting pointers. Unlike variables, we cant assign one type of pointer variable with another type of pointer variable, although both of them have memory
addresses as their values. This is known as incompatibility of pointers.
We cant use the assignment operator with the pointers of different types. We can, however, make explicit assignment between two incompatible pointer types by using cast
operator, as we do with fundamental types. The cast operator can be used as follows:
$ < $ptr1$ > $=($ < $data type$ > $ *)$ < $ptr2$ > $;
In this syntax, ptr2 is a pointer variable of a data type that is going to be converted to the type of ptr1. Usually, the is same as the type of $ < $ptr1$ >
Program that demonstrates casting from one type to another
#include$ < $stdio.h$ > $
main()
{
int a=65;
int *iptr=&a;
char *cptr;
cptr=(char *)iptr;
printf("%c",*cptr);
}
Output:
A
Though arrays can be used for data storage, they are of fixed size. The programmer must know the size of the array while writing the program. In most situations, it is not possible to
know the size of the memory required until run time. At execution time, a program can request more memory from a free memory pool (heap). Dynamic memory allocation refers to the
allocation of such memory during program execution. The only way to access this dynamically allocated memory is through pointers.
What are the differences between dynamic memory allocation and static memory allocation?
compile time.
Fixed number of bytes will be allocated.
The memory is allocated in memory
stack.
* The limit for dynamic memory allocation can be as large as the amount of available physical memory in the computer or the amount of available virtual memory in a virtual memory
system.
C supports many built-in standard library functions for efficient dynamic memory
files stdlib.h, alloc.h and malloc.h. These functions are: malloc(), calloc(), realloc() and free().
allocation
de-allocation.
Their
prototypes
are
declared
in
the
header
Return value:
On success, i.e., if free memory is available, malloc() returns a pointer to the newly allocated memory. Usually, it is generic pointer. Hence, it should be typecast to
appropriate data type before using it to access the memory allocate.
On failure, i.e., if enough free memory does not exist for block, malloc() returns NULL. The constant NULL is defined in stdio.h to have a value zero. Hence, it is safe to
check the return value.
Ex: 1) malloc(30); allocates 30 bytes of memory and returns the address of byte0.
2) malloc(sizeof(float)); allocates 4 bytes of memory and returns the address of byte0.
What do malloc(-20) and malloc(0) return?
The parameter to malloc() function should be an unsigned integer. If we pass any negative value as an argument, then NULL is returned. So, malloc(-20) returns NULL.
Though the value 0 is not a negative integer, malloc(0) does not return pointer to 0 bytes or NULL pointer. Instead, it also returns the constant NULL.
2) calloc() allocates multiple blocks of memory
The function malloc() has the following prototype:
void *calloc(size_t nitems,size_t size);
calloc() provides access to the C memory heap, which is available for dynamic allocation of variable-sized blocks of memory.
Arguments: Unlike malloc(), the function calloc() accepts two arguments: nitems and size. The parameter nitems specifies the number of items to allocate and size specifies the size of
each item.
Return value:
On success, i.e., if free memory is available, calloc() returns a pointer to the newly allocated memory. Usually, it is generic pointer. Hence, it should be typecast to appropriate data type before
using it to access the memory allocated.
On failure, i.e., if enough free memory does not exist for block, calloc() returns NULL. The constant NULL is defined in stdio.h to have a value zero. Hence, it is safe to verify the return value
before using it.
Ex: 1) calloc(3,5); allocates 15 bytes of memory and returns the address of byte0.
2) malloc(6,sizeof(float)); allocates 24 bytes of memory and returns the address of byte0.
The function realloc() adjusts the amount of memory allocated to the block to size, copying the contents to a new location if necessary.
Arguments: block is the pointer to the memory block that is previously obtained by calling malloc(), calloc() or realloc(). If blockis NULL pointer, realloc() works just like malloc().
Size is the new size for allocated block.
Return value:
On success, this function returns the address of the reallocated block, which might be different from the address of the original block.
On failure, i.e., if the block cant be reallocated or if the size passed is 0, the function returns NULL.
The function realloc() is more useful when the maximum size of allocated block can not be decided in advance.
Ex: int *a;
a=(int *) malloc(30); //first 30 bytes of memory is allocated.
Why does not sizeof operator tell us the size of block of memory pointed by a pointer?
The sizeof operator does not know the at malloc() has been used to allocate pointer; sizeof tells us the size of the pointer itself. There is no portable way to find out the size of a block
allocated by malloc().
a=(int *) realloc(a,15); //later the allocated memory is shrink to 15 bytes.
1.
2.
3.
int i,total;
total=0;
//step-3: Accessing array elements through pointer
for(i=0;i
total=total+*ptr++; //or total=total+*(ptr+i);
printf(\n The sum of array elements=%d,total);
}
Output:
Enter the array size:5
Enter the array elements: 2 4 6 3 1
The array elements are: 2 4
3.
4.
{
temp=*(ptr+i);
*(ptr+i)=*(ptr+j);
*(ptr+j)=temp;
}
}
}
printf(\n After sorting:);
display(ptr,n);
}
Note:
a[i] is equivalent to i[a] or *(a+i) or *(i+a)
Can we use the content of allocated memory after freeing it?
Some early documentation for malloc() stated that the contents of freed memory were left undisturbed. So, few programmers would use the contents of freed memory deliberately.
Function returning 1-D array
By using pointers, a function can return more than one value at a time. As array contains more than one element and array name is the base address, we can return the base address.
This gives us a view that a function can return more than one value at a time. The following program demonstrates this concept:
Write a program to demonstrate a function that returns a sorted array.
#include$ < $stdio.h$ > $
int * sort(int a[ ],int); //function prototype
main()
{
int *p;
int a[10],n,i;
printf("\n Enter the array size:");
scanf("%d",&n);
printf("\n Enter the array elements:");
for(i=0;i
scanf("%d",&a[i]);
printf("\n Before sorting:");
for(i=0;i
printf("%d\t",a[i]);
p=sort(a,n); //function call- p holds the base address of returned array
printf("\n After sorting:");
for(i=0;i
printf("%d\t",*p++);
}
int *sort(int a[ ],int n)
{
int i,j,temp;
for(i=0;i
{
for(j=i+1;j
{
if(a[i]>a[j])
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
return a; //sends the base address of sorted array
}
Output:
Enter the array size: 5
Enter the array elements:35
3
46
43
1
Before sorting: 35
46
43
After sorting: 1
35
43
2.
Once a pointer is declared, it should be initialized with the name of 2-D array that
declared and initialized earlier.
e.g., ptr=a; where a is two-dimensional array.
3.
Now, each element gets accessed with the help of the following expression:
*(*(ptr+i)+j) where i is the index of row and j is the index of column.
Write a program to access a 2-D array using pointer and print it in matrix form
#include$ < $stdio.h$ > $
main()
{
int a[10][10],m,n,i,j;
int (*ptr)[10]; //pointer-to-array
printf(\n Enter the matrix row and column values:);
scanf(%d%d,&m,&n);
printf(\n Enter matrix elements:);
for(i=0;i
for(j=0;j
scanf(%d,&a[i][j]);
ptr=a;
printf(\n The matrix elements:\n);
for(i=0;i
{
for(j=0;j
{
printf(%d\t,*(*(ptr+i)+j));
printf(\n);
}
}
}
Output:
Enter matrix row and column values: 2 2
Enter matrix elements: 23 45 65 232
The matrix elements:
23
45
65
232
3.
4.
scanf("%d",&a[i][j]);
printf(\n First matrix\n);
display(a,m,n);
b=(int **)malloc(p*sizeof(int));
for(i=0;i
a[i]=(int *)malloc(q*sizeof(int));
printf("\n Enter second matrix elements");
for(i=0;i
for(j=0;j
scanf("%d",&b[i][j]);
printf(\n Second matrix\n);
display(b,p,q);
multiply(a,b,m,n,p,q);
free(a);
free(b);
}
}
void display(int **a,int m,int n)
{
nt i,j;
for(i=0;i
{
for(j=0;j
printf("%d\t",a[i][j]);
printf(\n);
}
}
void multiply(int **a,int **b,int m,int n,int p,int q)
{
int **c,i,j;
c=(int **)malloc(m*sizeof(int));
for(i=0;i
c[i]=(int *)malloc(q*sizeof(int));
for(i=0;i
{
for(j=0;j
{
c[i][j]=0;
for(k=0;k
c[i][j]=c[i][j]+a[i][k]*b[k][j];
}
printf(\n The resultant matrix:\n);
display(c,m,q);
free(c);
}
(Click next to read rest of the article)
Array of pointers
There is an array of ints or an array of floats. Similarly, there can also be an array of pointers. Since, a pointer is an address; an array of pointers is nothing but a collection of addresses.
The addresses present in the array of pointers can be addresses of isolated variables or addresses of array elements or any other addresses. All rules that apply to an ordinary array
apply to the array of pointers as well. The following program demonstrates the concept of array of pointers:
Write a program to demonstrate array of pointers.
#include$ < $stdio.h$ > $
main()
{
int *a[4]; //declaration of array of pointers
int i=32,j=45,k=2,l=35,m;
a[0]=&i;
a[1]=&j;
a[2]=&k;
a[3]=&l;
for(m=0;m<3 data-blogger-escaped-m="m" data-blogger-escaped-o:p="o:p">
45
35
6
Write a program to print transpose of a matrix using pointer-to-array
#include$ < $stdio.h$ > $
main()
{
int a[10][10],m,n,i,j;
int (*ptr)[10]; //pointer-to-array
printf(\n Enter the matrix row and column values:);
scanf(%d%d,&m,&n);
printf(\n Enter matrix elements:);
for(i=0;i
for(j=0;j
scanf(%d,&a[i][j]);
ptr=a;
printf(\n The matrix elements:\n);
for(i=0;i
{
for(j=0;j
{
printf(%d\t,*(*(ptr+i)+j));
printf(\n);
}
}
printf(\n The transpose of matrix:\n);
for(i=0;i
{
for(j=0;j
{
printf(%d\t,*(*(ptr+j)+i));
printf(\n);
}
}
}
Output:
Enter matrix row and column values: 2 2
Enter matrix elements: 23 45 65 232
The matrix elements:
24
45
65
232
The transpose of matrix:
24
65
45
232
}
return count;
}
Output:
Given string is= Ravi Chandra
The length of string=12
Write a program to count number of alphabets, digits, spaces and special characters in a line of text
#include$ < $stdio.h$ > $
main()
{
char line[100];
char *ptr;
int nalpha,ndigit,nspace,nspecial;
printf(\n Enter a line of text:);
scanf(%[ ^\n],line);
ptr=line;
nalpha=nspace=ndigit=nspecial=0;
while(*ptr!=\0)
{
if(toupper(*ptr)>=A && toupper(*ptr)<=Z)
nalpha++;
else if(*ptr>=0&&*ptr<=z)
ndigit++;
else if(*ptr= = || *ptr= =\t)
nspace++;
else
nspecial++;
}
printf(\n No.of alphabets=%d,nalpha);
printf(\n No.of digits=%d,ndigits);
printf(\n No.of spaces=%d,nspace);
printf(\n No.of special characters=%d,nspecial);
}
Output:
Enter a line of text: Master says, B.Tech 1st year students are brilliant
No.of alphabets=41
No.of digits=1
No.of spaces=5
No.of special symbols=4
Pointer to a string
Suppose we wish to store the string Hello friend. We may either store it in a character array or we may ask the C compiler to store it some where in memory and assign the address of
that string in a char pointer. This is shown below:
char message[ ]=Hello friend;
char *p=Hello friend;
However, there are differences between these two:
1.
Ex:
The size of character array will be more than the size of the character pointer.
#include$ < $stdio.h$ > $
main()
{
char message[]=Hello friend;
char *p=Hello friend;
printf(\n Size of character array=%d,sizeof(message));
printf(\n Size of character pointer=%d,sizeof(p));
}
A char pointer can be assigned to another char pointer; but a character array cant be assigned to another character array.
#include$ < $stdio.h$ > $
main()
{
char message[ ]=Hello friend;
char mesg2[20];
char *p=Hello friend;
char *q;
mesg2=message; //A blunder
q=p;
//works
}
3.
Once a string has been defined using character array, it cant be initialized to another set of characters. Unlike character array, such an operation is perfectly valid
with char pointer.
Ex:
It is not necessary to include a maximum string size within declaration. However, it is necessary to allocate maximum string size as follows:
for(i=0;i
a[i]=(char *) malloc(15*sizeof(char)); //15 is each strings maximum length
3.
After memory is allocated, the array of character pointers can be initialized and accessed as normal arrays.
for(j=i+1;j
{
if(strcmp(names[i],names[j])>0)
{
temp=names[i];
names[i]=names[j];
names[j]=temp;
}
}
}
Master
Minister
Queen
Servant
1)
As we know that const is the keyword that is used to define a symbolic constant that never be changed throughout the program. E.g., the following is the constant definition:
const float PI=3.1412;
This definition defines a constant PI and this value never be changed through out the program.
Pointer to constant
When we want to deal with a pointer to constant, do the following:
Declare a pointer to constant that has the following form:
2)
3)
printf(%d,*ptr1);
ptr2++; //valida pointer to const can be changed
printf(%d,*ptr2); // prints the value of a[1]
}
Note: These types of pointers are very useful in char pointers, when pointers are to be passed to a function for printing. Suppose, we are writing a function that is aimed to print a
character string, it is good practice to code that function as follows:
void printstring(const char *str)
{
printf(%s,str);
}
The above function accepts a pointer of type const char *(pointer to constant character). The string that is being pointed can never be changed. This is safety measure, since it prevents
the accidental modification of the string that is being passed to called function.
nter-to-constant means that the value is not changed through that pointer, not which is unchanged through any
pointer.
Constant pointer
When we want to deal with a constant pointer, do the following:
1) Declare a constant pointer that has the following form:
$ < $data type$ > $ * const $ < $ptr_name$ > $=$ < $address$ > $;
E.g.,
int a=20;
int * const p=&a;
The above statement declares p as a constant pointer that holds the address of a.
2) Access the constant pointer to print the original content of variable or array whose address is stored.
E.g., printf(%d,*p); //prints the value of a
It is important to note that the value that is being pointed can be changed. In the above example, the value of a can be changed. But the value of constant pointer can never be changed.
i.e., in the above example, p++ or ++p is invalid.
Note: const int * const p=&a;
The above declaration disallows the modification of both p and a. i.e., both pointee and pointer.
What is the difference between const char *p and char* const q?
1)
p is a pointer-to-constant char.
P will be changed. But *p will never be changed.
2)
q is a constant pointer.
q will never be changed. But *q will be changed.