0

This is the working program to pass an array in a function, but I am not able to understand that in the print function only the base address of the array is passed but still I am able to access the array with subscript a[i]. I know the correct method will be *(a+i) but why does it work with the subscript too?

#include <iostream>
#include <conio.h>
void print(int *a);
using namespace std;
int main()
{
    int arr[3]={1,2,3};
    print(arr);
    getch();
    return 0;
}
void print(int *a)
{
    for(int i=0;i<3;i++)
    {
        cout<<a[i];//how we are able to access array with subscipt a[i]
    }
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Aman Jagga
  • 301
  • 5
  • 15

3 Answers3

3

Since you are passing a pointer (pointing to a specific memory address) you can treat it as usual even inside the function. Pointers and arrays are very closely related and the use is just fine.

a[0] and *a are the same thing, so are a[1] and *(a+1) etc.

"A pointer is equivalent to the address of the first element that it points to" - from http://www.cplusplus.com/doc/tutorial/pointers/

Victor Sand
  • 2,270
  • 1
  • 14
  • 32
  • 1
    This is because [arrays decay to pointers](http://stackoverflow.com/questions/1461432/what-is-array-decaying) – Captain Obvlious Apr 20 '13 at 20:40
  • 3
    And you can even write `i[a]` because it expands to `*(i + a)` which adds a pointer and an integer; you should never do this, though, except in an [IOCCC](http://ioccc.org/) contest entry. – Jonathan Leffler Apr 20 '13 at 20:44
0

The array can be passed like that, but the other way is to put name of the array followed by empty []:

#include <iostream>
#include <conio.h>
void print(int *a);
using namespace std;
int main()
{
    int arr[3]={1,2,3};
    print(arr);
    getch();
    return 0;
}
void print(int a[])
{
    for(int i=0;i<3;i++)
    {
        cout<<a[i];//how we are able to access array with subscipt a[i]
    }
}

both methods pass the address of the first number in array, so both methods work.

Svajs
  • 29
  • 1
  • 9
  • 1
    You're right that that is valid, but to understand how it works you now need an extra step to realise that `int a[]`, in the special case of a function parameter declaration, means `int *a`. This doesn't explain anything, it just complicates matters. –  Apr 20 '13 at 21:33
0

//how we are able to access array with subscipt a[i]

a[i] is the same thing as *(a + i).


As it is now, your print will only work for arrays of the exact size 3, so:

  • If the array happens to have more than 3 elements, some elements will not be printed.
  • If it happens to have less than 3, you'll access whatever is in memory behind the array, which is undefined behavior (translation: very bad!).

The size of the array gets "forgotten" when you pass the array to a function, so either explicitly pass the size to make the function reusable for arrays of all sizes (reusability is the point of having functions after all!)...

void print(int const* a, size_t a_size) {
    for (size_t i = 0; i < a_size; ++i) // size_t is the appropriate type here, not int.
        std::cout << a[i] << std::endl; // Use std::endl to be able to discern where teh current number ends and the next starts!
}

// ...

int arr[3] = {1, 2, 3};
const size_t arr_size = sizeof(arr) / sizeof(arr[0]);
print(arr, arr_size);

...or do it in the C++ way and use std::vector...

void print(const std::vector<int>& a) {
    for (const auto& s : a) // The new C++11 "for each" syntax.
        std::cout << s << std::endl;
}

// ...

std::vector<int> a;
a.push_back(1);
a.push_back(2);
a.push_back(3);
print(a);

...or even make it generic...

template <typename T>
void print(const std::vector<T>& a) {
    for (const auto& s : a)
        std::cout << s << std::endl;
}
Branko Dimitrijevic
  • 50,809
  • 10
  • 93
  • 167