0% found this document useful (0 votes)
9 views18 pages

Lecture 6

The document provides an overview of pointers in the C programming language, explaining their definition, declaration, and usage with various data types such as integers, arrays, and functions. It covers concepts like dereferencing, NULL pointers, double pointers, and the sizeof operator, along with examples to illustrate their applications. Additionally, it discusses the advantages of using pointers, including memory management and performance improvements.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views18 pages

Lecture 6

The document provides an overview of pointers in the C programming language, explaining their definition, declaration, and usage with various data types such as integers, arrays, and functions. It covers concepts like dereferencing, NULL pointers, double pointers, and the sizeof operator, along with examples to illustrate their applications. Additionally, it discusses the advantages of using pointers, including memory management and performance improvements.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 18

C Pointers

The pointer in C language is a variable which stores the address of another variable.
This variable can be of type int, char, array, function, or any other pointer. The size of
the pointer depends on the architecture. However, in 32-bit architecture the size of a
pointer is 2 byte.

Consider the following example to define a pointer which stores the address of an
integer.

1. int n = 10;
2. int*p = &n; // Variable p of type pointer is pointing to the address of the variable n
of type integer.

Declaring a pointer

The pointer in c language can be declared using * (asterisk symbol). It is also known
as indirection pointer used to dereference a pointer.( Dereferencing is used to
access or manipulate data contained in memory location pointed to by a pointer.)

1. int *a;//pointer to int


2. char *c;//pointer to char

Pointer Example

An example of using pointers to print the address and value is given below.

As you can see in the above figure, pointer variable stores the address of number
variable, i.e., fff4. The value of number variable is 50. But the address of pointer
variable p is aaa3.

By the help of * (indirection operator), we can print the value of pointer variable p.

Let's see the pointer example as explained for the above figure.

1. #include<stdio.h>
2. int main(){
3. int number=50;
4. int *p;
5. p=&number;//stores the address of number variable
6. printf("Address of p variable is %x \n",p); // p contains the address of the number
therefore printing p gives the address of number.
7. printf("Value of p variable is %d \n",*p); // As we know that * is used to dereference a
pointer therefore if we print *p, we will get the value stored at the address contained
by
8. return 0;
9. }

Output

Address of p variable is fff4


Value of p variable is 50

Pointer to array

1. int arr[10];
2. int *p[10]=&arr; // Variable p of type pointer is pointing to the address of an integer
array arr.

Pointer to a function

1. void show (int);


2. void(*p)(int) = &show; // Pointer p is pointing to the address of a function

Pointer to structure

1. struct st {
2. int i;
3. float f;
4. }ref;
5. struct st *p = &ref;
Advantage of pointer

1) Pointer reduces the code and improves the performance, it is used to


retrieving strings, trees, etc. and used with arrays, structures, and functions.

2) We can return multiple values from a function using the pointer.

3) It makes you able to access any memory location in the computer's memory.

Usage of pointer

There are many applications of pointers in c language.

1) Dynamic memory allocation

In c language, we can dynamically allocate memory using malloc() and calloc()


functions where the pointer is used.

2) Arrays, Functions, and Structures

Pointers in c language are widely used in arrays, functions, and structures. It reduces
the code and improves the performance.

Address Of (&) Operator

The address of operator '&' returns the address of a variable. But, we need to use %u
to display the address of a variable.

1. #include<stdio.h>
2. int main(){
3. int number=50;
4. printf("value of number is %d, address of number is %u",number,&number);
5. return 0;
6. }

Output

value of number is 50, address of number is fff4

NULL Pointer

A pointer that is not assigned any value but NULL is known as the NULL pointer. If you
don't have any address to be specified in the pointer at the time of declaration, you
can assign NULL value. It will provide a better approach.

int *p=NULL;

In the most libraries, the value of the pointer is 0 (zero).


Pointer Program to swap two numbers without using the 3rd variable.

1. #include<stdio.h>
2. int main(){
3. int a=10,b=20,*p1=&a,*p2=&b;
4.
5. printf("Before swap: *p1=%d *p2=%d",*p1,*p2);
6. *p1=*p1+*p2;
7. *p2=*p1-*p2;
8. *p1=*p1-*p2;
9. printf("\nAfter swap: *p1=%d *p2=%d",*p1,*p2);
10.
11. return 0;
12. }

Output

Before swap: *p1=10 *p2=20


After swap: *p1=20 *p2=10

Reading complex pointers

There are several things which must be taken into consideration while reading the
complex pointers in C. Lets see the precedence and associativity of the operators
which are used regarding pointers.

Operator Precedence Associativity

(), [] 1 Left to right

*, identifier 2 Right to left

Data type 3 -

Here, we must notice that,

o (): This operator is a bracket operator used to declare and define the function.
o []: This operator is an array subscript operator
o * : This operator is a pointer operator.
o Identifier: It is the name of the pointer. The priority will always be assigned to
this.
o Data type: Data type is the type of the variable to which the pointer is intended
to point. It also includes the modifier like signed int, long, etc).

How to read the pointer: int (*p)[10].

To read the pointer, we must see that () and [] have the equal precedence. Therefore,
their associativity must be considered here. The associativity is left to right, so the
priority goes to ().

Inside the bracket (), pointer operator * and pointer name (identifier) p have the same
precedence. Therefore, their associativity must be considered here which is right to
left, so the priority goes to p, and the second priority goes to *.

Assign the 3rd priority to [] since the data type has the last precedence. Therefore the
pointer will look like following.

o char -> 4
o * -> 2
o p -> 1
o [10] -> 3

The pointer will be read as p is a pointer to an array of integers of size 10.

Example

How to read the following pointer?

1. int (*p)(int (*)[2], int (*)void))

Explanation

This pointer will be read as p is a pointer to such function which accepts the first
parameter as the pointer to a one-dimensional array of integers of size two and the
second parameter as the pointer to a function which parameter is void and return
type is the integer.

C Double Pointer (Pointer to Pointer)


As we know that, a pointer is used to store the address of a variable in C. Pointer
reduces the access time of a variable. However, In C, we can also define a pointer to
store the address of another pointer. Such pointer is known as a double pointer
(pointer to pointer). The first pointer is used to store the address of a variable whereas
the second pointer is used to store the address of the first pointer. Let's understand it
by the diagram given below.
The syntax of declaring a double pointer is given below.
1. int **p; // pointer to a pointer which is pointing to an integer.

Consider the following example.


1. #include<stdio.h>
2. void main ()
3. {
4. int a = 10;
5. int *p;
6. int **pp;
7. p = &a; // pointer p is pointing to the address of a
8. pp = &p; // pointer pp is a double pointer pointing to the address of pointer p
9. printf("address of a: %x\n",p); // Address of a will be printed
10. printf("address of p: %x\n",pp); // Address of p will be printed
11. printf("value stored at p: %d\n",*p); // value stored at the address conta
ined by p i.e. 10 will be printed
12. printf("value stored at pp: %d\n",**pp); // value stored at the address co
ntained by the pointer stored at pp
13. }
Output
address of a: d26a8734
address of p: d26a8738
value stored at p: 10
value stored at pp: 10
C double pointer example
Let's see an example where one pointer points to the address of another pointer.

As you can see in the above figure, p2 contains the address of p (fff2), and p contains
the address of number variable (fff4).
1. #include<stdio.h>
2. int main(){
3. int number=50;
4. int *p;//pointer to int
5. int **p2;//pointer to pointer
6. p=&number;//stores the address of number variable
7. p2=&p;
8. printf("Address of number variable is %x \n",&number);
9. printf("Address of p variable is %x \n",p);
10. printf("Value of *p variable is %d \n",*p);
11. printf("Address of p2 variable is %x \n",p2);
12. printf("Value of **p2 variable is %d \n",*p);
13. return 0;
14. }
Output
Address of number variable is fff4
Address of p variable is fff4
Value of *p variable is 50
Address of p2 variable is fff2
Value of **p variable is 50
sizeof() operator in C
The sizeof() operator is commonly used in C. It determines the size of the expression
or the data type specified in the number of char-sized storage units. The sizeof()
operator contains a single operand which can be either an expression or a data
typecast where the cast is data type enclosed within parenthesis. The data type
cannot only be primitive data types such as integer or floating data types, but it can
also be pointer data types and compound data types such as unions and structs.

Note:
The output can vary on different machines such as on 32-bit operating
system will show different output, and the 64-bit operating system will show
the different outputs of the same data types.
The sizeof() operator behaves differently according to the type of the operand.
• Operand is a data type
• Operand is an expression
When operand is a data type.
1. #include<stdio.h>
2. int main()
3. {
4. int x=89;//variable declaration.
5. printf("size of the variable x is %d", sizeof(x));// Displaying the size of?x?
variable.
6. printf("\nsize of the integer data type is %d",sizeof(int));//Displaying the size of
integer data type.
7. printf("\nsize of the character data type is %d",sizeof(char));//Displaying the size
of character data type.
8.
9. printf("\nsize of the floating data type is %d",sizeof(float));//Displaying the size
of floating data type.
10. return 0;
11. }
In the above code, we are printing the size of different data types such as int, char,
float with the help of sizeof() operator.
Output
When operand is an expression
1. #include<stdio.h>
2. int main()
3. {
4. double i=78.0;//variable initialization.
5. float j=6.78; //variable initialization.
6. printf("size of (i+j) expression is: %d",sizeof(i+j)); //Displaying the size of the
expression(i+j).
7. return 0;
8. }
In the above code, we have created two variables 'i' and 'j' of type double and float
respectively, and then we print the size of the expression by using sizeof(i+j)
operator.
Output
size of (i+j) expression is : 8

Need of Sizeof
1. To find out number of elements in an array.
Sizeof can be used to calculate number of elements of the array automatically. Let
see Example :
include <stdio.h>
int main()
{
int arr[] = { 1, 2, 3, 4, 7, 98, 0, 12, 35, 99, 14 };
printf("Number of elements:%lu ", sizeof(arr) / sizeof(arr[0]));
return 0;
}
2. To allocate a block of memory dynamically.
sizeof is greatly used in dynamic memory allocation. For example, if we want to
allocate memory for which is sufficient to hold 10 integers and we don’t know the
sizeof(int) in that particular machine.
1. int*ptr=malloc(10*sizeof(int));
In the above example, we use the sizeof() operator, which is applied to the cast of
type int. We use malloc() function to allocate the memory and returns the pointer
which is pointing to this allocated memory. The memory space is equal to the number
of bytes occupied by the int data type and multiplied by 10.

C DEREFERENCE POINTER
As we already know that "what a pointer is", a pointer is a variable that stores the
address of another variable. The dereference operator is also known as an indirection
operator, which is represented by (*). When indirection operator (*) is used with the
pointer variable, then it is known as dereferencing a pointer. When we dereference
a pointer, then the value of the variable pointed by this pointer will be returned.
Why we use dereferencing pointer?
Dereference a pointer is used because of the following reasons:
• It can be used to access or manipulate the data stored at the memory location,
which is pointed by the pointer.
• Any operation applied to the dereferenced pointer will directly affect the value
of the variable that it points to.
Let's observe the following steps to dereference a pointer.
• First, we declare the integer variable to which the pointer points.
1. Int x =9;
• Now, we declare the integer pointer variable.
1. Int *ptr;
• After the declaration of an integer pointer variable, we store the address of 'x'
variable to the pointer variable 'ptr'.
1. ptr=&x;
• We can change the value of 'x' variable by dereferencing a pointer 'ptr' as given
below:
1. *ptr =8;
The above line changes the value of 'x' variable from 9 to 8 because 'ptr' points to the
'x' location and dereferencing of 'ptr', i.e., *ptr=8 will update the value of x.
Let's combine all the above steps:
1. #include <stdio.h>
2. int main()
3. {
4. int x=9;
5. int *ptr;
6. ptr=&x;
7. *ptr=8;
8. printf("value of x is:%d", x);
9. return 0;}
Output

Let's consider another example.


1. #include <stdio.h>
2. int main()
3. {
4. int x=4;
5. int y;
6. int *ptr;
7. ptr=&x;
8. y=*ptr;
9. *ptr=5;
10. printf("The value of x is:%d",x);
11. printf("\n The value of y is:%d",y);
12. return 0;
13. }

In the above code:


• We declare two variables 'x' and 'y' where 'x' is holding a '4' value.
• We declare a pointer variable 'ptr'.
• After the declaration of a pointer variable, we assign the address of the 'x'
variable to the pointer 'ptr'.
• As we know that the 'ptr' contains the address of 'x' variable, so '*ptr' is the
same as 'x'.
• We assign the value of 'x' to 'y' with the help of 'ptr' variable, i.e., y=*ptr
instead of using the 'x' variable.
Note: According to us, if we change the value of 'x', then the value of 'y' will
also get changed as the pointer 'ptr' holds the address of the 'x' variable.
But this does not happen, as 'y' is storing the local copy of value '5'.
Output

Let's consider another scenario.


1. #include <stdio.h>
2. int main()
3. {
4. int a=90;
5. int *ptr1,*ptr2;
6. ptr1=&a;
7. ptr2=&a;
8. *ptr1=7;
9. *ptr2=6;
10. printf("The value of a is : %d",a);
11. return 0;
12. }

In the above code:


• First, we declare an 'a' variable.
• Then we declare two pointers, i.e., ptr1 and ptr2.
• Both the pointers contain the address of 'a' variable.
• We assign the '7' value to the *ptr1 and '6' to the *ptr2. The final value of 'a'
would be '6'.
Note: If we have more than one pointer pointing to the same location, then
the change made by one pointer will be the same as another pointer.
Output

C Function Pointer
As we know that we can create a pointer of any data type such as int, char, float, we
can also create a pointer pointing to a function. The code of a function always resides
in memory, which means that the function has some address. We can get the address
of memory by using the function pointer.
Let's see a simple example.
1. #include <stdio.h>
2. int main()
3. {
4. printf("Address of main() function is %p",main);
5. return 0;
6. }
The above code prints the address of main() function.
Output

In the above output, we observe that the main() function has some address.
Therefore, we conclude that every function has some address.
Declaration of a function pointer
Till now, we have seen that the functions have addresses, so we can create pointers
that can contain these addresses, and hence can point them.
Syntax of function pointer
1. return type (*ptr_name)(type1, type2…);
For example:
1. int (*ip) (int);
In the above declaration, *ip is a pointer that points to a function which returns an int
value and accepts an integer value as an argument.
1. float (*fp) (float);
In the above declaration, *fp is a pointer that points to a function that returns a float
value and accepts a float value as an argument.
We can observe that the declaration of a function is similar to the declaration of a
function pointer except that the pointer is preceded by a '*'. So, in the above
declaration, fp is declared as a function rather than a pointer.
Till now, we have learnt how to declare the function pointer. Our next step is to assign
the address of a function to the function pointer.
1. float (*fp) (int , int); // Declaration of a function pointer.
2. float func( int , int ); // Declaration of function.
3. fp = func; // Assigning address of func to the fp pointer.
In the above declaration, 'fp' pointer contains the address of the 'func' function.
Note: Declaration of a function is necessary before assigning the address of
a function to the function pointer.
Calling a function through a function pointer
We already know how to call a function in the usual way. Now, we will see how to call
a function using a function pointer.
Suppose we declare a function as given below:
1. float func(int , int); // Declaration of a function.
Calling an above function using a usual way is given below:
1. result = func(a , b); // Calling a function using usual ways.
Calling a function using a function pointer is given below:
1. result = (*fp)( a , b); // Calling a function using function pointer.
Or
1. result = fp(a , b); // Calling a function using function pointer, and indirectio
n operator can be removed.
The effect of calling a function by its name or function pointer is the same. If we are
using the function pointer, we can omit the indirection operator as we did in the
second case. Still, we use the indirection operator as it makes it clear to the user that
we are using a function pointer.
Let's understand the function pointer through an example.
1. #include <stdio.h>
2. int add(int,int);
3. int main()
4. {
5. int a,b;
6. int (*ip)(int,int);
7. int result;
8. printf("Enter the values of a and b : ");
9. scanf("%d %d",&a,&b);
10. ip=add;
11. result=(*ip)(a,b);
12. printf("Value after addition is : %d",result);
13. return 0;
14. }
15. int add(int a,int b)
16. {
17. int c=a+b;
18. return c;
19. }
Output

Passing a function's address as an argument to other function


We can pass the function's address as an argument to other functions in the same
way we send other arguments to the function.
Let's understand through an example.
1. include <stdio.h>
2. void func1(void (*ptr)());
3. void func2();
4. int main()
5. {
6. func1(func2);
7. return 0;
8. }
9. void func1(void (*ptr)())
10. {
11. printf("Function1 is called");
12. (*ptr)();
13. }
14. void func2()
15. {
16. printf("\nFunction2 is called");
17. }
In the above code, we have created two functions, i.e., func1() and func2(). The
func1() function contains the function pointer as an argument. In the main() method,
the func1() method is called in which we pass the address of func2. When func1()
function is called, 'ptr' contains the address of 'func2'. Inside the func1() function, we
call the func2() function by dereferencing the pointer 'ptr' as it contains the address of
func2.
Output

Array of Function Pointers


Function pointers are used in those applications where we do not know in advance
which function will be called. In an array of function pointers, array takes the
addresses of different functions, and the appropriate function will be called based on
the index number.
Let's understand through an example.
1. #include <stdio.h>
2. float add(float,int);
3. float sub(float,int);
4. float mul(float,int);
5. float div(float,int);
6. int main()
7. {
8. float x; // variable declaration.
9. int y;
10. float (*fp[4]) (float,int); // function pointer declaration.
11. fp[0]=add; // assigning addresses to the elements of an array o
f a function pointer.
12. fp[1]=sub;
13. fp[2]=mul;
14. fp[3]=div;
15. printf("Enter the values of x and y :");
16. scanf("%f %d",&x,&y);
17. float r=(*fp[0]) (x,y); // Calling add() function.
18. printf("\nSum of two values is : %f",r);
19. r=(*fp[1]) (x,y); // Calling sub() function.
20. printf("\nDifference of two values is : %f",r);
21. r=(*fp[2]) (x,y); // Calliung sub() function.
22. printf("\nMultiplication of two values is : %f",r);
23. r=(*fp[3]) (x,y); // Calling div() function.
24. printf("\nDivision of two values is : %f",r);
25. return 0;
26. }
27.
28. float add(float x,int y)
29. {
30. float a=x+y;
31. return a;
32. }
33. float sub(float x,int y)
34. {
35. float a=x-y;
36. return a;
37. }
38. float mul(float x,int y)
39. {
40. float a=x*y;
41. return a;
42. }
43. float div(float x,int y)
44. {
45. float a=x/y;
46. return a;
47. }
In the above code, we have created an array of function pointers that contain the
addresses of four functions. After storing the addresses of functions in an array of
function pointers, we call the functions using the function pointer.
Output

You might also like