The rules for assigning one pointer to another are tighter than the rules for numeric types. For example, you can assign an int value to a double variable without using a type conversion, but you can’t do the same for pointers to these two types. Let’s see a simple C program to exemplify this.
/* * ptr_compatibility.c -- program illustrates concept of pointer * compatibility */ #include <stdio.h> int main(void) { int n = 5; long double x; int *pi = &n; long double *pld = &x; x = n; /* implicit type conversion */ pld = pi; /* compile-time error: assigning pointer-to-int to */ /* pointer-to-long-double */ return 0; }
These restrictions extend to more complex types. Suppose we have the following declarations:
int *pi; int (*pa)[3]; /* pointer to an array of 3 integers */ int ar1[2][3]; int ar2[3][2]; int **p2pi; /* a pointer-to-pointer-to-int, a double pointer */ /* Then we have the following: */ pi = &ar1[0][0]; /* both pointer-to-int */ pi = ar1[0]; /* both pointer-to-int */ pi = ar1; /* not valid because ar1 is an array of 3 integers */ pa = ar1; /* both pointer-to-int[3] */ pa = ar2; /* not valid because ar2 is an array of 2 integers */ p2pi = π /* both pointer-to-int * */ *p2pi = ar2[0]; /* both pointer-to-int */ p2pi = ar2; /* not valid */
Notice that the non valid assignments all involve two pointers that don’t point to the same type. For example, ‘pi’ points to a single int, but ‘ar1’ points to an array of three ints. Similarly, ‘pa’ points to an array of three ints, so it is compatible with ‘ar1’, but not with ‘ar2’, which points to an array of two ints.
The last two examples are somewhat tricky. The variable p2pi is a pointer-to-pointer-to-int, whereas ar2 is a pointer-to-array-of-two-ints (or, more concisely, pointer-to-int[2]). So p2pi and ar2 are of different types, and therefore we can’t assign ‘ar2’ to ‘p2pi’. But ‘*p2pi’ is of type pointer-to-int, making it compatible with ‘ar2[0]’. Recall that ‘ar2[0]’ is a pointer to its first element, ‘ar2[0][0]’, making ‘ar2[0]’ type pointer-to-int also.
In general, multiple indirection is tricky. For instance, consider the next snippet of code:
int *p1; const int *p2; const int **p2p; p1 = p2; /* not valid -- assigning const to non-const */ p2 = p1; /* valid -- assigning non-const to const */ p2p = &p1; /* not valid -- assigning non-const to const */
As we have seen earlier, assigning a const pointer to a non-const pointer is invalid, because we could use the new pointer to alter const data. But assigning a non-const pointer to a const pointer is okay, provided that we’re dealing with just one level of indirection:
p2 = p1; /* valid -- assigning non-const to const */
But such assignments no longer are safe when we go to two levels of indirection. If it were allowed, we could do something like this:
const int **pp2; int *p1; const int n = 13; pp2 = &p1; /* not allowed, but suppose it were */ *pp2 = &n; /** valid, both const, but sets p1 to point at n */ *p1 = 10; /* valid, but changes const n */
But notice then non-constant pointer-to-int ‘p1’ modified constant integer n. Therefore multi-level indirection is not allowed.
Sanfoundry Global Education & Learning Series – 1000 C Tutorials.
- Practice Computer Science MCQs
- Watch Advanced C Programming Videos
- Check Computer Science Books
- Apply for C Internship
- Apply for Computer Science Internship