简体   繁体   中英

passing pointers (the name of array) into function in C/C++

Lets say we create an array like:

int a[4]={1,2,3,4};

Now a is the name of this array and also the pointer points to the first element a[0] . So when I want to call the elements in the array, I can use a[ i ] or *(a+i) .

Now I have a function:

void print_array(int* array, int arraySize){
    for(int i=0; i<arraySize; i++){
       cout<<*(array+i)<<endl;
       cout<<array[i]<<endl;
    }
}

When I pass a[4]={1,2,3,4} into this function using print_array(a,4) , for the first line of cout , I fully understand because I use *(a+i) method to access data and a is the pointer I passed.

What I can't understand is: since I pass a pointer a into function, why can I use a in the format of a[i] like the second line of cout ? Isn't a a pointer? If a is a pointer why does a[i] work?

This has confused me for a whole day. Any help will be much appreciated!

Because in effect, while the subscript operator is defined on arrays, what happens is that they decay into pointers for the arithmetic to occur.

Meaning if a is an array, semantically what happens is:

int b = a[i]; => int *__tmp = a; int b = *(__tmp + i);

However, once operator overloading comes into play, then it is no longer true that a[i] == *(a + i) . The right hand side may not even be defined.

This quote from the C++ Standard will make the point clear (5.2.1 Subscripting)

1 A postfix expression followed by an expression in square brackets is a postfix expression. One of the expressions shall have the type “array of T” or “pointer to T” and the other shall have unscoped enumeration or integral type. The result is of type “T.” The type “T” shall be a completely-defined object type.64 The expression E1[E2] is identical (by definition) to *((E1)+(E2)) [Note: see 5.3 and 5.7 for details of * and + and 8.3.4 for details of arrays. —end note], except that in the case of an array operand, the result is an lvalue if that operand is an lvalue and an xvalue otherwise.

a is an array, not a pointer. They are not the same things. However, the name a can be implicitly converted to a pointer (with the value &a[0] ).

For example;

  int main()
  {
       int a[] = {1,2,3,4};
       int *p = a;              //  p now has the value &a[0]

Now, after this partial code snippet, assuming i is an integral value, rules of the language amount to;

  • a[i] is equivalent to *(a + i) which is equivalent to *(&a[0] + i)
  • p[i] is equivalent to *(p + i)

Now, since p is equal to &a[0] this means that a[i] , *(a + i) , p[i] , and *(p + i) are all equivalent.

When calling print_arrat(a, 4) where a is the name of an array, then a is ALWAYS converted to a pointer. This means print_arrat() is always passed a pointer. And this means *(array + i) inside print_arrat() is the same as a[i] in the caller.

What I can't understand is: since I pass a pointer "a" into function, why can I use "a" in the format of a[i] like the second line of "cout"?

Because subscript operator a[i] is defined for arrays and it is equivalent to *(a+i) by definition.

In the line with cout , you use array[i] however, where array is a pointer. This is also allowed, because the subscript operator is also defined for pointers.

Isn't "a" a pointer?

No. a is an array. array is a pointer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM