You are on page 1of 54

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
The Stack
 The stack is the place where all local variables are stored
 a local variable is declared in some scope

 Example

int x; // creates the variable x on the stack


 As soon as the scope ends, all local variables declared in
that scope end
 the variable name and its space are gone

 this happens implicitly – the user has no control over


it
The Heap
 The heap is an area of memory that the user handles
explicitly
 user requests and releases the memory through

system calls
 if a user forgets to release memory, it doesn’t get

destroyed
 it just uses up extra memory

 A user maintains a handle on memory allocated in


the heap with a pointer
Basic Idea
1200 1216
pointer
ending address
(on the stack)
of data

starting address
of data

1200
data
(on the heap)
Declaring Pointers
 Declaring a pointer is easy
 declared like regular variable except that an asterisk
(*) is placed in front of the variable
 example
int *x;
 using this pointer now would be very dangerous
 x points to some random piece of data
 declaring a variable does not allocate space on the
heap for it
 it simply creates a local variable (on the stack) that will is a
pointer
 use malloc() to actually request memory on the heap
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

8
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

9
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 */

10
Why do we need Pointer?
 Simply because it’s there!
 It is used in some circumstances in C

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

11
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 =
address of i
printf(“ptr = %p\n”, ptr); *ptr = 5
in memory
ptr = effff5e0

12
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

13
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

14
Example: Pass by Reference
 Modify behaviour in argument passing

void f(int j) void f(int *ptr)


{ {
j = 5; *ptr = 5;
} }
void g() void g()
{ {
int i = 3; int i = 3;
f(i); f(&i);
i = 3? i = 5?
} }

15
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;

16
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;

17
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 Indirection
18
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
19
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) 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 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
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 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 22
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
23
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 24
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) 25
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
26
Pointer Arithmetic
 What’s ptr + 1?
 The next memory location!
 What’s ptr - 1?
 The previous memory location!
 What’s ptr * 2 and ptr / 2?
 Invalid operations!!!

27
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;
a[3] float float array element (variable) ?
ptr = ptr - 3;
ptr float * float pointer variable
*ptr = 6.0;
*ptr float de-reference of float pointer ?
ptr += 2;
variable
*ptr = 7.0;

28
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;
a[3] float float array element (variable) ?
ptr = ptr - 3;
ptr float * float pointer variable address of a[2]
*ptr = 6.0;
*ptr float de-reference of float pointer ?
ptr += 2;
variable
*ptr = 7.0;

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) 3.14
*ptr = 9.0;
a[3] float float array element (variable) ?
ptr = ptr - 3;
ptr float * float pointer variable address of a[2]
*ptr = 6.0;
*ptr float de-reference of float pointer 3.14
ptr += 2;
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) 3.14
*ptr = 9.0;
a[3] float float array element (variable) ?
ptr = ptr - 3;
ptr float * float pointer variable address of a[3]
*ptr = 6.0;
*ptr float de-reference of float pointer ?
ptr += 2;
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;
a[3] float float array element (variable) 9.0
ptr = ptr - 3;
ptr float * float pointer variable address of a[3]
*ptr = 6.0;
*ptr float de-reference of float pointer 9.0
ptr += 2;
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;
a[3] float float array element (variable) 9.0
ptr = ptr - 3;
ptr float * float pointer variable address of a[0]
*ptr = 6.0;
*ptr float de-reference of float pointer ?
ptr += 2;
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) 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;
a[3] float float array element (variable) 9.0
ptr = ptr - 3;
ptr float * float pointer variable address of a[0]
*ptr = 6.0;
*ptr float de-reference of float pointer 6.0
ptr += 2;
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) 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;
a[3] float float array element (variable) 9.0
ptr = ptr - 3;
ptr float * float pointer variable address of a[2]
*ptr = 6.0;
*ptr float de-reference of float pointer 3.14
ptr += 2;
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) 7.0
*ptr = 9.0;
a[3] float float array element (variable) 9.0
ptr = ptr - 3;
ptr float * float pointer variable address of a[2]
*ptr = 6.0;
*ptr float de-reference of float pointer 7.0
ptr += 2;
variable
*ptr = 7.0;

36
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;

37
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 …
38
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 …
39
Use of & and *

 When is & used?

 When is * used?

 & -- "address operator" which gives or produces the


memory address of a data variable
 * -- "dereferencing operator" which provides the
contents in the memory location specified by a
pointer

Lect 14 P. 40
Pointers and Functions
 Pointers can be used to pass addresses of variables
to called functions, thus allowing the called function
to alter the values stored there.

 We looked earlier at a swap function that did not


change the values stored in the main program
because only the values were passed to the function
swap.

 This is known as "call by value".

Lect 14 P. 41
Pointers and Functions
 If instead of passing the values of the variables to
the called function, we pass their addresses, so that
the called function can change the values stored in
the calling routine. This is known as "call by
reference" since we are referencing the variables.

 The following shows the swap function modified from


a "call by value" to a "call by reference". Note that
the values are now actually swapped when the
control is returned to main function.

Lect 14 P. 42
Pointers with Functions
(example)
#include <stdio.h> void swap( int *a, int *b )
void swap ( int *a, int *b ) ; {
int main ( ) int temp;
{ temp= *a; *a= *b; *b = temp ;
int a = 5, b = 6; printf ("a=%d b=%d\n", *a, *b);
printf("a=%d b=%d\n",a,b) ; }
Results:
swap (&a, &b) ;
a=5 b=6
printf("a=%d b=%d\n",a,b) ;
a=6 b=5
return 0 ;
a=6 b=5
}

Lect 14 P. 43
Arithmetic and Logical
Operations on Pointers
 A pointer may be incremented or decremented

 An integer may be added to or subtracted from a


pointer.

 Pointer variables may be subtracted from one


another.

 Pointer variables can be used in comparisons, but


usually only in a comparison to NULL.

Lect 14 P. 44
Arithmetic Operations on
Pointers
 When an integer is added to or subtracted from a
pointer, the new pointer value is changed by the
integer times the number of bytes in the data
variable the pointer is pointing to.

 For example, if the pointer valptr contains the


address of a double precision variable and that
address is 234567870, then the statement:
valptr = valptr + 2;
would change valptr to 234567886

Lect 14 P. 45
Using the C Language Special
Keyword
sizeof
 This keyword can be used to determine the number
of bytes in a data type, a variable, or an array
 Example:
double array [10];
sizeof (double); /* Returns the value 8 */
sizeof (array); /* Returns the value 80
*/
sizeof(array)/sizeof(double); /* Returns 10 */

Lect 14 P. 46
Problem G12

 A bubble sort can be used to sort the wrist pins in


order of size from smallest to largest.
 Six volunteers are needed for a demonstration of the
bubble sort.
 The students will be sorted on the basis of height.
 Start with the first person and compare heights with
the second person.
 If the first is taller, they swap places.
 Continue to compare no. 2 to no. 3
 Are they now sorted according to height? If not,
continue sorting.

Lect 14 P. 47
Problem G12

 This problem deals with the wrist pin data from G10
so you might want to use that program to start G12.
 You want to sort the data until it goes from the
smallest to the largest.
 You start at the first wrist pin and compare it to the
next pin. If it is larger, swap the pins.
 Continue to do this until you have made one pass
through the data set.

Lect 14 P. 48
Problem G12

 Now check the modified data against the original set.


 Some pins will have been moved but the modified set
may not be completely sorted.
 Make another pass manually.
 Are you closer to total sorting being complete?
 You want swapping to continue until the sorting is
done.

Lect 14 P. 49
Problem G12

 This is a good application for a do - while loop.


 But what is the test?

Lect 14 P. 50
START
Flow Chart
Declare Vars
finptr,foutptr
i,changes,x
wpin[20],temp

Open Files

Y Print “did not


fin NULL
open”

Read in data

Actions of
agorithm

Print sorted list

END

Lect 14 P. 51
START
sorting
START
Flow Chart
Initialize
Declare Vars Changes = 1
finptr,foutptr
i,changes,x
wpin[20],temp
While
Changes N
Open Files =1

Changes = 0
Y Print “did not
fin NULL
open”

N i=0 i<=18
i++

Read in data

Wpin[i]>
wpin[i+1]

Actions of Y
agorithm
Exchange wpin
data
Changes = 1
Print sorted list

END Sort
END

Lect 14 P. 52
Advice and Precaution
 Pros
 Efficiency

 Convenience

 Cons
 Error-prone

 Difficult to debug

53
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

54

You might also like