0% found this document useful (0 votes)
7 views

L8- Pointers in C.ppt

This document is a lecture module on pointers in C programming, covering topics such as address operators, pointer variables, dereferencing, pointer arithmetic, and dynamic memory allocation. It explains how pointers can be used with functions, arrays, and includes examples of pointer declarations and operations. The content is intended for first-year students at IMT and IMG, with a disclaimer that it is not copyrighted material and encourages the use of reference books for detailed understanding.

Uploaded by

Ishan
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

L8- Pointers in C.ppt

This document is a lecture module on pointers in C programming, covering topics such as address operators, pointer variables, dereferencing, pointer arithmetic, and dynamic memory allocation. It explains how pointers can be used with functions, arrays, and includes examples of pointer declarations and operations. The content is intended for first-year students at IMT and IMG, with a disclaimer that it is not copyrighted material and encourages the use of reference books for detailed understanding.

Uploaded by

Ishan
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 50

C Programming

Module-8: Pointers in C

IMT and IMG 1st Year

Instructor : Dr. Santosh Singh Rathore


ABV-IIITM Gwalior
Disclaimer

This is NOT A COPYRIGHT MATERIAL

Content for the slides have been taken from the various sources and
from the reference books.

Students need to follow reference books to get the thorough details


of the concepts discussed in slides
Address Operator
• C provides an address operator ‘&', which returns the address of a variable
when placed before it.
• This operator can be read as "the address of ", so &age means address of
age, similarly &sal means address of sal.
Address Operator
• Here we have used %u control sequence to print the address, but this does not
mean that addresses are unsigned integers.
• We have used it since there is no specific control sequence to display address.
• Addresses are just whole numbers. These addresses may be different each time
you nm your program, it depends on which part of memory is allocated by
operating system for this program.
• The address operator cannot be used with a, constant or an expression.
• &j; /*Valid, used with a variable*/
• &arr[ 1]; /*Valid, used with an array element */
• &289; /*Invalid, used with a constant*/
• &(j+k); /*Invalid, used with an expression*/
• This address operator is not new. for us,~ we have already used it in scanf()
function.
• The address of variable is provided to scanf( ), so that it knows where to write
the input value.
Pointers Variables
• A pointer is a variable that store memory address.
• Like all other variables it also has a name, has to be declared and occupies some
space in memory.
• It is called pointer because it points to a particular location in memory by
storing the address of that location.

• Declaration Of Pointer Variables


• Like other variables, pointer variables should also be declared before being
used .
• The general syntax of declaration is
• data_type *pname
• Here pname is the name of pointer variable, which should be a valid C
identifier. The asterisk '*' preceding this name informs the compiler that the
variable is declared as a pointer.
Pointers Variables
• Here data type is known as the base type of pointer. Examples-
• int *iptr;
• float *fptr;
• char *cptr, ch2, ch2;
• Here iptr is a pointer that should point to variables of type int, similarly fptf and
cptr should point to variables of float and char type respectively.
• We can also combine the declaration of simple variables and pointer variables
as we have done in the third declaration statement where ch1 and ch2 are
declared as variables of type char.
• Pointers are also variables so compiler will reserve space for them and they will
also have some address.
• All pointers irrespective of their base type will occupy same space in memory
since all of them contain addresses only.
• Generally 2 bytes are used to store an address (may vary in different
computers), so the compiler allocates 2 bytes for a pointer variable.
Assigning Address To Pointer Variables
• When we declare a pointer variable it contains garbage value i.e, it may be
pointing anywhere in the memory. So we should always assign an address
before using it in the program.
• The use of an unassigned pointer may give unpredictable results and even cause
the program to crash.
• Pointers may be assigned the address of a variable using assignment statement.
• int *ptr, age = 30;
• float *f1ptr, sal = 1500.50;
• iptr = &age;
• fptr = &sal;
• Now iptr contains the address of variable age i.e. it points to variable age, similarly fptr
points to variable sal.
• Since iptr is declared as a pointer of type int, we should assign address of only integer
variables to it.
• If we assign address of some other data type then compiler won't show any error, but the
output will be incorrect.
Assigning Address To Pointer Variables
Dereferencing Pointer Variables
• By placing the indirection operator before a pointer variable, we can access the
variable whose address is stored in the pointer. Example-
• int a = 87;
• float b= 4.5;
• int *p1 = &a;
• float *p2 = &b;

• The term *(&age), where age is a variable. Since &age is an address, so


dereferencing it with * operator will give the variable at that address and the
variable at that address is age. Hence *(&age) is same as writing age.
Dereferencing Pointer Variables
Dereferencing Pointer Variables
Pointer Arithmetic
• All types of arithmetic operations are not possible with pointers. The only valid
operations that can be performed are as-
• Addition of an integer to a pointer and increment operation.
• Subtraction of an integer from a pointer and decrement operation
• Subtraction of a pointer from another pointer of same type.

• Pointer arithmetic is somewhat different from ordinary arithmetic. Here all


arithmetic is performed to the size of base type of pointer.
• For example if we have an integer pointer pi which contains address 1000 then
on incrementing we get 1002 instead of 1001. This is because the size of int
data type is 2.
• Similarly on decrementing pi, we will get 998 instead of 999. The expression
(pi+3 ) will represent the address 1006.
Pointer Arithmetic
Pointer Arithmetic
Pointer Arithmetic
Precedence Of Dereferencing Operator and
Increment/Decrement operators
• The precedence level of * operator and increment/decrement operators is
same and their associativity is from right to left.
• Suppose ptr is an integer pointer and x in an integer variable.

• x ='*ptr++;

• The expression *ptr++ is equivalent to *(ptr++), since these operators


associate from right to left.
• Hence the increment operator will be applied to ptr, and not to *ptr.
• The increment operator is postfix, so first the value of ptr will be used in the
expression and then it will be incremented.
• Hence firstly the integer pointed toby ptr will be dereferenced and assigned
to x and then ptr wi1l be incremented. This is same as- .
• x = *ptr;
• ptr = ptr+ 1;
Precedence Of Dereferencing Operator and
Increment/Decrement operators
Precedence Of Dereferencing Operator and
Increment/Decrement operators
Pointer Comparisons
• The relational operators = =, != , < , <=, >, >= can be used with pointers.
• The operators = = and != are used to compare two pointers for finding
whether they contain same address or not.
• They will be equal only if both are NULL or they contain address of same
variable.
• The use of these operators is valid between pointers or same type or between
NULL pointer and any other pointer, or between void pointer and any other
pointer.
• The relational operators <, >; >=, <= are valid between pointers of same
type.
• These operations make sense only when both the pointers point to elements
of the same array.
Pointer To Pointer
• We can store the address of a pointer variable in some other variable, which
is known as a pointer to pointer variable.
• Similarly we can have a pointer to pointer to pointer variable and this
concept can be extended to any limit, but in practice/only pointer to pointer
is used.
• Pointer to pointer is generally used while passing pointer variables to
functions.
• The syntax of declaring a pointer to pointer is as-
• data_type **pptr;
• Here variable pptr is a pointer to pointer and it can point to a pointer pointing
to a variable of type data_type. The double asterisk used in the declaration
informs the compiler that a pointer to pointer is being declared.
Pointer To Pointer
• int a = 5;·
• int *pa = &a;
• int **ppa = &pa;
• Here type of variable a is int, type of variable pa is (int*) or pointer to int,
and type of variable ppa is (int **) or pointer to pointer to int.
Pointer To Pointer
Pointers and One Dimensional Arrays
• In C language, pointers and arrays are closely related. We can access
the array elements using pointer expressions.
• Actually the compiler also accesses the array elements by converting
subscript notation to pointer notation.
• Following are the main points for understanding the relationship of
pointers with arrays.
• Elements of an array are stored in consecutive memory locations.
• The name of an array is a constant pointer that points to the first
element of the array, i.e. it stores the address of the first element, also
known as the base address of array.
• According to pointer arithmetic, when a pointer variable is
incremented, it points to the next location of its base type.
Pointers And Functions
Pointers And Functions
• Here we are passing addresses of variables a and b in the function call. So the
receiving formal arguments in the function declaration should be declared of
pointer type.
• Whenever function ref( ) is called, two pointer to int variables, named p and q
are created and they are initialized with the addresses of a and, b.
• Now if we dereference 'pointers p and q, we will be able to access variables a
and b from function ref( )
Returning More Than One Value From A Function
Function Returning Pointer
Function Returning Pointer
Function Returning Pointer
Array Of Pointers
• We can declare an array that contains pointers as its elements.
• Every element of this array is a pointer variable that can hold address of
any variable of appropriate type.
• The syntax of declaring an array of pointers is similar to that of declaring
arrays except that an asterisk is placed before the array name.
• datatype *arrayname[size];
• For example to declare an array of size 10 that contains integer pointers
we can write int *arrp[10];
Array Of Pointers
void Pointers
• If we have a pointer to int, then it would be incorrect to assign the address of a
float variable to it.
• But an exception to this rule is a pointer to void.
• A pointer to void is a generic pointer that can point to any data type.
• The syntax of declaration of a void pointer is
• void *vpt;
void Pointers
• A void pointer can't be dereferenced simply by using indirection
operator.
• Before dereferencing, it should be type cast to appropriate pointer
data type.
• For example if vp is a void pointer and it holds the address of an
integer variable then we can't dereference it just by writing *vp.
• We'll have to write *(int *)vp.
• where leftmost asterisk is the indirection, operator and (int *) is
used for typecasting.
• Similarly pointer arithmetic can't be performed on void pointers
without typecasting.
void Pointers
Dynamic Memory Allocation
• The memory allocation that we have done till now was static memory
allocation.
• The memory that could be used by the program was fixed i.e. we could not
increase or decrease the size of memory during the execution of program.
• The process of allocating memory at the time of execution is called dynamic
memory allocation.
• The allocation and release of this memory space can be done with the help of
some built-in-functions whose prototypes are found in alloc.h and stdlib.h
header files.
• These functions take memory from a memory area called heap and release this
memory whenever not required, so that it can be used again for some other
purpose.
• Pointers play an important role in dynamic memory allocation because we can
access the dynamically allocated memory only' through pointers.
malloc()
• Declaration:
• void *malloc(size_t size);
• This function is used to allocate memory dynamically.
• The argument size specifies the number of bytes to be allocated.
• The type size_t is defined in stdlib.h as unsigned int.
• On success malloc( ) returns a pointer to the first byte of allocated memory.
• The returned pointer is of type void, which can be type cast to appropriate type
of pointer.
• It is generally used as
• ptr = (datatype *) malloc (specified size);
• Here ptr is a pointer of type datatype, and specified size is the size in bytes
required to be reserved memory.
• The expression (datatype *) is used to typecast the pointer returned by malloc().
malloc()

• This allocates 10 contiguous bytes of memory space and the address of first
byte is stored in the pointer variable ptr.
• This space can hold 5 integers. The allocated memory contains garbage value.
• ptr = (int *) malloc (5 * sizeof (int));
• This allocates the memory space to hold five integer values.
malloc()
• If there is not sufficient memory available in heap then malloc() returns NULL.
So we should always check the value returned by malloc().
• ptr = (float *) malloc(1O*sizeof(float) );
• if ( ptr == NULL )
• printf("Sufficient memory not available");
• Unlike memory allocated for variables and arrays, -dynamically allocated
memory has no name associated with it.
• So it can be accessed only through pointers. We have a pointer which points to
the first byte of the allocated memory and we can access the subsequent bytes
using pointer arithmetic.
malloc()
calloc()
realloc()
realloc()
free()
Dynamic Arrays
• The memory allocated by malloc(), calloc() and realloc() is always
made up of contiguous bytes.
• Moreover in C there is an equivalence between pointer notation
and subscript notation i.e. we can apply subscripts to a pointer
variable.
• So we can access the dynamically allocated memory through
subscript notation also.
• We can utilize these features to 'create dynamic arrays whose size
can vary during run time.
Dynamic Arrays
Pointers To Functions
• The code of a function resides in memory hence every function has an address like all
other variables in the program.
• We can get the address of function by just writing the function's name without ().
Declaring A Pointer To A Function
• We have seen that functions have addresses, so we can have pointers that can
contain these addresses and hence point to them.
• The syntax for declaration of a pointer to a function is as
• return type (*ptr_name)(type1, type2, ……);
• For example
• float (*fp)( int );
• char (*func_p)(float, char);
• Here fp is a pointer that can point to any function that returns a float value
and accepts an int value argument.
• Similarly func_p is a pointer that can point to functions returning char and
accepting float d char as arguments
Thank you for your attention!

< Questions?

You might also like