1

How can I pass an array, declared in main method by reference as a parameter to a function? Also the compiler wants dimentions, but when i give them with variables, the compiler gives errors of invalid integer dimensions of the array, here's the code:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int scanV(int Row, int value, int M, int (&tableValues)[])
{
for (int i = 0; i <= M; ++i)
{
    if (tableValues[Row - 1][i] == 1)
    {
        if (i + value <= M)
        {
            tableValues[Row][i+value] == 1;
        }
        if (i - value >= 0)
        {
            tableValues[Row][i-value] = 1;
        }
    }
}
}

int main()
{
int C, B, M;
cin>>C;
int integers[C];

for (int i = 1; i < C; ++i)
{
    cin>>integers[i];
}
cin>>B;
cin>>M;
integers[0] = B;
int tableValues[C][M + 1];
tableValues[0][B] = 1;
for (int i = 1; i < C; ++i)
{
    scanV(i, integers[i], M, tableValues);
}

return 0;
}
11
  • 1
    Easy with an std::vector: vector<int> &tableValues would be your parameter. Commented Apr 28, 2012 at 1:17
  • 1
    The tableValues parameter is a reference to an array of int, not to an array of arrays of int, so you can't do tableValues[x][y] on it, nor can you pass it an array of arrays of int. There are various other problems in the code—e.g., you can't do "int integers[C]" unless C is a compile-time constant (which it obviously isn't here). Commented Apr 28, 2012 at 1:21
  • OK, but when i use it, it gives error on line 10, which is "if (tableValues[Row - 1][i] == 1)"and the error is "invalid types 'int[int]' for array subscript|" and many more on other lines Commented Apr 28, 2012 at 1:24
  • 1
    If you want an array of arrays, you need two pairs of brackets, not one. But the question is, why do you want a reference to an array of arrays here? If you just take an int**, it will have the exact same effect here. And if you don't know why, you need to learn about array decay more than you need to know the magic invocation to make this actually be a reference to an array of arrays. And if you don't want to learn, you should stick to vectors, which are safer and easier. Commented Apr 28, 2012 at 1:39
  • 1
    @abarnert, right. Just don't give off the impression he should use the bare pointer in production code :D. Also, he probably shouldn't rely on c99-style dynamic-length arrays. I don't believe that's in standard C++ (though it is an extension on most). Plus, then you run the chance of blowing up the stack. Commented Apr 28, 2012 at 2:12

2 Answers 2

3

One simple solution is to use vectors. Consider this simple example:

#include <iostream>
#include <vector>

void f (std::vector<std::vector<int> > &v)
{
    for (int i = 0; i < 3; ++i)
        for (int j = 0; j < 3; ++j)
            v[i][j] = i * 3 + j;
}

int main()
{
    std::vector<std::vector<int> > v (3, std::vector<int> (3, 0));
    f (v);

    for (int i = 0; i < 3; ++i)
        for (int j = 0; j < 3; ++j)
            std::cout << v[i][j] << ' ';
}

In main, a 2D vector of ints (3x3) is created. The constructor shows 3 elements, all initialized with a vector of ints, which are in turn created with 3 elements initialized to 0.

Then, the vector is passed by reference to the function f, which assigns increasing values. When the vector is printed in main, it shows:

0 1 2 3 4 5 6 7 8

As you can see, their use is very similar to normal arrays, but they are actually contained, and provide easy access to a new level of programming using the STL.

In C++11, their use becomes even more familiar. You can assign vectors as follows:

std::vector<int> v0 = {2, 5};
std::vector<std::vector<int> > v1 { {1,2,3} , {4,5,6} , {7,8,9} };

Note that for vectors of multiple dimensions it's a good idea to encapsulate it in a matrix class of some sort with an underlying 1D vector type instead.

Edit:

Here's an example of initializing a 1D and 2D vector to specified elements. As seen above, this is easy in C++11, but if you have an array already, it's still pretty quick.

int a [5] = {1,2,3,4,5}; //normal
std::vector<int> v1 (a, a +5); //create using beginning and ending addresses of a

int b[3][3] = { {1,2,3} , {4,5,6} , {7,8,9} }; //normal
std::vector<std::vector<int> > v2; //empty vector

for (int i = 0; i < 3; ++i) //3 in first dimension
    v2.push_back (std::vector<int> (b [i], b [i] + 3)); //push a vector with the appropriate 3 elements of b onto the back of v2

For going through one element at a time, you can do this:

std::vector<std::vector<int> > v (3, std::vector<int> (3));

for (int i = 0; i < v.size(); ++i) //v.size() == 3
    for (int j = 0; j < v [i].size(); ++j)
        adjustElement (v [i][j]); //replace with what you need
Sign up to request clarification or add additional context in comments.

5 Comments

How should I put my variables in std::vector<std::vector<int>> v (3, std::vector<int> (3, 0)); ?
That last sentence probably needs a rewrite. You certainly don't want to encapsulate multiple dimensions as a 1D vector. What he probably wants here is a 2D matrix class.
@abarnert, thanks for the input. I'll change it. Also, user1113314, I'll add an example.
why not use range-based for? You're relying on c++11 as you don't have a space between your right angle brackets anyway.
@RobertMason, oops, that's just a bad habit of mine when posting code. Indeed I did use ranged-for when making sure what I said worked.
1

std::vectors are the way to go in C++ as variable-length arrays (such as int integers[C];) are forbidden.

I recommend typedefing these to make your code easier to read:

#include <vector>

typedef std::vector<int> row_t;
typedef std::vector<row_t> table_t;

Then you can declare:

void scanV(int Row, int value, int M, table_t& tableValues)

I've made this void since it doesn't return anything.

Your variables in int main() then become:

row_t integers;
table_t tableValues;

Watch out for this line:

            tableValues[Row][i+value] == 1;

You probably meant to assign, rather than to check equivalence!

And please try to pick some more meaningful variable names than B, M, C...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.