Page 93 - C-Language
P. 93
8:3.1415926536 <=> 3.1415929204 out of tolerance 0.0000000100 (rel diff 8.4914E-08)
9:3.1415926536 <=> 3.1415929204 out of tolerance 0.0000000010 (rel diff 8.4914E-08)
Doing extra scaling in pointer arithmetic
In pointer arithmetic, the integer to be added or subtracted to pointer is interpreted not as change
of address but as number of elements to move.
#include <stdio.h>
int main(void) {
int array[] = {1, 2, 3, 4, 5};
int *ptr = &array[0];
int *ptr2 = ptr + sizeof(int) * 2; /* wrong */
printf("%d %d\n", *ptr, *ptr2);
return 0;
}
This code does extra scaling in calculating pointer assigned to ptr2. If sizeof(int) is 4, which is
typical in modern 32-bit environments, the expression stands for "8 elements after array[0]", which
is out-of-range, and it invokes undefined behavior.
To have ptr2 point at what is 2 elements after array[0], you should simply add 2.
#include <stdio.h>
int main(void) {
int array[] = {1, 2, 3, 4, 5};
int *ptr = &array[0];
int *ptr2 = ptr + 2;
printf("%d %d\n", *ptr, *ptr2); /* "1 3" will be printed */
return 0;
}
Explicit pointer arithmetic using additive operators may be confusing, so using array subscripting
may be better.
#include <stdio.h>
int main(void) {
int array[] = {1, 2, 3, 4, 5};
int *ptr = &array[0];
int *ptr2 = &ptr[2];
printf("%d %d\n", *ptr, *ptr2); /* "1 3" will be printed */
return 0;
}
E1[E2] is identical to (*((E1)+(E2))) (N1570 6.5.2.1, paragraph 2), and &(E1[E2]) is equivalent to
((E1)+(E2)) (N1570 6.5.3.2, footnote 102).
Alternatively, if pointer arithmetic is preferred, casting the pointer to address a different data type
can allow byte addressing. Be careful though: endianness can become an issue, and casting to
types other than 'pointer to character' leads to strict aliasing problems.
https://riptutorial.com/ 69

