Pointers

Lecture 5 Pointers
1. Variable, memory location, address, value
2. Concepts of pointers
3. Examples of pointer usage
Variable: name, memory location, value
• Every variable in C has a name and a value associated with it. When
a variable is declared, a specific block of memory within the
computer is allocated to hold the value of that variable. The size of
the allocated block depends on the type of the data, e.g. 4 for int
int x = 10;
• When this statement executes, the compiler sets aside 4 bytes of
memory to hold the value 10. It also sets up a symbol table in
which it adds the symbol x and the relative address in memory
where those 4 bytes are set aside.
© Oxford University Press 2014. All rights reserved.
Variable, address
• Thus, every variable in C has a value and an a
memory location associated with it.
• The & operator retrieves the address of x,
i.e., the address of the first memory cell of
the memory location.
© Oxford University Press 2014. All rights reserved.
Variable: name, memory location
Variable name x
reference to memory location
65329
10
address at memory location
Value at memory location
Value stored in either big
endian or little endian
format.
65325
65324
int x = 10;
x represents variable name
(e.g. an assigned name for a memory location )
&x represents the starting address of the location
of x, e.g. 65325
*(&x) or x represents the value of at location x, 10
Program example
#include<stdio.h>
int main()
{
int x = 10;
printf("Value of x is %d\n",x);
printf("Address of x in Hex is %p\n",&x);
printf("Address of x in decimal is %lu\n",&x);
printf("Value at address of x is %d\n",*(&x));
return 0;
}
Value of x is 10
Address of x in Hex is 0061FF0C
Address of x in decimal is 6422284
Value at address of x is 10
2. Concept of Pointers
• A pointer is a variable that contains the memory address
of another variable.
• The general syntax of declaring pointer variable is
data_type* ptr_name;
• The '*' informs the compiler that ptr_name is a pointer
variable and data_type specifies that it will store the
address of data_type variable.
© Oxford University Press 2014. All rights reserved.
Dereferencing a Pointer Variable
 We can "dereference" a pointer, i.e. refer to
the value of the variable to which it points
by using unary '*' operator as in *ptr.
 That is, *ptr has value 10, since 10 is value
of x.
© Oxford University Press 2014. All rights reserved.
Example of Pointer
int x = 10;
int *p = &x;
If pointer p holds the address of variable a, we say p points to a
*p represents the value stored at address p
*p is called dereferencing of pointer p
• Using pointer to get the memory address of anther variable, as
well as the value of that variable
pointer
int x = 10;
int *ptr;
ptr = &x;
65329
variable name
x
65325
10
65324
pointer variable name
ptr 65320
65325
*ptr
Variable vs Pointer
65329
Variable
int x = 10;
&x represents address of x
x represents the value stored
65325
at &x
65324
10
10
int *p;
*p = 10; // this is not correct.
Pointer
int *p; p is declared to be an int pointer
p = &a; p holds address of a, i.e.65325
*p represents the value stored at p, ie.10
int b = *p; b will have value 10.
*p = 20; a will have value 20.
Pointer example
#include<stdio.h>
int main() {
int x = 10;
int *ptr;
ptr = &x;
printf("Value of x is %d\n", x);
printf("Address of x is %lu\n", (unsigned long int) &x);
printf("Value of pointer ptr is %lu\n", (unsigned long int) ptr);
printf("Address of pointer ptr is %lu\n", (unsigned long int) &ptr);
printf("Ptr pointing value is %d\n",*ptr);
return 0;
Value of x is 10
}
Address of x is 6422284
Value of pointer ptr is 6422284
Address of pointer ptr is 6422280
Ptr pointing value is 10
Why pointer?
1. Pointers provide an alternative way to address memory
location of data type and its stored value
2. As variables, pointers make it possible to do address
operations, so as to access memory space for data
operations
3. More features:
–
–
–
–
Pointers support dynamic memory management.
Pointer helps to return multiple values from a function
through function argument
Pointer increases program execution speed
Pointer is an efficient tool for manipulating complex data
structures like linked lists, queues, stacks, trees etc.
Pointer Expressions and Arithmetic
• Pointer variables can also be used in expressions. For example,
int num1=2, num2= 3, sum=0, mul=0, div=1;
int *ptr1, *ptr2;
ptr1 = &num1; ptr2 = &num2;
sum = *ptr1 + *ptr2; // the value of sum is ?
mul = sum * *ptr1;
// the value of mul is ?
• We can compare pointers by using relational operators in the
expressions. For example p1 > p2 , p1==p2 and p1!=p2 are all
valid in C.
© Oxford University Press 2014. All rights reserved.
Pointer Expressions and Arithmetic
• When using pointers, unary increment (++) and decrement (--)
operators have greater precedence than the dereference
operator (*).
• Therefore, the expression *ptr++ is equivalent to *(ptr++).
• The expression will increase the value of ptr so that it now points
to the next element.
• In order to increment the value of the variable whose address is
stored in ptr, write (*ptr)++.
© Oxford University Press 2014. All rights reserved.
Null Pointers
• A null pointer is a special pointer value that is known not to point
anywhere. This means that a NULL pointer does not point to any
valid memory address.
• To declare a null pointer you may use the predefined constant
NULL.
int *ptr = NULL;
 It is used in situations if one of the pointers in the program points
somewhere some of the time but not all of the time.
 In such situations it is always better to set it to a null pointer when
it doesn't point anywhere valid, and to test to see if it's a null
pointer before using it.
© Oxford University Press 2014. All rights reserved.
Generic Pointers
• A generic pointer is pointer variable that has void as its data type.
• The generic pointer can be pointed at variables of any data type.
• It is declared by writing
void *ptr;
• You need to cast a void pointer to another kind of pointer before
using it.
int a = 10;
void *ptr = &a;
printf("%d", *(int *)ptr);
• Generic pointers are used when a pointer has to point to data of
different types at different times.
© Oxford University Press 2014. All rights reserved.
Pass by reference
#include<stdio.h>
void add(int*, int) ;
int main( void ) {
int n = 2, j = 2;
add( &n, j);
printf( "n = %i\n", n );
printf( "j = %i\n", j );
return 0;
} /* main */
void add( int* x, int y) {
*x = *x + 1;
y=y+1;
} /* add */
n= 3
j = 2
Pointer to Pointers
• You can use pointers that point to pointers. The pointers in turn
point to data (or even to other pointers). To declare pointers to
pointers just add an asterisk (*) for each level of reference.
• For example, if we have:
10
int x=10;
1002
2004
int *px, **ppx;
x
px=&x;
px
ppx=&px;
Now if we write,
printf(“\n %d”, **ppx);
This would print 10, the value of x.
© Oxford University Press 2014. All rights reserved.
ppx
Pointer of pointer example
#include<stdio.h>
int main()
{
int x = 10, *ptr, **pptr;
ptr = &x;
pptr = &ptr;
Value of x is 10
Address of x in Hex is 0061FF0C
Address of x in decimal is 6422284
Value of pointer variable ptr is 0061FF0C (address in
Hex)
Address of pointer variable ptr is 6422280
The value pointed by Ptr is 10
Address of pointer pptr is 6422276
The value pointed by pptr is 6422284
The pointed by pptr is 10 or 10
printf("Value of x is %d\n", x);
printf("Address of x in Hex is %p\n",&x);
printf("Address of x in decimal is %lu\n", &x);
printf("Value of pointer variable ptr is %p (address in Hex)\n", ptr);
printf("Address of pointer variable ptr is %lu\n", &ptr);
printf("The value pointed by Ptr is %d\n",*ptr);
printf("Address of pointer pptr is %lu\n", &pptr);
printf("The value pointed by pptr is %lu\n", *pptr);
printf("The pointed by pptr is %d or %d\n", **pptr, *(*pptr));
return 0;
}
Example of pass by reference
#include <stdio.h>
void swap(int *, int *);
int main() {
int i = 5, j = 10;
printf("Before exchange, i = %d, j = %d\n", i, j);
swap( &i, &j);
printf("After exchange, i = %d, j = %d\n", i, j);
return 0;
}
void swap( int *first, int *second ) {
int temp;
temp = *first;
*first = *second;
*second = temp;
}
Omitting * is a common mistake.
#include <stdio.h>
void swap ( int *ptr1, int *ptr2 ) {
int temp;
temp = *ptr1;
*ptr1 = *ptr2;
*ptr2 = temp;
}
void exchange(int *q1, int *q2, int *q3) {
if (*q1 < *q2) swap(q1, q2);
if (*q1 < *q3) swap(q1, q3);
if (*q2 < *q3) swap(q2, q3);
}
int main() {
int a, b, c, *p1, *p2, *p3;
scanf("%d,%d,%d",&a, &b, &c);
p1 = &a;
p2 = &b;
p3 = &c;
exchange(p1, p2, p3);
printf("\n%d,%d,%d\n",a,b,c);
}
6,3,9
p1
p2
p3
a
6
b
3
c
9
p1
p2
p3
a
9
b
3
c
6
p1
p2
p3
a
9
b
6
c
3
9,6,3
p1 = &a;
p2 = &b;
p3 = &c;
exchange
(p1, p2, p3);
*q1 < *q3
swap(q1,q3)
*q2 < *q3
swap(q2,q3)
Function type pointer
int max();
int (*p)();
p = max;
// declare a function pointer
// pointing to function max()
c = (*p)(a, b); // use pointer to call the function
Example of function type pointer
#include <stdio.h>
int mul(int a, int b, int c) { return a*b*c; }
int main() {
int (*function_pointer)(int, int, int);
function_pointer = mul;
printf("The product of three numbers is:%d",
function_pointer(2, 3, 4));
return 0;
}
// ouput: 24
Functions as parameter
#include <stdio.h>
int max(int, int);
int min(int, int);
void process(int, int, int (*)());
int main(){
int max(), min(), (*p)(), a, b, c ;
p = max;
scanf("%d,%d",&a,&b);
c = (*p)(a,b);
printf("Max is %d\n", c);
printf("Max is ");
process(a, b, max);
printf("\n");
printf("Min is ");
process(a, b, min);
printf("\n");
return 0;
}
int max(int x, int y){
int z;
z = x > y? x:y;
return(z);
}
int min(int x, int y){
int z;
z = x < y? x:y;
return(z);
}
void process(int x, int y, int (*fun)()){
int result;
result = (*fun)(x, y);
printf("%d", result);
}