You are on page 1of 42

Pointers in C

1
Pre-requisite

◼ Basics of the C programming language


◼ Data type
◼ Variable
◼ Array
◼ Function call
◼ Standard Input/Output
◼ e.g. printf(), scanf()

2
Outline

◼ Computer Memory Structure


◼ Addressing Concept
◼ Introduction to Pointer
◼ Pointer Manipulation
◼ Summary

3
Computer Memory Revisited

◼ Computers store data in memory slots


◼ Each slot has an unique address
◼ Variables store their values like this:

Addr Content Addr Content Addr Content Addr Content


1000 i: 37 1001 j: 46 1002 k: 58 1003 m: 74
1004 a[0]: ‘a’ 1005 a[1]: ‘b’ 1006 a[2]: ‘c’ 1007 a[3]: ‘\0’
1008 ptr: 1001 1009 … 1010 1011

4
Computer Memory Revisited

◼ Altering the value of a variable is indeed


changing the content of the memory
◼ e.g. i = 40; a[2] = ‘z’;

Addr Content Addr Content Addr Content Addr Content


1000 i: 40 1001 j: 46 1002 k: 58 1003 m: 74
1004 a[0]: ‘a’ 1005 a[1]: ‘b’ 1006 a[2]: ‘z’ 1007 a[3]: ‘\0’
1008 ptr: 1001 1009 … 1010 1011

5
Addressing Concept

◼ Pointer stores the address of another


entity
◼ It refers to a memory location

int i = 5;
int *ptr; /* declare a pointer variable */
ptr = &i; /* store address-of i to ptr */
printf(“*ptr = %d\n”, *ptr); /* refer to referee of ptr */

6
Why do we need Pointer?

◼ Simply because it’s there!


◼ It is used in some circumstances in C

Remember this?
scanf(“%d”, &i);

7
What actually ptr is?

◼ ptr is a variable storing an address


◼ ptr is NOT storing the actual value of i
ptr address of i
int i = 5;
int *ptr;
ptr = &i; i 5
printf(“i = %d\n”, i); Output:
printf(“*ptr = %d\n”, *ptr); i = 5 value of ptr =
printf(“ptr = %p\n”, ptr); *ptr = 5 address of i
in memory
ptr = effff5e0

8
Twin Operators

◼ &: Address-of operator


◼ Get the address of an entity
◼ e.g. ptr = &j;

Addr Content Addr Content Addr Content Addr Content


1000 i: 40 1001 j: 33 1002 k: 58 1003 m: 74
1004 ptr: 1001 1005 1006 1007

9
Twin Operators

◼ *: De-reference operator
◼ Refer to the content of the referee
◼ e.g. *ptr = 99;

Addr Content Addr Content Addr Content Addr Content


1000 i: 40 1001 j: 99 1002 k: 58 1003 m: 74
1004 ptr: 1001 1005 1006 1007

10
An Illustration
int i = 5, j = 10;
int *ptr;
int **pptr;
ptr = &i;
pptr = &ptr;
*ptr = 3; Data Table
**pptr = 7; Name Type Description Value
ptr = &j; i int integer variable 5
**pptr = 9; j int integer variable 10
*pptr = &i;
*ptr = -2;

12
An Illustration
int i = 5, j = 10;
int *ptr; /* declare a pointer-to-integer variable */
int **pptr;
ptr = &i;
pptr = &ptr;
*ptr = 3; Data Table
**pptr = 7; Name Type Description Value
ptr = &j; i int integer variable 5
**pptr = 9; j int integer variable 10
*pptr = &i; ptr int * integer pointer variable
*ptr = -2;

13
An Illustration
int i = 5, j = 10;
int *ptr;
int **pptr; /* declare a pointer-to-pointer-to-integer variable */
ptr = &i;
pptr = &ptr;
*ptr = 3; Data Table
**pptr = 7; Name Type Description Value
ptr = &j; i int integer variable 5
**pptr = 9; j int integer variable 10
*pptr = &i; ptr int * integer pointer variable
*ptr = -2;
pptr int ** integer pointer pointer variable

Double
14
An Illustration
int i = 5, j = 10;
int *ptr;
int **pptr;
ptr = &i; /* store address-of i to ptr */
pptr = &ptr;
*ptr = 3; Data Table
**pptr = 7; Name Type Description Value
ptr = &j; i int integer variable 5
**pptr = 9; j int integer variable 10
*pptr = &i; ptr int * integer pointer variable address of i
*ptr = -2;
pptr int ** integer pointer pointer variable
*ptr int de-reference of ptr 5
15
An Illustration
int i = 5, j = 10;
int *ptr;
int **pptr;
ptr = &i;
pptr = &ptr; /* store address-of ptr to pptr */
*ptr = 3; Data Table
**pptr = 7; Name Type Description Value
ptr = &j; i int integer variable 5
**pptr = 9; j int integer variable 10
*pptr = &i; ptr int * integer pointer variable address of i
*ptr = -2;
pptr int ** integer pointer pointer variable address of ptr
*pptr int * de-reference of pptr value of ptr
(address of i) 16
An Illustration
int i = 5, j = 10;
int *ptr;
int **pptr;
ptr = &i;
pptr = &ptr;
*ptr = 3; Data Table
**pptr = 7; Name Type Description Value
ptr = &j; i int integer variable 3
**pptr = 9; j int integer variable 10
*pptr = &i; ptr int * integer pointer variable address of i
*ptr = -2;
pptr int ** integer pointer pointer variable address of ptr
*ptr int de-reference of ptr 3
17
An Illustration
int i = 5, j = 10;
int *ptr;
int **pptr;
ptr = &i;
pptr = &ptr;
*ptr = 3; Data Table
**pptr = 7; Name Type Description Value
ptr = &j; i int integer variable 7
**pptr = 9; j int integer variable 10
*pptr = &i; ptr int * integer pointer variable address of i
*ptr = -2;
pptr int ** integer pointer pointer variable address of ptr
**pptr int de-reference of de-reference of 7
pptr 18
An Illustration
int i = 5, j = 10;
int *ptr;
int **pptr;
ptr = &i;
pptr = &ptr;
*ptr = 3; Data Table
**pptr = 7; Name Type Description Value
ptr = &j; i int integer variable 7
**pptr = 9; j int integer variable 10
*pptr = &i; ptr int * integer pointer variable address of j
*ptr = -2;
pptr int ** integer pointer pointer variable address of ptr
*ptr int de-reference of ptr 10
19
An Illustration
int i = 5, j = 10;
int *ptr;
int **pptr;
ptr = &i;
pptr = &ptr;
*ptr = 3; Data Table
**pptr = 7; Name Type Description Value
ptr = &j; i int integer variable 7
**pptr = 9; j int integer variable 9
*pptr = &i; ptr int * integer pointer variable address of j
*ptr = -2;
pptr int ** integer pointer pointer variable address of ptr
**pptr int de-reference of de-reference of 9
pptr 20
An Illustration
int i = 5, j = 10;
int *ptr;
int **pptr;
ptr = &i;
pptr = &ptr;
*ptr = 3; Data Table
**pptr = 7; Name Type Description Value
ptr = &j; i int integer variable 7
**pptr = 9; j int integer variable 9
*pptr = &i; ptr int * integer pointer variable address of i
*ptr = -2;
pptr int ** integer pointer pointer variable address of ptr
*pptr int * de-reference of pptr value of ptr
(address of i) 21
An Illustration
int i = 5, j = 10;
int *ptr;
int **pptr;
ptr = &i;
pptr = &ptr;
*ptr = 3; Data Table
**pptr = 7; Name Type Description Value
ptr = &j; i int integer variable -2
**pptr = 9; j int integer variable 9
*pptr = &i; ptr int * integer pointer variable address of i
*ptr = -2;
pptr int ** integer pointer pointer variable address of ptr
*ptr int de-reference of ptr -2
22
CALL BY VALUE/CALL
BY REFERENCE
Pointers

23
Call by Value
◼ The value of the actual parameters is copied into the
formal parameters.
◼ In call by value method, we can not modify the value of
the actual parameter by the formal parameter.
◼ In call by value, different memory is allocated for actual
and formal parameters since the value of the actual
parameter is copied into the formal parameter.
◼ The actual parameter is the argument which is used in the
function call whereas formal parameter is the argument
which is used in the function definition.

24
Call by Value Example: Swapping
the values of the two variables
Call by value

25
Call by value

◼ OUTPUT

26
Call by Reference

◼ In call by reference, the address of the variable is passed


into the function call as the actual parameter.
◼ The value of the actual parameters can be modified by
changing the formal parameters since the address of the
actual parameters is passed.
◼ In call by reference, the memory allocation is similar for
both formal parameters and actual parameters. All the
operations in the function are performed on the value
stored at the address of the actual parameters, and the
modified value gets stored at the same address.

27
Call by Reference

◼ Output

28
Pointer Arithmetic

◼ What’s ptr + 1?
➔ Thenext memory location!
◼ What’s ptr - 1?

➔ Theprevious memory location!


◼ What’s ptr * 2 and ptr / 2?

➔ Invalid operations!!!

29
Pointer Arithmetic and Array
float a[4];
Data Table
float *ptr;
Name Type Description Value
ptr = &(a[2]);
a[0] float float array element (variable) ?
*ptr = 3.14;
a[1] float float array element (variable) ?
ptr++;
a[2] float float array element (variable) ?
*ptr = 9.0;
ptr = ptr - 3;
a[3] float float array element (variable) ?

*ptr = 6.0; ptr float * float pointer variable


ptr += 2; *ptr float de-reference of float pointer ?
variable
*ptr = 7.0;

30
Pointer Arithmetic and Array
float a[4];
Data Table
float *ptr;
Name Type Description Value
ptr = &(a[2]);
a[0] float float array element (variable) ?
*ptr = 3.14;
a[1] float float array element (variable) ?
ptr++;
a[2] float float array element (variable) ?
*ptr = 9.0;
ptr = ptr - 3;
a[3] float float array element (variable) ?

*ptr = 6.0; ptr float * float pointer variable address of a[2]


ptr += 2; *ptr float de-reference of float pointer ?
variable
*ptr = 7.0;

31
Pointer Arithmetic and Array
float a[4];
Data Table
float *ptr;
Name Type Description Value
ptr = &(a[2]);
a[0] float float array element (variable) ?
*ptr = 3.14;
a[1] float float array element (variable) ?
ptr++;
a[2] float float array element (variable) 3.14
*ptr = 9.0;
ptr = ptr - 3;
a[3] float float array element (variable) ?

*ptr = 6.0; ptr float * float pointer variable address of a[2]


ptr += 2; *ptr float de-reference of float pointer 3.14
variable
*ptr = 7.0;

32
Pointer Arithmetic and Array
float a[4];
Data Table
float *ptr;
Name Type Description Value
ptr = &(a[2]);
a[0] float float array element (variable) ?
*ptr = 3.14;
a[1] float float array element (variable) ?
ptr++;
a[2] float float array element (variable) 3.14
*ptr = 9.0;
ptr = ptr - 3;
a[3] float float array element (variable) ?

*ptr = 6.0; ptr float * float pointer variable address of a[3]


ptr += 2; *ptr float de-reference of float pointer ?
variable
*ptr = 7.0;

33
Pointer Arithmetic and Array
float a[4];
Data Table
float *ptr;
Name Type Description Value
ptr = &(a[2]);
a[0] float float array element (variable) ?
*ptr = 3.14;
a[1] float float array element (variable) ?
ptr++;
a[2] float float array element (variable) 3.14
*ptr = 9.0;
ptr = ptr - 3;
a[3] float float array element (variable) 9.0

*ptr = 6.0; ptr float * float pointer variable address of a[3]


ptr += 2; *ptr float de-reference of float pointer 9.0
variable
*ptr = 7.0;

34
Pointer Arithmetic and Array
float a[4];
Data Table
float *ptr;
Name Type Description Value
ptr = &(a[2]);
a[0] float float array element (variable) ?
*ptr = 3.14;
a[1] float float array element (variable) ?
ptr++;
a[2] float float array element (variable) 3.14
*ptr = 9.0;
ptr = ptr - 3;
a[3] float float array element (variable) 9.0

*ptr = 6.0; ptr float * float pointer variable address of a[0]


ptr += 2; *ptr float de-reference of float pointer ?
variable
*ptr = 7.0;

35
Pointer Arithmetic and Array
float a[4];
Data Table
float *ptr;
Name Type Description Value
ptr = &(a[2]);
a[0] float float array element (variable) 6.0
*ptr = 3.14;
a[1] float float array element (variable) ?
ptr++;
a[2] float float array element (variable) 3.14
*ptr = 9.0;
ptr = ptr - 3;
a[3] float float array element (variable) 9.0

*ptr = 6.0; ptr float * float pointer variable address of a[0]


ptr += 2; *ptr float de-reference of float pointer 6.0
variable
*ptr = 7.0;

36
Pointer Arithmetic and Array
float a[4];
Data Table
float *ptr;
Name Type Description Value
ptr = &(a[2]);
a[0] float float array element (variable) 6.0
*ptr = 3.14;
a[1] float float array element (variable) ?
ptr++;
a[2] float float array element (variable) 3.14
*ptr = 9.0;
ptr = ptr - 3;
a[3] float float array element (variable) 9.0

*ptr = 6.0; ptr float * float pointer variable address of a[2]


ptr += 2; *ptr float de-reference of float pointer 3.14
variable
*ptr = 7.0;

37
Pointer Arithmetic and Array
float a[4];
Data Table
float *ptr;
Name Type Description Value
ptr = &(a[2]);
a[0] float float array element (variable) 6.0
*ptr = 3.14;
a[1] float float array element (variable) ?
ptr++;
a[2] float float array element (variable) 7.0
*ptr = 9.0;
ptr = ptr - 3;
a[3] float float array element (variable) 9.0

*ptr = 6.0; ptr float * float pointer variable address of a[2]


ptr += 2; *ptr float de-reference of float pointer 7.0
variable
*ptr = 7.0;

38
Pointer Arithmetic and Array
float a[4];
◼ Type of a is float *
float *ptr;
ptr = &(a[2]); ◼ a[2] ➔ *(a + 2)
*ptr = 3.14; ptr = &(a[2])
ptr++; ➔ ptr = &(*(a + 2))
*ptr = 9.0;
➔ ptr = a + 2
ptr = ptr - 3;
*ptr = 6.0; ◼ a is a memory address constant
ptr += 2; ◼ ptr is a pointer variable
*ptr = 7.0;

39
More Pointer Arithmetic

◼ What if a is a double array?


◼ A double may occupy more memory slots!
◼ Given double *ptr = a;
◼ What’s ptr + 1 then?

Addr Content Addr Content Addr Content Addr Content


1000 a[0]: 37.9 1001 … 1002 … 1003 …
1004 a[1]: 1.23 1005 … 1006 … 1007 …
1008 a[2]: 3.14 1009 … 1010 … 1011 …
40
More Pointer Arithmetic

◼ Arithmetic operators + and – auto-adjust


the address offset
◼ According to the type of the pointer:
◼ 1000 + sizeof(double) = 1000 + 4 = 1004

Addr Content Addr Content Addr Content Addr Content


1000 a[0]: 37.9 1001 … 1002 … 1003 …
1004 a[1]: 1.23 1005 … 1006 … 1007 …
1008 a[2]: 3.14 1009 … 1010 … 1011 …
41
Advice and Precaution

◼ Pros
◼ Efficiency
◼ Convenience
◼ Cons
◼ Error-prone
◼ Difficult to debug

42
Summary

◼ A pointer stores the address (memory


location) of another entity
◼ Address-of operator (&) gets the
address of an entity
◼ De-reference operator (*) makes a
reference to the referee of a pointer
◼ Pointer and array
◼ Pointer arithmetic

43

You might also like