Pointers in C
Computing Lab
https://www.isical.ac.in/~dfslab
Indian Statistical Institute
Computing Lab (ISI) Pointers 1 / 16
Pointers
Memory = consecutively numbered storage cells (bytes)
Variable can occupy one or more contiguous bytes, depending on its
type
Address of a variable = serial number of “first” byte occupied by the
variable
Pointer holds the address of a variable
Pointer / address itself may be (usually is) stored in another variable
x p ...
Computing Lab (ISI) Pointers 2 / 16
Basic operations
& – address / location operator
* – dereferencing operator
char c, *cp; /* neither c nor cp is initialised */
int i, *ip; /* neither i nor ip is initialised */
cp = &c; ip = &i; /* cp, ip are initialised now */
*cp = 0; /* same as c = 0; c is initialised now */
Computing Lab (ISI) Pointers 3 / 16
Pointer arithmetic
Byte addresses 100 104 108 100 + 4n
[0] [1] [2] [3] ... [n-1]
n elements
Pointer values
ip1 = ip2 - n ip2 = ip1 + n
points to n-th element (of the proper type) after what ip
ip1 + n
is pointing to
points to n-th element (of the proper type) before what
ip2 - n
ip is pointing to
ip2 - ip1 number of elements between ip1 and ip2
Computing Lab (ISI) Pointers 4 / 16
Pointers and arrays
An array name is synonymous with the address of its first element.
Conversely, a pointer can be regarded as an array of elements starting
from wherever it is pointing.
But:
int a[10] = {...}, *p;
CORRECT INCORRECT
p = a; /* same as p = &(a[0]); */ &p &a
*p = 5; /* same as a[0] = 5; */
p[2] = 6; /* same as a[2] = 6; */ p = a; a = p;
*(a+3) = 7; /* same as a[3] = 7; */ p++; a++;
Computing Lab (ISI) Pointers 5 / 16
Pointer-array equivalence (contd.)
Using pointer arithmetic Using array elements
p = a + i p = &(a[i])
*p = x a[i] = x
*(p+j) = x p[j] = x or a[i+j] = x
Computing Lab (ISI) Pointers 6 / 16
Review questions
1. What does the following do and why? (see strcpy.c)
1 char a[32] = "Introduction", b[32] = "Programming", *s, *t;
2 s = a; t = b;
3 while (*s++ = *t++);
2. What output is generated by the following code?
for (i=0; i < 10; i++)
printf("abcdefghijklmnop\n" + i);
Computing Lab (ISI) Pointers 7 / 16
Review questions — Solutions
1. String copying
do {
*s = *t;
s++; t++;
} while (*t != '\0');
Computing Lab (ISI) Pointers 8 / 16
Review questions — Solutions
1. String copying
do {
*s = *t;
s++; t++;
} while (*t != '\0');
do {
*s++ = *t++;
} while (*t != '\0');
Computing Lab (ISI) Pointers 8 / 16
Review questions — Solutions
1. String copying
do {
*s = *t;
s++; t++;
} while (*t != '\0');
do {
*s++ = *t++;
} while (*t != '\0');
while ((*s++ = *t++) != '\0');
Computing Lab (ISI) Pointers 8 / 16
Review questions — Solutions
2. Think of the problem this way:
p = "abcdefghijklmnop\n";
printf(p);
Computing Lab (ISI) Pointers 9 / 16
Review questions — Solutions
2. Think of the problem this way:
p = "abcdefghijklmnop\n";
printf(p);
p = "abcdefghijklmnop\n";
printf(p + 2);
Computing Lab (ISI) Pointers 9 / 16
Review questions — Solutions
2. Think of the problem this way:
p = "abcdefghijklmnop\n";
printf(p);
p = "abcdefghijklmnop\n";
printf(p + 2);
p = "abcdefghijklmnop\n";
printf(p + i);
Computing Lab (ISI) Pointers 9 / 16
Topics to be covered
1. How do you allocate space for an array if you do not know (a
reasonable upper bound on) the size when writing your program?
2. What to do if an array is full, and you need to store more elements?
3. Multi-dimensional arrays
4. Difference between int a[M][N] and int **a; ←− LATER
Computing Lab (ISI) Pointers 10 / 16
Variable length arrays
OK
int num_elts;
WRONG
int num_elts; // not initialised
scanf("%d", &num_elts);
int array[num_elts]; // num_elts == ???
int array[num_elts];
Caution: compile and run large-vlas.c
Computing Lab (ISI) Pointers 11 / 16
Allocating memory
Syntax:
#include <stdlib.h>
(type *) malloc(n * sizeof(type))
(type *) calloc(n, sizeof(type))
(type *) realloc(ptr, n * sizeof(type))
malloc, calloc, realloc
free(ptr) return void pointers
Convenient macros: (see common.h)
#define Malloc(n,type) (type *) malloc( (unsigned) ((n)*sizeof(type)))
#define Realloc(loc,n,type) (type *) realloc( (char *)(loc), \
(unsigned) ((n)*sizeof(type)))
Computing Lab (ISI) Pointers 12 / 16
Extending an array using realloc
int *array, capacity = 100, num_elts = 0;
/* Initial allocation */
if (NULL == (array = Malloc(capacity, int))) {
perror("out of memory");
exit(1); // instead of exit(0)
}
...
/* "Grow" the array when required */
if (num_elts == capacity) {
capacity *= 2;
if (NULL == (array = Realloc(array, capacity, int)) {
perror("out of memory");
exit(1);
}
}
Computing Lab (ISI) Pointers 13 / 16
Multi-dimensional arrays
Multi-dimensional array = array of arrays = pointer to pointer
int **a, i;
a = (int **) malloc(rows * sizeof(int *));
for (i = 0; i < rows; i++)
a[i] = (int *) malloc(cols * sizeof(int));
a a[0]
...
a[1]
...
. .
. a[rows-1].
...
Computing Lab (ISI) Pointers 14 / 16
Multi-dimensional arrays: row-major storage
mat
cols
... ... ... ...
temp
rows
..
int ii;
int *temp;
if (NULL == (temp = (int *) malloc(rows*cols*sizeof(int))) ||
NULL == (mat = (int **) malloc(rows * sizeof(int *))))
ERR_MESG("Out of memory");
for (ii = 0; ii < rows; temp += cols, ii++)
mat[ii] = temp;
Computing Lab (ISI) Pointers 15 / 16
Programming problems
1. Consider 2 sequences of letters (a–z), A and B , stored in arrays.
(a) Write a program to find the number of (possibly overlapping)
occurrences of the sequence B in A.
(b) Write a program to find whether the multisets corresponding to A and
B are equal.
2. Write a program that first reads multiple lines of text from the terminal,
and then, depending on the user’s choice, prints either the odd- or the
even-numbered lines, either in their original or in reverse order.
You may assume that
lines are numbered starting with one;
each line is no more than 80 characters long;
the input text will not consist of more than 10 lines.
Redesign your program so that it will run correctly even if the number
of lines in the input text is not known a priori.
Computing Lab (ISI) Pointers 16 / 16