knoxy5467
knoxy5467

Reputation: 31

what is wrong with this array usage in c++?

#include<iomanip>

using namespace std;

void displaySeats(bool taken[][]){

    for (int i = 0; i < 15; i++) {
        for (int j = 0; j < 30;j++)
            if (taken[i][j])
                cout << '*';
            else
                cout << '#';
        cout << '\n';
    }

}

int main()
{
    bool taken[15][30];
    int rows, clm;
    rows = 15;
    clm = 30;
    displaySeats(taken);
    system("PAUSE");

}

it is giving me errors like

an array may not have elements of this type line 6

'void displaySeats(bool [][])': cannot convert argument 1 from 'bool [15][30]' to 'bool [][]' line 25

'taken': missing subscript line 6

but if i move the code from the function to the main it works perfectly fine.

I can have a array of type bool.

there is subscript.

i've tried passing through a pointer to the array (which arrays are anyway)

i've tried passing through an array of pointers

a 2d array of pointers

a pointer of an array of pointers.

scoured stack exchange and looks at other peoples code and i am doing it almost line for line.

does it not work with bools? because it doesn't work with ints either.

Upvotes: 1

Views: 147

Answers (6)

Swift - Friday Pie
Swift - Friday Pie

Reputation: 14589

If you start to study language rules, not their interpretation, you'll come to realization that neither C nor C++ document doesn't mention an array with multiple dimensions at all, not like FORTRAN or flavors of Basic. It speaks about just an array as a form of object.

Array is an object which has a continuous storage containing multiple objects of same type. Array is an object. Thus we may have an array of arrays. That's what bool taken[15][30] is. It can be read this way

 bool  (taken[15])[30]; //Array of 15 arrays of 30 bools each

While this line is correct

 void foo(bool arg[])   // same as  void foo(bool *arg) for all purposes

And this one gives compiler some information:

void foo(bool arg[30])   // sizeof(arg) would return size of array, 
                         // not size of pointer type

This line is ill-formed.

 void boo(bool arg[][])  // 

It would suggest an unknown type of array elements (how big is the element of array?), which contradicts ideology of strongly-typed language.

Two correct styles can be mixed:

     void foo(bool arg[][30])        // same as void foo(bool (*arg)[30])

Here the parameter of function is a pointer to an array of bools.

Functions in C or C++ never could take an array or return an array. The reason to that is that C (and subsequently, C++) by default can pass parameters and return results by value, which means loading those values into stack. Doing that to array would be ineffective because of stack possible limitations. There were also logical conundrums in syntax, where name of array decays to a pointer. Thus arrays supposed to be passed by their address, by a pointer and can be returned only by pointer as well.

But you can pass structures by value and you can return them as result, even if they contain arrays. C++ classes expands functionality of original aggregate type struct and std::array is an example of template for such aggregate.

Upvotes: 0

Ted Lyngmo
Ted Lyngmo

Reputation: 117258

As mentioned, bool taken[][] isn't valid. Only the left-most (outer) array extent may be left unspecified.

I prefer the longest form to be explicit and to take the argument by reference. Motivation: Taking it as a pointer would lead to a runtime problem if you happen to pass in a nullptr by mistake (unless you check if(taken==nullptr) return; in the function). With a reference, you'd get a compilation error instead so there's no need to check if it's a nullptr.

Also, make the function argument const since you're not making changes to the array in the display function.

constexpr size_t ROWS = 15;
constexpr size_t COLS = 30;

void displaySeats(const bool (&taken)[ROWS][COLS]) {
    using std::cout;

    for (size_t i = 0; i < ROWS; i++) {
        for (size_t j = 0; j < COLS;j++)
            if (taken[i][j])
                cout << '*';
            else
                cout << '#';
        cout << '\n';
    }
}

You can then easily turn this into a function template to accept arbitrary 2D arrays of bool:

template<size_t ROWS, size_t COLS>
void displaySeats(const bool (&taken)[ROWS][COLS]) {
    // same as above
}

Upvotes: 0

pranjal khatri
pranjal khatri

Reputation: 1

try specifying size of array, or use reference see here

#include<iomanip>
#include <iostream>
using namespace std;

// template <typename t>
void displaySeats(bool taken[][30]){

    for (int i = 0; i < 15; i++) {
        for (int j = 0; j < 30;j++)
            if (taken[i][j])
                cout << '*';
            else
                cout << '#';
        cout << '\n';
    }

}

int main()
{
    bool taken[15][30];
    int rows, clm;
    rows = 15;
    clm = 30;
    displaySeats(taken);
    system("PAUSE");

}

Upvotes: 0

john
john

Reputation: 87959

This is a big topic. You need to research how arrays really work in C++. But the short (and surprising) answer is that you cannot have an array as a parameter to a function in C++. This code void func(int a[]) is actually an alternative for the pointer code void func(int* a).

But this simple rule only works for one dimension. With two dimensions only the first dimension is turned into a pointer. So the equivalent for your case would be

void displaySeats(bool (*taken)[30]){

or

void displaySeats(bool taken[][30]){

or

void displaySeats(bool taken[15][30]){

But the important part is that in all cases taken is a pointer not an array.

Because arrays are so useless in C++ we prefer to use std::vector, which doesn't have the same limitations (and has many other advantages besides).

Upvotes: 1

Kostas
Kostas

Reputation: 4176

When expecting an array argument on a function you don't need to know how many elements it has, since you can index it freely. However, you need to know how big each element is, to know how many bytes to skip for each index, when indexing.

In this case your element is a bool[30] with size 30 bytes. You need to signify this on your function signature.

void displaySeats(bool taken[15][30]){ // array 15*30 bool
// OR
void displaySeats(bool taken[][30]){ // array with elements bool[30]
// OR
void displaySeats(bool (*taken)[30]){ // pointer to element(s) bool[30]

See below on how 2d arrays are structured in memory and this will make sense. enter image description here

Upvotes: 2

ABC
ABC

Reputation: 645

The taken array must have some size defined like so taken[15][30].
Also, you have to include <iostream> in order to use cout.

Upvotes: 0

Related Questions