UNIT- 5
Pointers in C
- Give an Introduction to pointers and explain it with examples with all the possible aspects
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.
- Int n = 10;
- 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.
- Int *a;//pointer to int
- 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.
- #include<stdio.h>
- Int main(){
- Int number=50;
- Int *p;
- p=&number;//stores the address of number variable
- Printf("Address of p variable is %x \n",p); // p contains the address of the number therefore printing p gives the address of number.
- 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 p.
- Return 0;
- }
Output
Address of number variable is fff4
Address of p variable is fff4
Value of p variable is 50
Pointer to array
- Int arr[10];
- Int *p[10]=&arr; // Variable p of type pointer is pointing to the address of an integer array arr.
Pointer to a function
- Void show (int);
- Void(*p)(int) = &display; // Pointer p is pointing to the address of a function
Pointer to structure
- Struct st {
- Int i;
- Float f;
- }ref;
- 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.
- #include<stdio.h>
- Int main(){
- Int number=50;
- Printf("value of number is %d, address of number is %u",number,&number);
- Return 0;
- }
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.
- #include<stdio.h>
- Int main(){
- Int a=10,b=20,*p1=&a,*p2=&b;
- Printf("Before swap: *p1=%d *p2=%d",*p1,*p2);
- *p1=*p1+*p2;
- *p2=*p1-*p2;
- *p1=*p1-*p2;
- Printf("\nAfter swap: *p1=%d *p2=%d",*p1,*p2);
- Return 0;
- }
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 the 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,
- (): This operator is a bracket operator used to declare and define the function.
- []: This operator is an array subscript operator
- * : This operator is a pointer operator.
- Identifier: It is the name of the pointer. The priority will always be assigned to this.
- 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.
- Char -> 4
- * -> 2
- p -> 1
- [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?
- 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.
2. Explain Declaring Pointer Variables and Initialization of Pointer Variables
Declaration of C Pointer variable
General syntax of pointer declaration is,
Datatype *pointer_name;
Data type of a pointer must be same as the data type of the variable to which the pointer variable is pointing. Void type pointer works with all data types, but is not often used.
Here are a few examples:
Int *ip // pointer to integer variable
Float *fp; // pointer to float variable
Double *dp; // pointer to double variable
Char *cp; // pointer to char variable
Initialization of C Pointer variable
Pointer Initialization is the process of assigning address of a variable to a pointer variable. Pointer variable can only contain address of a variable of the same data type. In C language address operator& is used to determine the address of a variable. The & (immediately preceding a variable name) returns the address of the variable associated with it.
#include<stdio.h>
Void main()
{
Int a = 10;
Int *ptr; //pointer declaration
Ptr = &a; //pointer initialization
}
Pointer variable always point to variables of same datatype. Let's have an example to showcase this:
#include<stdio.h>
Void main()
{
Float a;
Int *ptr;
Ptr = &a; // ERROR, type mismatch
}
If you are not sure about which variable's address to assign to a pointer variable while declaration, it is recommended to assign a NULL value to your pointer variable. A pointer which is assigned a NULL value is called a NULL pointer.
#include <stdio.h>
Int main()
{
Int *ptr = NULL;
Return 0;
}
Using the pointer or Dereferencing of Pointer
Once a pointer has been assigned the address of a variable, to access the value of the variable, pointer is dereferenced, using the indirection operator or dereferencing operator*.
#include <stdio.h>
Int main()
{
Int a, *p; // declaring the variable and pointer
a = 10;
p = &a; // initializing the pointer
Printf("%d", *p); //this will print the value of 'a'
Printf("%d", *&a); //this will also print the value of 'a'
Printf("%u", &a); //this will print the address of 'a'
Printf("%u", p); //this will also print the address of 'a'
Printf("%u", &p); //this will print the address of 'p'
Return 0;
}
Points to remember while using pointers
- While declaring/initializing the pointer variable, * indicates that the variable is a pointer.
- The address of any variable is given by preceding the variable name with Ampersand &.
- The pointer variable stores the address of a variable. The declaration int *a doesn't mean that a is going to contain an integer value. It means that a is going to contain the address of a variable storing integer value.
- To access the value of a certain address stored by a pointer variable, * is used. Here, the * can be read as 'value at'.
3. What is Pointer Expressions in C language?
1) If p1 and p2 are properly declared and initialized pointers, then the following statements are valid:
Y=*p1**p2;
Sum=sum+*p1;
Z=5*-*p2/ *p1;
*p2=*p2+10;
*p1=*p1+*p2;
*p1=*p2-*p1;
NOTE: in the third statement there is a blank space between ‘/’ and * because the symbol /*is considered as beginning of the comment and therefore the statement fails.
2) if p1 and p2 are properly declared and initialized pointers then, ‘C’ allows adding integers to a pointer variable.
EX:
int a=5, b=10;
int *p1,*p2;
p1=&a;
p2=&b;
Now,
P1=p1+1=1000+2=1002;
P1=p1+2=1000+ (2*2) =1004;
P1=p1+4=1000+ (2*4) =1008;
P2=p2+2=3000+ (2*2) =3004;
P2=p2+6=3000+ (2*6) =3012;
Here addition means bytes that pointer data type hold are subtracted number of times that is subtracted to the pointer variable.
3) If p1 & p2 are properly declared and initialized, pointers then
‘C’ allows to subtract integers from pointers. From the above example,
P1=p1-1=1000-2=998;
P1=p1-2=1000-4=996;
P1=p1-4=1000-8=992;
P2=p2-2=3000-4=2996;
P2=p2-6=3000-12=2988;
Here the subtraction means byte that pointer data type hold are subtracted number of times that is subtracted to the pointer variable.
4) If p1 & p2 are properly declared and initialize pointers, and both points to the elements of same type. “Subtraction of one pointer from another pointer is also possible".
NOTE: this operation is done when the both pointer variable points to the elements of the same array.
EX:
P2- P1 (It gives the number of elements between p1 and p2)
5) Pointer can also be used with increment and decrement operators.
Ex:
int a=10;
int *b;
b=&a;
4. Write a function to calculate the roots. The function must use two pointer parameters, one to receive the coefficients a, b and c and the other to send roots to calling function.
01 | #include<stdio.h> | |
02 | #include<math.> | |
03 | Roots (p, q) | |
04 | Float*p,*q; | |
05 | { | |
06 | *q= (–(*(p+1) +sqrt((*(p+1))*(*(p+1))–4*(*p)*(*(p+2))))/ | |
07 | (2*(*p)); | |
08 | *(q+1) = (–(*(p+1)-sqrt((*(p+1))*(*(p+1))–4*(*p)*(*(p+2))))/ | |
09 | (2*(*p)); | |
10 | } | |
11 | Voidmain () | |
12 | { | |
13 | FloatA [3], R [2]; | |
14 | Inti; | |
15 | Printf(‘‘Enter values fora, b, c’’); | |
16 | For(i=0; i< = 2; i++) | |
17 | Scanf(‘‘%f’’, A+i); | |
18 | Roots (A, R); | |
19 | Printf(‘‘root1 = %f’’, *(R+0)); | |
20 | Printf(‘‘root2=%f’’, *(R+1)); | |
21 | } | |
22 |
| |
5. Write a ‘C’ program to compute the sum of all elements stored in an array Using pointers.
01 | /*program to compute sum of all elements stored in an | |
02 | Array */ | |
03 | #include<stdio.h> |
04 | #include<conio.h> |
05 | Main () | |
06 | { | |
07 | Inta [10], I, sum=0,*p; | |
08 | Printf(“enter 10 elements \n”); | |
09 | For(i=0; i<10; i++) | |
10 | Scanf(“%d”, & a[i]); | |
11 | p = a; | |
12 | For(i = 0; i<10; i++) | |
13 | { | |
14 | Sum = sum*p; | |
15 | p++; | |
16 | } | |
17 | Printf(“the sum is % d”, sum); | |
18 | Getch (); | |
19 | } |
6. Write a ‘C’ program using pointers to determine the length of a character String.
01 | /*program to find the length of a char string */ | |
02 | #include<stdio.h> | |
03 | #include<conio.h> | |
04 | #include<string.h> | |
05 | Main () | |
06 | { | |
07 | Char str [20].*p; | |
08 | Int l=0; | |
09 | Printf(“enter a string \n”); | |
10 | Scanf(“ % s”, str); | |
11 | p=str; | |
12 | While(*p!=’\0’) | |
13 | { | |
14 | l++; | |
15 | p++; | |
16 | } | |
17 | Printf(“the length of the given string is %d”, l); | |
18 | Getch (); | |
19 | } |
7. Write an example of Functions Pointers
For example, the next program swaps two values of two:
Void swap (int *a, int *b);
Int main() {
Int m = 25;
Int n = 100;
Printf("m is %d, n is %d\n", m, n);
Swap(&m, &n);
Printf("m is %d, n is %d\n", m, n);
Return 0;}
Void swap (int *a, int *b) {
Int temp;
Temp = *a;
*a = *b;
*b = temp;}
}
Output:
m is 25, n is 100
m is 100, n is 25
The program swaps the actual variables values because the function accesses them by address using pointers. Here we will discuss the program process:
- We declare the function responsible for swapping the two variable values, which takes two integer pointers as parameters and returns any value when it is called.
- In the main function, we declare and initialize two integer variables ('m' and 'n') then we print their values respectively.
- We call the swap() function by passing the address of the two variables as arguments using the ampersand symbol. After that, we print the new swapped values of variables.
- Here we define the swap() function content which takes two integer variable addresses as parameters and declare a temporary integer variable used as a third storage box to save one of the value variables which will be put to the second variable.
- Save the content of the first variable pointed by 'a' in the temporary variable.
- Store the second variable pointed by b in the first variable pointed by a.
- Update the second variable (pointed by b) by the value of the first variable saved in the temporary variable.
8. Explain Functions with Array Parameters with examples
In C, we cannot pass an array by value to a function. Whereas, an array name is a pointer (address), so we just pass an array name to a function which means to pass a pointer to the array.
For example, we consider the following program:
Intadd_array (int *a, intnum_elements);
Int main() {
Int Tab[5] = {100, 220, 37, 16, 98};
Printf("Total summation is %d\n", add_array(Tab, 5));
Return 0;}
Intadd_array (int *p, int size) {
Int total = 0;
Int k;
For (k = 0; k < size; k++) {
Total += p[k]; /* it is equivalent to total +=*p ;p++; */}
Return (total);}
Output:
Total summation is 471
Here, we will explain the program code with its details
- We declare and define add_array() function which takes an array address( pointer) with its elements number as parameters and returns the total accumulated summation of these elements. The pointer is used to iterate the array elements (using the p[k] notation), and we accumulate the summation in a local variable which will be returned after iterating the entire element array.
- We declare and initialize an integer array with five integer elements. We print the total summation by passing the array name (which acts as address) and array size to the add_array()called function as arguments.
9. Explain Function Pointers with examples
As we know by definition that pointers point to an address in any memory location, they can also point to at the beginning of executable code as functions in memory.
A pointer to function is declared with the * ,the general statement of its declaration is:
Return_type (*function_name)(arguments)
You have to remember that the parentheses around (*function_name) are important because without them, the compiler will think the function_name is returning a pointer of return_type.
After defining the function pointer, we have to assign it to a function. For example, the next program declares an ordinary function, defines a function pointer, assigns the function pointer to the ordinary function and after that calls the function through the pointer:
#include <stdio.h>
VoidHi_function (int times); /* function */
Int main() {
Void (*function_ptr)(int); /* function pointer Declaration */
Function_ptr = Hi_function; /* pointer assignment */
Function_ptr (3); /* function call */
Return 0;}
VoidHi_function (int times) {
Int k;
For (k = 0; k < times; k++) printf("Hi\n");}
Output:
Hi
Hi
Hi
- We define and declare a standard function which prints a Hi text k times indicated by the parameter times when the function is called
- We define a pointer function (with its special declaration) which takes an integer parameter and doesn't return anything.
- We initialize our pointer function with the Hi_function which means that the pointer points to the Hi_function().
- Rather than the standard function calling by taping the function name with arguments, we call only the pointer function by passing the number 3 as arguments, and that's it!
Keep in mind that the function name points to the beginning address of the executable code like an array name which points to its first element. Therefore, instructions like function_ptr = &Hi_function and (*funptr)(3) are correct.
NOTE: It is not important to insert the address operator & and the indirection operator * during the function assignment and function call.
10. Explain Functions using void Pointers with examples
Void pointers are used during function declarations. We use a void * return type permits to return any type. If we assume that our parameters do not change when passing to a function, we declare it as const.
For example:
Void * cube (const void *);
Consider the following program:
#include <stdio.h>
Void* cube (const void* num);
Int main() {
Int x, cube_int;
x = 4;
Cube_int = cube (&x);
Printf("%d cubed is %d\n", x, cube_int);
Return 0;}
Void* cube (const void *num) {
Int result;
Result = (*(int *)num) * (*(int *)num) * (*(int *)num);
Return result;}
Result:
4 cubed is 64
Here, we will discuss the program details:
- We define and declare a function that returns an integer value and takes an address of unchangeable variable without a specific data type. We calculate the cube value of the content variable (x) pointed by the num pointer, and as it is a void pointer, we have to type cast it to an integer data type using a specific notation (* datatype) pointer, and we return the cube value.
- We declare the operand and the result variable. Also, we initialize our operand with value "4."
- We call the cube function by passing the operand address, and we handle the returning value in the result variable