1

Can someone please explain to me how/why these functions are the same?

void doubleArray(int* values, int length)

void doubleArray(int values[], int length)

I didn't have to change anything for my code to still work completely the same, but I'm not sure of the logic. I expected to have to change what was written in the function at the very least. Full code is below if needed;

  #include <iostream>

    using std::cout;
    using std::endl;

void doubleArray(int* values, int length);

int main() {

    int length = 10;
    int values[length];

    for (int i = 0; i < length; i++){
        values[i] = i;
    }

    doubleArray(values, length);

    for (int i = 0; i < length; i++) {
      cout << values[i] << endl;
   }

}

void doubleArray(int* values, int length) {
    for(int i = 0; i < length; i++){
        values[i] = values[i] * 2;
    }
}
3
  • C-arrays decay to a pointer to the first element when you use them as function parameter. Don't use C-arrays. C++ has std::array. int values[length]; is a variable-length array (because length is not constexpr) and not supported by C++ standard. Many compilers won't compile it. You should set constexpr int length = 10; Commented Mar 23, 2020 at 8:45
  • read about the relation between arrays and pointers stackoverflow.com/questions/3959705/arrays-are-pointers Commented Mar 23, 2020 at 8:45
  • Unrelated: Since your arrays have unknown length at compile time, you should use a std::vector<int> instead. With that you don't need to pass the length around. Commented Mar 23, 2020 at 8:51

3 Answers 3

3

From https://en.cppreference.com/w/cpp/language/function#Parameter_list:

The type of each function parameter in the parameter list is determined according to the following rules:

[..]

2) If the type is "array of T" or "array of unknown bound of T", it is replaced by the type "pointer to T"

[..]

Because of these rules, the following function declarations declare exactly the same function:

int f(char[]);
int f(char* s);
int f(char* const);
int f(char* volatile s);
Sign up to request clarification or add additional context in comments.

Comments

1

Why are they the same? Because that's the rules of C++ (which it inherited from C).

The designers of C felt it was a bad idea to be able to pass an array to a function. They felt that it was preferable to pass a pointer to the array's first element instead. Questionable (in my view).

But they also decided they didn't want to do away with the array syntax in a function parameter declaration. So they decided that, when used as a function parameter, the array form T param[] was just a different way of writing the pointer form, T* param. It's even the same if you specify a size for the array (which is ignored), T param[10] is also a pointer. Even more questionable (in my view).

In C++ you are able to avoid all this by using std::vector or std::array. In C you are not so lucky.

Comments

-1

Suppose we declare an array of int:

int values[10];

A block of memory for 10 ints is allocated on the stack, and the variable values contains the address of the beginning of that block of memory, or to put it another way, the address of the zeroth element of the array, which is the same thing.

Thus

&values[0] == values

is always true.

Similarly these two statements are addressing the same element

cout << values[5];
cout << *(values + 5);

Thus if we have a function parameter (or any other variable), it can be declared as of type int* or int[] and both will accept values, because both declarations are merely alternative ways of declaring the same thing - a pointer. .

This can cause confusion, since both of these calls to foo() are valid:

void foo (int[] vals);

int values[10];
foo (values); // Passing an array

int x = 0;
int* px = &x:
foo (px);     // Passing a single object by address

So as a matter of style, if a function expects an array, it should take the array for (int[]) and a length. If it expects a single object it should take a pointer (int*).

5 Comments

values is a variable of type int[].
The values here: void doubleArray(int values[], int length)
Yes. That was the question. I was explaining why they are the same thing.
still wrong: the variable values does not contain an address. It's like saying that a variable of type double contains an integer.
values does contain an address. Otherwise how could int x = *values; be valid? You can only deference a pointer and a pointer contains an address.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.