[Solved] What motivates the concept of “pointers” in C, when the concept of numbers only would suffice?


TL;DR

It is completely possible to have a language without pointers. Actually, it is possible to write a C program where you store addresses in regular integer variables and then cast them to pointers. Calling pointers, and also the general concept of types, syntactic sugar is to stretch it a bit, but it’s not completely untrue either.

Long story

The reason is that it is very valuable to have different types. That allows the compiler to do type checking and automatic conversions. It also allows the compiler to warn you when you are doing something that probably is not what you intend. For instance, look at this C code:

int x;
int *p;
// Init x and p somehow
int y = p + x; // Legal, but you probably meant y = *p + x

An early language B, which predates C had only one type called “word”. It was used for integers, pointers, floats or whatever. It was up to the program to interpret the bit pattern.

Consider this C code:

int i=5;
float f=3.5;
float x=f+i;

In the last statement, i will be promoted to float before a float addition is performed. This would not be possible without type information. Now x will have the value 8.5 (rounding errors ignored) but now consider this pseudocode that illustrates the problem you would have in a language like B:

word i, f, x;
i = 5;
f = 3.5;
x = i + f;

What do you expect the variable x to contain? And what type should that bit pattern represent?

When it comes to pointers, this is very valuable. Consider that you have two pointers, char *cptr and int *iptr. Now let’s have a look at some pointer arithmetic. When adding an integer to a pointer we will offset the pointer with respect to the size of the type. So *(cptr + 1) will return the value that is one byte after cptr, while *(iptr + 1) will (typically) return the value that is on the address 4 or 8 bytes after iptr.

Here is an example that is very close to your question. Consider this C code:

float *p = malloc(10 * sizeof (*p));

for(int i=0; i<10; i++)
    p[i]= i * 1.2;

for(int i=0; i<10; i++)
    printf("%f\n", p[i]);

If we did not have pointer types, then we would have to write something like this instead:

unsigned p = malloc(10 * sizeof(float));

for(int i=0; i<10; i++)
    *(p + i*sizeof(float)) = i * 1.2;

for(int i=0; i<10; i++)
    printf("%f\n", (float) *(p + i*sizeof(float)));

If you REALLY want to, you can actually do stuff like this in C. Here is an example that compiles and runs, although with warnings and probably have undefined behavior, but it produced the expected result on my computer:

unsigned p = malloc(10 * sizeof(float));

for(int i=0; i<10; i++)
    *((float*)p + i*sizeof(float)) = i * 1.2;

for(int i=0; i<10; i++)
    printf("%f\n", *((float*)p + i*sizeof(float)));

5

solved What motivates the concept of “pointers” in C, when the concept of numbers only would suffice?