Module 10 - Pointers in C
Module 10 - Pointers in C
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Why?
✓ Allows memory level operations
✓ Very few Programming languages allow this: C, C++, Fortran
✓ Enables “Pass by Reference”
✓ Enables us to return multiple data items from functions
✓ Like arrays, large complex structures
✓ Enables dynamic memory allocation at run-time
✓ You don’t need to fix the input size at the time of programming
✓ Many More…
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Module Overview
• Pointers in C
• Pointer Arithmetic
• Pass by reference
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
BITS Pilani
Pilani Campus
Pointers in C
Addresses and Pointers
Consider a variable declaration in the Address
following program: es in Hex
int main(){ a 5
1000
1001
int a = 5; 1002
} 1003
1004
1005
Say, the variable “a” occupies 2 bytes 1006
starting at memory location whose address is 1007
1000 (in hexa-decimal). (Assuming 16-bit 1008
addresses) 1009
1010
This address can be accessed by “&a” 1011
printf(“Value of a: %d”,a); 5
printf(“Address of a: %p”,&a); 1000 Memory
allotted to
%p used to print addresses main()
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Addresses and Pointers
• The address of this variable a, can be stored in Address
a variable called a pointer variable es in Hex
int * ptr = &a;
a 1000
5
1001
• ptr is a pointer variable of integer type. It is 1002
capable of storing the address of an integer 1003
variable. 1004
1005
• We can access the value stored in the variable ptr 1000 1006
a by *ptr 1007
printf(“Value of a: %d”,*ptr); 5 1008
1009
1010
• *ptr translates to value at ptr. (de- 1011
referencing)
• Pointer variable of any type typically occupies 4
Memory
bytes (or 8 bytes) in memory depending upon
allotted to
the compiler. main()
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Simplifying with an example
Given declarations
int v;
int *p;
p = &v; is a valid assignment statement.
v 5
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Simplifying with an example…
Now, what is the effect of (*p)++ ?
v 5
*p (i.e., contents of p) is 5;
v 6
And it is changed to 6;
So v is also 6 p
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Example with float
float u,v; // floating-point variable declaration
float * pv; // pointer variable declaration
……
pv = &v; // assign v’s address to pv
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Another Example
int main(){
int v = 3, *pv; Note: %p prints contents of
a pointer variable which is
pv = &v; the address
v=v+1;
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
BITS Pilani
Pilani Campus
Pointer Arithmetic
Size of a Pointer
Size
Borland C / Turbo C 2 bytes
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Pointer Arithmetic
• Incrementing a pointer
– NewPtr = CurrentPtr + N bytes
– Where N is size of pointer data type.
Example:
int a = 5;
int * p = &a; // assume &a = 1000 (assume 16-bit addresses)
int * q = p + 1;
printf(“printing ptr: %p”, p); 1000
printf(“printing ptr: %p”, q); 1002
Example:
int a = 5;
int * p = &a; // assume &a = 1000 (assume 16-bit addresses)
int * q = p + 4;
printf(“printing ptr: %p”, p); 1000
printf(“printing ptr: %p”, q); 1008
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Operator Precedence
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Incrementing a pointer
variable: Case 1
int c1 = *++ptr;
// c1 = *(++ptr);
// increment ptr and dereference its (now
incremented) value
// c1 = 21 Address in
Memory
10 1000
21 1002
40 1004
ptr 1000 1002
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Incrementing a pointer
variable: Case 2
int c2 = ++*ptr;
// c2 = ++(*ptr);
// dereference ptr and increment the
dereferenced value
Address in
// c2 = 11 Memory
10 11 1000
21 1002
40 1004
ptr 1000
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Incrementing a pointer
variable: Case 3
int c3 = *ptr++; // or int c3 = *(ptr++);
// both of the above has same meaning
// c3 = *ptr; ptr = ptr+1;
// dereference current ptr value and
increment ptr afterwards
Address in
Memory
// c3 = 10 10 1000
21 1002
40 1004
ptr 1000 1002
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Incrementing a pointer
variable: Case 4
int c4 = (*ptr)++;
// c4 = *ptr; *ptr = *ptr + 1;
// dereference current ptr value and increment
the dereferenced value - now we need
parentheses
Address in
Memory
// c4 = 10 10 11 1000
21 1002
40 1004
ptr 1000
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Example
int main() { Note the difference of 4
int v =3, *pv; bytes in the addresses. In
this example, size of int is
assumed to be 4 bytes.
pv = &v;
*pv++;
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Example – Variation 1
int main() {
int v =3, *pv;
pv = &v;
(*pv)++;
pv = &v;
++*pv;
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Simplifying with an example
Given
Ai
int Ai[100];
int *pi;
pi
pi = Ai
pi = Ai +2
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Example
int main(){ This program
int *ptr, i, iA[5]={5,10,15,20,25}; assumes sizeof(int)
for(i=0;i<5;i++) to be 4 bytes
printf("iA[%d]:address=%p
data=%d", i, &iA[i], iA[i]);
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Example: Array of Pointers
int main(){
int *ptr[3], i, iA[]={5,10,15}, iB[]={1,2,3}, iC[]={2,4,6};
ptr[0]=iA;
ptr[1]=iB; This program assumes
ptr[2]=iC; sizeof(int) to be 4 bytes
for(i=0;i<3;i++) {
printf("iA[%d]:addr=%p data=%d ",i,ptr[0]+i,*(ptr[0]+i));
printf("iB[%d]:addr=%p data=%d ",i,ptr[1]+i,*(ptr[1]+i));
printf("iC[%d]:addr=%p data=%d ",i,ptr[2]+i,*(ptr[2]+i));
} Output:
return 0; iA[0]:addr=0x7ffe7213707c data=5
} iB[0]:addr=0x7ffe72137088 data=1
iC[0]:addr=0x7ffe72137094 data=2
iA[1]:addr=0x7ffe72137080 data=10
iB[1]:addr=0x7ffe7213708c data=2
iC[1]:addr=0x7ffe72137098 data=4
iA[2]:addr=0x7ffe72137084 data=15
iB[2]:addr=0x7ffe72137090 data=3
iC[2]:addr=0x7ffe7213709c data=6
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Another example
int main(){
int line[]={10,20,30,40,50};
line[2]=*(line + 1);
*(line+1) = line[4];
for(int i =0;i<5;i++)
printf("%d ", *(line+i)); Output:
return 0;
40 50 20 40 40
}
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
BITS Pilani
Pilani Campus
Pointers to Structures
Pointers to Structure
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Accessing members in pointers
to Structures
• Once ptr points to a structure variable, the members can be
accessed through dot(.) or arrow operators:
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Illustration
struct stud {
int roll;
char dept_code[25];
float cgpa;
} class, *ptr;
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Caveats
• When using structure pointers, we should take care of operator
precedence.
• Member operator “.” has higher precedence than “*”
• ptr–>roll and (*ptr).roll mean the same thing.
*ptr.roll will lead to error
• The operator “–>” has the highest priority among operators.
• ++ptr–>roll will increment roll, not ptr
• (++ptr)–>roll will do the intended thing.
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Pointers to Array of Structures
struct stud {
int roll;
char dept_code[25];
float cgpa;
} class[3], *ptr;
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
BITS Pilani
Pilani Campus
Call/Pass by reference
Variable, Arrays and Structures
Swapping two variables using a
function: Attempt 1 – Pass by value
First Attempt: Pass by value Output:
10 20
void swap(int x, int y){ int main(){
10 20
int temp = x; int a = 10, b = 20;
x = y; printf("Before Swapping %d %d\n", a, b);
y = temp; swap(a, b);
} printf("After Swapping %d %d\n", a, b);
return 0;
}
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Swapping two variables using a function:
Attempt 2 – Pass by reference
Second Attempt: Pass by reference
void swap(int *x, int *y) { int main() {
int temp = *x; int a = 10, b = 20;
*x = *y; printf("Before Swapping %d %d\n", a, b);
*y = temp; swap(&a, &b);
} printf("After Swapping %d %d\n", a, b);
return 0;
}
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Passing Arrays into functions
Passing arrays into functions is by default call by reference.
void sort(int a[]) { int main() {
int temp, i , j, sorted = 0; int arr[8] = {2,5,9,7,1,5,4,6};
for(i = 0; i < SIZE-i-1; i++){
for(j = 0; j<SIZE-1-i; j++){ int SIZE = 8;
if(a[j] > a[j + 1]) printf(“Array before sort: \n”);
{ for (i = 0; i < SIZE; i++)
temp = a[j]; printf("%d ", arr[i]);
a[j] = a[j + 1];
a[j + 1] = temp; printf("\n");
} sort(arr);
} printf(“Array after sort: \n");
} for (i = 0; i < SIZE; i++)
} printf("%d ", arr[i]);
When arrays are passed as printf("\n");
parameters, you pass the sort() function implements bubble
return 0;
address of the first location sort which is one of the sorting
}
which the array variable name algorithms. Don’t worry about it.
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Taking arrays as input
parameter
void sort(int a[]) { void sort(int * a) {
int temp, i , j, sorted = 0; int temp, i , j, sorted = 0;
for(i = 0; i < SIZE-i-1; i++){ for(i = 0; i < SIZE-i-1; i++){
for(j = 0; j<SIZE-1-i; j++){ for(j = 0; j<SIZE-1-i; j++){
if(a[j] > a[j + 1]) if(a[j] > a[j + 1])
{ {
temp = a[j]; temp = a[j];
a[j] = a[j + 1]; a[j] = a[j + 1];
a[j + 1] = temp; a[j + 1] = temp;
} }
} }
} }
} }
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Example: Computing length of
a string
❑ Applications of Pointer arithmetic:
int strlen(char *str) {
char *p;
for (p=str; *p != ‘\0’; p++);
return p-str;
}
❑ Observe the similarities and differences with arrays.
int strlen(char str[]) {
int j;
for (j=0; str[j] != ‘\0’; j++);
return j;
}
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Character Arrays and Pointers:
Example 2
Boolean isPalindrome(char *str) {
return TRUE;
}
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Pass by reference using
structures
typedef struct{ int main() {
int a;
float b; ST s1, s2;
} ST; s1.a=10; s1.b=10.555;
s2.a=3; s2.b=3.555;
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
BITS Pilani
Pilani Campus
Pointers Revisited
Null Pointer
• Initialize a pointer variable to NULL when that pointer variable
isn’t assigned any valid memory address yet.
• int *p = NULL;
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Generic or Void Pointer
Do we need different types of pointers to store the addresses of
the variable of different types?
No!
void_ptr = &x;
printf("\n x=%d",*(int *)void_ptr);
void_ptr = &y;
printf("\n y=%f",*(float *)void_ptr);
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Pointer to a Pointer
A pointer to a pointer is a form of multiple indirection, or a chain
of pointers.
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Example
int main () { “pointer to a pointer” is useful in
int var, *ptr, **pptr; creating 2-D arrays with dynamic
memory allocation (next module)
var = 3000;
ptr = &var;
pptr = &ptr;
return 0;
}
Output:
Value of var = 3000, *ptr = 3000, **pptr = 3000
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Review Question
int main(){
int (*x1)[3];
int y[2][3]={{1,2,3},{4,5,6}};
x1 = y;
for (int i = 0; i<2; i++)
for (int j = 0; j<3; j++)
printf("\n The X1 is %d and Y is %d",*(*(x1+i)+j), y[i][j]);
// printf("\n The X1 is %d and Y is %d", x1[i][j], y[i][j]);
// would also work
return 0;
}
Output:
The X1 is 1 and Y is 1
The X1 is 2 and Y is 2
The X1 is 3 and Y is 3
The X1 is 4 and Y is 4
The X1 is 5 and Y is 5
The X1 is 6 and Y is 6
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Review Question
int main()
{
int arr[3][4] = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12}};
int i = 1,j = 2;
return 0;
}
Output:
garbage
Data at *(arr+i)+j = 7
Data at *(arr+i+j) = 1970957920
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Review Question
int main()
{
int x[] = {10,12,14};
int *y, **z;
y = x;
z = &y;
return 0;
}
Output:
x = 10, y = 12, z = 14
x = 10, y = 11, z = 12
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
BITS Pilani
Pilani Campus