Anda di halaman 1dari 23

Pointers in C

• Pointer is a fundamental part of C.


• Use of pointers gives the power and flexibility.
• C uses pointers explicitly with
– Arrays,
– Structures,
– Functions.
• C uses pointers a lot.
– It is the only way to express some computations.
– It produces compact and efficient code.
– It provides a very powerful tool.
What is a Pointer?
• A pointer is a variable which contains the
address in memory of another variable.
• We can have a pointer to any variable type.
• The operator & gives the address of a variable.
• The indirection or dereference operator * gives
the contents of an object pointed to by a
pointer.
• To declare a pointer to a variable do:
int *pointer_var_name;
• In the following example px is a pointer to
objects of type float, and sets it equal to the
address of x:

float x;
float *px;
x = 6.5;
px = &x;

• The content of the memory location referenced


by a pointer is obtained using the ``*'' operator
(this is called dereferencing the pointer).
• Thus, *px refers to the value of x.
• We must associate a pointer to a particular
type.
• We can't assign the address of a short int
to a long int.
• For example, consider the effect of the
following code:
int x = 1, y = 2;
int *ip;
ip = &x;
y = *ip;
*ip = 3;
• When a pointer is declared it does not point
anywhere.
• We must set it to point somewhere before its use.
• So the following statements will generate an error
(program crash!!).
int *p;
*p = 10;

• The correct use is:


int *p, *q, x, y;
p = &x; q = &y;
*p = 10; *q = 20;
p = q; legal but
*p = *q different meaning
Common Pointer Pitfalls
• Here we will highlight two common mistakes
made with pointers.
• Not assigning a pointer to memory address
before using it
int *x;
*x = 100;
• We need a physical location say: int y;
x = &y;
*x = 100;
• This may be hard to spot. NO COMPILER
ERROR. Also x could get some random address
at initialization.
Dynamic Memory Allocation and
Dynamic Structures
• Dynamic allocation is a unique feature to
C (amongst high level languages).
• It enables us to create data types and
structures of any size and length to suit
our programs need within the program.
• There are two common applications of
this:
• dynamic arrays
• dynamic data structure e.g. linked lists
Integer Arithmetic on a pointer
• We can do the following:
float *p, *q;
*p = *p + 10;
++*p; (*p)++; q = p;
• A pointer to any variable type is an address in
memory which is an integer address.
• A pointer is definitely NOT an integer.
• The reason we associate a pointer to a data type
is so that it knows how many bytes the data is
stored in.
• When we increment a pointer we increase the
pointer by one ``block'' memory.
Pointer and Functions
• When C passes arguments to functions it
passes them by value.
• There are many cases when we may want
to alter a passed argument in the function
and receive the new value back once to
function has finished.
• C uses pointers explicitly to do this.
• Let us try and write a function to swap
variables around?
• The usual function call: swap(a,b) WON'T
WORK.
• Pointers provide the solution: Pass the address
of the variables to the functions and access
address of function.
• Thus our function call in our program would look
like this: swap(&a, &b)
• The Code to swap is fairly straightforward:

void swap(int *px, int *py)


{ int temp;
temp = *px;
/* contents of pointer */
*px = *py;
*py = temp;
}
Pointers and Arrays
• Pointers and arrays are very closely linked
in C.
• C treats the name of the array as if it were
a pointer to the first element.
• This is important in understanding how to
do arithmetic with arrays.
• Thus, if v is an array, *v is the same thing
as v[0], *(v+1) is the same thing as v[1],
and so on.
• Here pv is simply indication pointer v
Example
int a[10], x, y;
int *pa;
// pa pointer to address of a[0]
pa = &a[0];
// x = contents of pa (a[0] in this case)
x = *pa;
// same as y = a[i]
y = *(pa + i);
• C however is much more subtle in its link
between arrays and pointers.
• For example, we can just type pa = a;
instead of pa = &a[0] and a[i] can be
written as *(a + i) i.e. &a[i] ≅ a + i.
• We also express pointer addressing like
this: pa[i] ≅ *(pa + i).
• However pointers and arrays are different:
• A pointer is a variable. We can do pa = a
and pa++ etc.
• An Array is not a variable.
• So, a = pa and a++ ARE ILLEGAL.
Handling of array with pointer

#include<stdio.h> #include<stdio.h>
main () main ()
{ {
int a[5], x, y, i; int i,n, *pa;
printf("Input the value of N\n");
scanf("%d", &n);
printf("Input 5 values\n"); pa=malloc(n);
for(i=0;i<5;i++)
{ scanf("%d",&a[i]); }; printf("Input %d values\n", n);
for(i=0;i<n;i++)
printf("Print array with normal { scanf("%d", (pa+i)); };
and pointer methods\n");
for(i=0;i<5;i++) printf("\nprint array using dynamic
{ printf(“%d %d\n",a[i], pointer\n");
*(a+i)); }; for(i=0;i<n;i++)
} { printf(“%d\n", *(pa+i)); };
}
Multidimensional arrays and pointers
• A 2D (two dimensional) array (in maths similar to
matrix) is really a 1D array, each of whose
elements is itself an array.
• Hence in a[n][m] notation, there are n rows and
m columns.
• Array elements are stored row by row.
• When we pass a 2D array to a function we must
specify the number of columns and the number
of rows is irrelevant.
• The reason for this is pointers again. C needs to
know how many columns in order that it can
jump from row to row in memory.
Example:
• Consider int a[5][35] to be passed in a function:
• We can define function definition as:
f(int a[][35])
{ }
OR
f(int (*a)[35])
{ }

• int (*a)[35]; declares a pointer to an array of 35


integers whereas int *a[35]; declares an array
of 35 pointers to integers. Both are different.
Malloc, Sizeof, and Free
• The system defined function malloc is
most commonly used to attempt to ``grab''
a continuous portion of memory.
• If memory cannot be allocated then a
NULL pointer is returned.
char *cp;
cp = malloc(100);
• It attempts to get 100 bytes and assigns
the start address to cp.
• Also it is usual to use the sizeof() function
to specify the number of bytes:
int *ip;
ip = (int *) malloc(100*sizeof(int));
• Some C compilers may require to cast the
type of conversion.
• The (int *) means coercion to an integer
pointer.
• Coercion to the correct pointer type is very
important to ensure that the pointer
arithmetic is performed correctly.
• It is good practice to use sizeof() even if
you know the actual size you want as it
makes code device independent
(portable).
• sizeof can be used to find the size of any
data type, variable or structure. Simply
supply one of these as an argument to the
function.
• NULL is a pointer constant.
• If p = NULL means that p is an empty
pointer.
• When you have finished using a portion of
memory you should always free() it.
• This allows the memory freed to be
available again, possibly for further
malloc() calls
• The function free() takes a pointer as an
argument and frees the memory to which
the pointer refers.
Illegal indirection
• Consider:
// request 100 bytes of memory
*p = (char *) malloc(100);
*p = `y';
• There is mistake above as Malloc returns
a pointer and also p does not point to any
address.
• The correct code should be:
p = (char *) malloc(100);