Module 10 - Pointers
Module 10 - Pointers
BITS Pilani
Pilani Campus
Department of Computer Science & Information Systems
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 (data) 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 a ptr 1000 1006
by *ptr 1007
printf(“Value of a: %d”,*ptr); 5 1008
1009
1010
• *ptr translates to value at ptr. 1011
(de-referencing)
• Pointer variable of any type typically occupies 4
bytes (or 8 bytes) in memory depending upon Memory
the compiler. allotted to
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
p
#include <stdio.h>
What is the effect of the following? int main(){
v = 5; int a=10, *p; p=&a;
printf("%d\t%p\t%u\t%x\t%lu\n", *p, p, p, p,
sizeof(p)); return 0;}
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Example
#include <stdio.h>
int main()
{
int i=5, *p;
p=&i;
printf("Address= %p, %p %p", &i, p, &p);
printf("\nsize of = %d, %d", sizeof(i), sizeof(p));
printf("\nvalue of = %d, %d %d", i, p, *p);
return 0;
}
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;
p
So v is also 6
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
Example
#include<stdio.h>
void main ()
{
int c3, a =10, *ptr;
ptr=&a;
printf("\nAddress %u", ptr);
c3=*ptr++;
printf("\nc3=%d ptr=%d", c3, *ptr);
printf("\nAddress %u", ptr);
return 0;
}
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Example
#include<stdio.h>
void main ()
{
int c3, a =10, *ptr;
ptr=&a;
printf("\nAddress %u", ptr);
c3=*ptr++;
printf("\nc3=%d ptr=%d", c3, *ptr);
printf("\nAddress %u\t %d", ptr, *ptr);
printf("\nAddress %u\t %d", --ptr, *ptr);
return 0;
}
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Explained Example
#include <stdio.h>
int main()
{
int a[5]={11,22,33,44,55}, *p;
p=a;
printf(" %d", *p++);
printf("\n %d", *p);
return 0;
}
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
#include<stdio.h>
int main ()
{
int c3, c4, a =10, *ptr;
ptr=&a;
printf("\nAddress %u", ptr);
c3=*ptr++;
printf("\nc3=%d ptr=%d", c3, *ptr);
printf("\n c3 address=%u ptr Address %u", ptr,c3);
c4=(*ptr)++;
printf("\nc4=%d ptr=%d", c4, *ptr);
return 0;
}
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
#include <stdio.h>
int main()
{
int a[100], *p, *q;
a[90]=10;
p=&a;
q=a+90;
printf("a[90]=%d, %d, %d %d %d", a[90], *p, *(p+90), *q, q-p);
return 0;
}
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
Output ?
++(*ptr) =>?
*(++ptr) => ? #include <stdio.h>
int main()
{
++*++ptr => ? int a[5]={11,22,33,44,55}, *p;
p=a;
printf(" %d", ++*p++);
printf("\n %d", *p);
return 0;
}
printf(" %d", ++*++p);
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
Explained
#include <stdio.h>
int main(){
int line[]={10,20,30,40,50};
line[2]=*(line + 1);
for(int i =0;i<5;i++)
printf("%d ", *(line+i));
printf("\n\n") ;
*(line+1) = line[4];
for(int i =0;i<5;i++)
printf("%d ", *(line+i));
printf("\n\n") ;
for(int i =0;i<5;i++)
printf("%d ", *(line+i));
return 0; }
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Example
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Example
#include <stdio.h>
#define MAX 3
int main () {
char *names[] = {
"Pilani",
"Goa",
"Hyderabad"
};
int i = 0;
char *p[3];
for ( i = 0; i < MAX; i++) {
p[i]=names[i];
printf("Value of names[%d] = %s // p=%s\n", i, names[i], p[i] );
}
return 0;
}
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Output?
#include <stdio.h>
#pragma pack(0)
struct base
{
int a;
char b;
};
int main()
{
struct base var;
printf("size of var: %ld\n", sizeof(var));
return 0;
}
Pack(0) => 8
Pack(1) => 5
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
Explained
#include <stdio.h>
struct stud{
int roll;
char dept_code[25];
float cgpa;
};
struct stud cla[2]={{7,"IT", 8.75f}, {17,"CSIS", 7.50f}};
int main() {
struct stud *ptr=cla;
printf("\n1 roll=%d", ptr->roll);
printf("\n2 roll=%d", ++ptr->roll);
printf("\n3 roll=%d", (++ptr)->roll);
return 0;
}
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Example
#include <stdio.h>
struct stud{
int roll;
char dept[25];
float cgpa;
};
struct stud cla[2]={{7,"EEE", 8.75f}, {17,"CSIS", 7.50f}};
int main()
{
struct stud *ptr=cla;
printf("\n1 roll=%d", ptr->roll);
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
Alternative Solution
#include <stdio.h>
int a = 10, b = 20;
void swap(){
int main()
{
printf("Before Swapping %d %d\n", a, b);
swap();
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 temp, i , j, sorted = 0; int main() {
for(i = 0; i < SIZE-i-1; i++){ int arr[8] = {2,5,9,7,1,5,4,6};
for(j = 0; j<SIZE-1-i; j++){ int SIZE = 8;
if(a[j] > a[j + 1]) printf(“Array before sort: \n”);
{
temp = a[j]; for (i = 0; i < SIZE; i++)
a[j] = a[j + 1]; printf("%d ", arr[i]);
a[j + 1] = temp; printf("\n");
}
sort(arr);
}
} printf(“Array after sort: \n");
} for (i = 0; i < SIZE; i++)
When arrays are passed as printf("%d ", arr[i]);
parameters, you pass the printf("\n");
address of the first location return 0; sort() function implements bubble
which the array variable name } sort which is one of the sorting
algorithms. Don’t worry about it.
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Arrays as input parameter
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Selection sorting
#include <stdio.h>
void printArray(int *array, int size) {
void swap(int *a, int *b) {
for (int i = 0; i < size; ++i) {
int temp = *a;
printf("%d ", *(array+i));
*a = *b;
}
*b = temp;
printf("\n");
}
}
void selectionSort(int *array, int size) {
for (int stp = 0; stp < size - 1; stp++) {
int main() {
int min_idx = stp;
int data[] = {16, 12, 10, 15, 19};
for (int i = stp + 1; i < size; i++)
int size = sizeof(data) / sizeof(int);
{ // Select the min element in each loop.
selectionSort(data, size);
if (array[i] < array[min_idx])
printf("Sorted array in Acsending Order using
min_idx = i;
Selection Sorting:\n");
}
printArray(data, size);
// put min at the correct position
}
swap(&array[min_idx], &array[stp]);
}
}
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
Explained
#include <stdio.h>
nt strlen1(char *str) {
char *p; int cnt=0;
for (p=str; *p != '\0'; p++);
printf("%u, %u", p,str);
return p-str;
}
int main()
{
char *ptr="Hello World";
printf("\nlen1=%d", strlen1(ptr));
return 0;
}
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;
void swap(ST * p1, ST * p2){
ST temp; printf("s1.a:%d, s1.b:%f\n",s1.a,s1.b);
temp.a = (*p1).a; printf("s2.a:%d, s2.b:%f\n",s2.a,s2.b);
temp.b = (*p1).b;
(*p1).a = (*p2).a; swap(&s1, &s2);
(*p1).b = (*p2).b;
(*p2).a = temp.a; printf("s1.a: %d, s1.b:%f\n",s1.a,s1.b);
(*p2).b = temp.b; printf("s2.a: %d, s2.b:%f\n",s2.a,s2.b);
} }
Be careful of the precedence of “*”and “.” , with the latter having higher precedence.
You must use () if you want the operation to be correct
Dept. of Computer Science & Information Systems, BITS Pilani, Pilani Campus
Pass by reference using
structures (equivalent)
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