Lecture 6
Lecture 6
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.)
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
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
Pointer to structure
1. struct st {
2. int i;
3. float f;
4. }ref;
5. struct st *p = &ref;
Advantage of pointer
3) It makes you able to access any memory location in the computer's memory.
Usage of pointer
Pointers in c language are widely used in arrays, functions, and structures. It reduces
the code and improves the performance.
The address of operator '&' returns the address of a variable. But, we need to use %u
to display the address of a variable.
1. #include<stdio.h>
2. int main(){
3. int number=50;
4. printf("value of number is %d, address of number is %u",number,&number);
5. return 0;
6. }
Output
NULL Pointer
A pointer that is not assigned any value but NULL is known as the NULL pointer. If you
don't have any address to be specified in the pointer at the time of declaration, you
can assign NULL value. It will provide a better approach.
int *p=NULL;
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
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.
Data type 3 -
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).
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
Example
Explanation
This pointer will be read as p is a pointer to such function which accepts the first
parameter as the pointer to a one-dimensional array of integers of size two and the
second parameter as the pointer to a function which parameter is void and return
type is the integer.
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
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