Pointer Arithmetic

Pointer arithmetic in the mikroC PRO for PIC32 is limited to:

The internal arithmetic performed on pointers depends on the memory specifier in force and the presence of any overriding pointer modifiers. When performing arithmetic with pointers, it is assumed that the pointer points to an array of objects.

Arrays and Pointers

Arrays and pointers are not completely independent types in the mikroC PRO for PIC32. When the name of an array comes up in expression evaluation (except with operators & and sizeof ), it is implicitly converted to the pointer pointing to array’s first element. Due to this fact, arrays are not modifiable lvalues.

Brackets [ ] indicate array subscripts. The expression

id[exp]

is defined as

*((id) + (exp))

where either:

The following statements are true:

&a[i]  =  a + i
 a[i]  =  *(a + i)

According to these guidelines, it can be written:

pa = &a[4];       // pa points to a[4]
x = *(pa + 3);    // x = a[7]

/* .. but: */
y = *pa + 3;      // y = a[4] + 3

Also the care should be taken when using operator precedence:

*pa++;           // Equal to *(pa++), increments the pointer
(*pa)++;         // Increments the pointed object!

The following examples are also valid, but better avoid this syntax as it can make the code really illegible:

(a + 1)[i] = 3;
// same as: *((a + 1) + i) = 3, i.e. a[i + 1] = 3

(i + 2)[a] = 0;
// same as: *((i + 2) + a) = 0, i.e. a[i + 2] = 0

Assignment and Comparison

The simple assignment operator (=) can be used to assign value of one pointer to another if they are of the same type. If they are of different types, you must use a typecast operator. Explicit type conversion is not necessary if one of the pointers is generic (of the void type).

Assigning the integer constant 0 to a pointer assigns a null pointer value to it.

Two pointers pointing to the same array may be compared by using relational operators ==, !=, <, <=, >, and >=. Results of these operations are the same as if they were used on subscript values of array elements in question:

int *pa = &a[4], *pb = &a[2];

if (pa == pb) {... /* won't be executed as 4 is not equal to 2 */ }
if (pa > pb)  {... /* will be executed as 4 is greater than 2 */ }

You can also compare pointers to zero value – testing in that way if the pointer actually points to anything. All pointers can be successfully tested for equality or inequality to null:

if (pa == 0) { ... }
if (pb != 0) { ... }
  Note : Comparing pointers pointing to different objects/arrays can be performed at programmer’s own responsibility — a precise overview of data’s physical storage is required.

Pointer Addition

You can use operators +, ++, and += to add an integral value to a pointer. The result of addition is defined only if the pointer points to an element of an array and if the result is a pointer pointing to the same array (or one element beyond it).

If a pointer is declared to point to type, adding an integral value n to the pointer increments the pointer value by n * sizeof(type) as long as the pointer remains within the legal range (first element to one beyond the last element). If type has a size of 10 bytes, then adding 5 to a pointer to type advances the pointer 50 bytes in memory. In case of the void type, the size of a step is one byte.

For example:

int a[10];         /* array a containing 10 elements of type int */
int *pa = &a[0];   /* pa is pointer to int, pointing to a[0] */
*(pa + 3) = 6;     /* pa+3 is a pointer pointing to a[3], so a[3] now equals 6 */
pa++;              /* pa now points to the next element of array a: a[1] */

There is no such element as “one past the last element”, of course, but the pointer is allowed to assume such value. C “guarantees” that the result of addition is defined even when pointing to one element past array. If P points to the last array element, P + 1 is legal, but P + 2 is undefined.

This allows you to write loops which access the array elements in a sequence by means of incrementing pointer — in the last iteration you will have the pointer pointing to one element past the array, which is legal. However, applying an indirection operator (*) to a “pointer to one past the last element” leads to undefined behavior.

For example:

void f (some_type a[], int n) {
    /* function f handles elements of array a; */
    /* array a has n elements of type some_type */

  int i;
  some_type *p=&a[0];

  for ( i = 0; i < n; i++ ) {
          /* .. here we do something with *p .. */
    p++;  /* .. and with the last iteration p exceeds
                the last element of array a */
  }
  /* at this point, *p is undefined! */
}

Pointer Subtraction

Similar to addition, you can use operators -, -- , and -= to subtract an integral value from a pointer.

Also, you may subtract two pointers. The difference will be equal to the distance between two pointed addresses, in bytes.

For example:

int a[10];
int *pi1 = &a[0];
int *pi2 = &a[4];
i = pi2 - pi1;      /* i equals 8 */
pi2 -= (i >> 1);    /* pi2 = pi2 - 4: pi2 now points to [0] */
Copyright (c) 2002-2012 mikroElektronika. All rights reserved.
What do you think about this topic ? Send us feedback!
Want more examples and libraries? 
Find them on LibStock - A place for the code