简体   繁体   English

c++ 中的这种阵列使用有什么问题?

[英]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数组可能没有这种类型的元素第 6 行

'void displaySeats(bool [][])': cannot convert argument 1 from 'bool [15][30]' to 'bool [][]' line 25 'void displaySeats(bool [][])':无法将参数 1 从 'bool [15][30]' 转换为 'bool [][]' 第 25 行

'taken': missing subscript line 6 “采取”:缺少下标第 6 行

but if i move the code from the function to the main it works perfectly fine.但是如果我将代码从 function 移到 main 中,它工作得很好。

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)我试过通过一个指向数组的指针(无论如何都是 arrays)

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.因为它也不适用于整数。

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.当期望 function 上的数组参数时,您不需要知道它有多少元素,因为您可以自由索引它。 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.在这种情况下,您的元素是一个大小为 30 字节的bool[30] You need to signify this on your function signature.您需要在 function 签名上表明这一点。

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.请参阅下文,了解如何在 memory 中构造 2d arrays,这将是有意义的。 在此处输入图像描述

This is a big topic.这是一个很大的话题。 You need to research how arrays really work in C++.您需要研究 arrays 在 C++ 中的实际工作原理。 But the short (and surprising) answer is that you cannot have an array as a parameter to a function in C++.但简短(且令人惊讶)的答案是,您不能将数组作为 C++ 中的 function 的参数。 This code void func(int a[]) is actually an alternative for the pointer code void func(int* a) .此代码void func(int a[])实际上是指针代码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.但重要的部分是在所有情况下taken的是指针而不是数组。

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).因为 arrays 在 C++ 中如此无用,我们更喜欢使用std::vector ,它没有相同的限制(并且还有许多其他优点)。

The taken array must have some size defined like so taken[15][30] . taken的数组必须具有一些定义的大小,如taken[15][30]
Also, you have to include <iostream> in order to use cout .此外,您必须include <iostream>才能使用cout

As mentioned, bool taken[][] isn't valid.如前所述, bool taken[][]无效。 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).动机:如果您碰巧错误地传入了一个nullptr ,将其作为指针会导致运行时问题(除非您在函数中检查if(taken==nullptr) return; )。 With a reference, you'd get a compilation error instead so there's no need to check if it's a nullptr .通过引用,您会得到一个编译错误,因此无需检查它是否为nullptr

Also, make the function argument const since you're not making changes to the array in the display function.此外,将 function 参数设为const ,因为您没有更改显示 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 :然后,您可以轻松地将其转换为 function 模板以接受bool的任意 2D arrays :

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

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");

}

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.如果您开始研究语言规则,而不是它们的解释,您将意识到 C 和 C++ 文档根本没有提到具有多维的数组,不像 Z36B29ACFC7B63EF39D78DD854034EBC5 的风格。 It speaks about just an array as a form of object.它仅将数组作为 object 的一种形式。

Array is an object which has a continuous storage containing multiple objects of same type.数组是一个 object,它具有包含多个相同类型对象的连续存储。 Array is an object.阵列是 object。 Thus we may have an array of arrays.因此,我们可能有一个 arrays 数组。 That's what bool taken[15][30] is.这就是bool taken[15][30]的含义。 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:两个正确的styles可以混用:

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

Here the parameter of function is a pointer to an array of bool s.这里 function 的参数是一个指向bool数组的指针。

Functions in C or C++ never could take an array or return an array. C 或 C++ 中的函数永远不能接受数组或返回数组。 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.原因是 C(以及随后的 C++)默认情况下可以传递参数并按值返回结果,这意味着将这些值加载到堆栈中。 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.因此 arrays 应该通过它们的地址,通过指针传递,并且也只能通过指针返回。

But you can pass structures by value and you can return them as result, even if they contain arrays.但是您可以按值传递结构并将它们作为结果返回,即使它们包含 arrays。 C++ classes expands functionality of original aggregate type struct and std::array is an example of template for such aggregate. C++ 类扩展了原始聚合类型struct的功能, std::array是此类聚合的模板示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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