【问题标题】:Pass 2d array in function: 2d array received is pointer array在函数中传递二维数组:接收到的二维数组是指针数组
【发布时间】:2015-02-01 19:51:01
【问题描述】:

我有一个巨大的二维数组,我试图将它传递给一个函数。这是数组:

int image[13][13] =
{
    { 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72 },
    { 72, 72, 71, 70, 70, 70, 70, 70, 70, 70, 70, 72, 72 },
    { 72, 107, 116, 145, 137, 130, 154, 118, 165, 111, 173, 116, 72 },
    { 72, 126, 150, 178, 158, 175, 163, 169, 170, 160, 176, 163, 70 },
    { 72, 130, 192, 195, 197, 186, 129, 185, 196, 196, 193, 195, 70 },
    { 72, 126, 187, 166, 85, 75, 106, 185, 191, 191, 189, 188, 69 },
    { 72, 121, 183, 111, 100, 51, 137, 188, 187, 186, 184, 180, 69 },
    { 72, 117, 177, 143, 58, 77, 137, 180, 171, 183, 178, 173, 69 },
    { 72, 111, 172, 108, 101, 110, 115, 67, 49, 120, 175, 165, 68 },
    { 72, 107, 145, 105, 145, 120, 85, 51, 51, 56, 138, 157, 68 },
    { 72, 103, 147, 158, 155, 131, 115, 114, 114, 115, 121, 152, 68 },
    { 72, 79, 146, 161, 163, 165, 168, 167, 164, 162, 158, 114, 70 },
    { 72, 69, 53, 49, 49, 49, 49, 49, 49, 49, 50, 61, 72 }
};

我有这样声明的函数:

int max_2d(int p_valeurs[13][13]);

int max_2d(int p_valeurs[13][13])
{
    int valeur_max;

    for (int i = 0; i < 13; i++)
    {
        int max_local = max(p_valeurs[i], LARGEUR);

        if (valeur_max < max_local)
        {
            valeur_max = max_local;
        }
    }
    return valeur_max;
}

int max(int p_valeurs[]);

int max(int p_valeurs[], int p_taille)
{
    int valeur_max;

    for (int i = 0; i < p_taille; i++)
    {
        if (valeur_max > p_valeurs[i])
        {
            valeur_max = p_valeurs[i];
        }
    }

    return valeur_max;
}

我的问题是当我在max_2d 函数中传递image 2d 数组时,该数组变成了一个int(*)[13]。我不明白发生了什么,出了什么问题。谁能帮帮我?

编辑

请记住,这是学生作品。我需要了解出了什么问题以及如何解决此问题。谢谢!

【问题讨论】:

  • 你是按值传递的吗?哎呀。你真的需要阅读如何有效地使用参考资料。
  • "数组变成了一个 int(*)[13]"——是的,确实如此。这就是数组在 C 和 C++ 中的工作方式——在大多数情况下,它们会衰减为指针,例如。 G。当您将它们传递给函数时。
  • @tadman 你不能只是“将其重新转换为int *”(即使使用int *p = &amp;p_valeurs[0][0];),因为当迭代到达第二行时,这将违反严格的别名规则。
  • @MattMcNabb 我的意思是,如果你有一个 2D 数组,并且你获得了一个指向它的第一个元素的指针(int *p = &amp;arr[0][0]; - 你为什么要做强制转换?),那么你可以仅使用该指针访问第一行的元素。其他任何事情都会调用未定义的行为(如讨论的hereherehere)。
  • @TheParamagneticCroissant 那些正在谈论由于 C 中数组 arr[0] 的越界访问而导致的未定义行为。(与严格的别名无关;而且还不清楚它是否是 UB C++)。但是,如果你写int *p = (int *)&amp;arr;int *p = (int *)arr,那么肯定不会有越界访问,因为p 绑定到所有arr,而不仅仅是第一行。

标签: c++ arrays


【解决方案1】:

我在代码中看到几个逻辑错误:

  1. valeur_max 未在这些函数中初始化:这是不允许的(您无法与未初始化的值进行比较)。

  2. 在第二个函数中,变量被命名为valeur_max,但比较是保持最小值(如果它更大,它会更新valeur_max)。

至于问题的标题,C++ 数组在传递给函数时会隐式转换为指向第一个元素的指针。 如果您真的想按值传递数组,则需要将其包装在一个结构中(请注意,通过副本传递只是为了找到最大值似乎是无稽之谈)。

2D 数组在 C++ 中只是一个数组数组,因此当将其传递给函数时,传递的值变成了指向数组(行)的指针。这就是 int(*)[13] 的意思……指向 13 个整数数组的指针。

对于 C++ 编译器来说,这两个声明

void foo(int x[30]);

void foo(int *x);

完全相同(是的,数字完全被忽略)。

请注意,这种隐式转换(或标准所描述的“衰减”)不会影响元素访问,而只会影响数组未被复制的事实;例如,仅在一个函数中进行 2d 处理的版本可能是:

int max_2d(int p[13][13]) {
    int max_val = INT_MIN;
    for (int i=0; i<13; i++) {
        for (int j=0; j<13; j++) {
            if (max_val < p[i][j]) {
                max_val = p[i][j];
            }
        }
    }
    return max_val;
}

【讨论】:

  • 好的,我想我明白了,但是我怎么能在max函数中访问二维数组中的值呢?
  • @hsim:我不确定我是否理解了这个问题:该代码是正确的(除了我已经指出的错误),因为第一个函数调用第二个函数来获取每行的最大值. p_valeurs 是一个指向max_2d 中的数组的指针,因此p_valeurs[i] 是一个数组,它在传递给max() 时变成一个整数指针。在那个函数中p_valeurs[i] 是一个整数。
  • 是的,如果我必须在一个循环中执行此操作,我会说您的建议正是我将继续进行的方式。但是,我的作业旨在让我使用指针,但我不明白如何才能达到作为最大值指针传递的数组中的值。
【解决方案2】:

这是 C 和 C++ 中的经典问题,数组不能按值传递。然而,它们可以在 C++ 中通过引用传递:

int max_2d(int (&p_valeurs)[13][13]);

p_valuers 具有正确的类型。但请记住,这是一个参考。您所做的任何更改(例如 p_valuers[3][7]++;)都将反映在调用站点上。

(在 C 语言中,我将传递一个指向数组 int max_2d(int (*p_valeurs)[13][13]); 的指针以获得类型安全的解决方案。)

但这对您来说不是问题,因为您没有在 max_2d 函数中修改 p_valuers。实际上,为了清楚起见,您应该明确地将其标记为 const

int max_2d(const int (&p_valeurs)[13][13]);

最后,我说数组不能在 C 或 C++ 中按值传递。当您尝试按值传递数组时,它将改为传递指向数组第一个元素的指针。此外,当编译器在函数的参数列表中看到数组时,它会自动将“顶级”数组转换为指针,int x[13][13]int (*x)[13]。这意味着一个看似接受数组的函数实际上接受了一个指针。但我们可以通过多种方式阻止这种行为,例如使用 C++ 中的引用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-15
    • 1970-01-01
    • 1970-01-01
    • 2021-10-09
    • 1970-01-01
    • 2019-03-28
    • 1970-01-01
    • 2021-12-17
    相关资源
    最近更新 更多