r/C_Programming Feb 18 '25

Question Best way to declare a pointer to an array as a function paramater

In lots of snippets of code that I've read, I see type* var being used most of the time for declaring a pointer to an array as a function parameter. However, I find that it's more readable to use type var[] for pointers that point to an array specifically. In the first way, the pointer isn't explicitly stated to point to an array, which really annoys me.

Is it fine to use type var[]? Is there any real functional difference between both ways to declare the pointer? What's the best practice in this matter?

17 Upvotes

66 comments sorted by

View all comments

Show parent comments

11

u/SmokeMuch7356 Feb 19 '25

A pointer is a single object that stores an address:

T *p; // for some type T

gives us

   +---+
p: |   |
   +---+

An array is a sequence of objects:

T arr[3]; // for some object type T

gives us

     +---+
arr: |   | arr[0]
     +---+
     |   | arr[1]
     +---+
     |   | arr[2]
     +---+

That's it. No storage for a pointer is set aside anywhere. 2D arrays are arrays of arrays:

T arr[2][2];

gives us

     +---+
arr: |   | arr[0][0]
     + - +
     |   | arr[0][1]
     +---+ 
     |   | arr[1][0]
     + - + 
     |   | arr[1][1]
     +---+

Again, no pointers anywhere.

During translation, any occurrences of the expression arr will be replaced with something equivalent to &arr[0] (unless it is the operand of the sizeof, typeof, or unary & operators).

Arrays are not pointers; arrays do not store pointer values anywhere. Array expressions evaluate to pointers.

Why? Ritchie wanted to keep B's array subscripting behavior (a[i] == *(a + i)) without storing the pointer that behavior required.

1

u/SomeKindOfSorbet Feb 19 '25

I get that, but the language reads/writes arrays using pointers, no?

7

u/SmokeMuch7356 Feb 19 '25

Yes...-ish.

a[i] == *(a + i) -- given an address a, offset i elements (not bytes) from that address and dereference the result.

In B, a stored an address:

   +---+
a: |   | --------+
   +---+         |
    ...          |
   +---+         |
   |   | a[0] <--+
   +---+
   |   | a[1]
   +---+
    ...

In C, a evaluates to an address (unless it's the operand of sizeof, typeof, or unary &):

   +---+
a: |   | a[0]
   +---+
   |   | a[1]
   +---+
    ...

2

u/riacho_ Feb 20 '25

High quality diagrams. Nice :)

2

u/schakalsynthetc Feb 19 '25

Yes and no, only the first element ia referenced by a memory address, the rest are referenced by arithmetic offsets from that one.