【问题标题】:How scan ANY 2d array with just one function?如何只用一个函数扫描任何二维数组?
【发布时间】:2015-08-17 23:36:54
【问题描述】:

我一直在寻找如何在任何地方执行此操作,但我找不到任何东西,我想我可能问错了问题,但在这里,我一直在尝试只使用一个函数来阅读或打印您在 main 上定义的任何二维数组,然后将其作为单个参数传递给函数...这是我的代码:

int main() {

    int array2d[2][5] = {{0}};

    load_array(array2d,2);

    return(0);

}

void load_array(int a[][5],int row) {

    int i = 0,j = 0,column;
    column= sizeof(*a) / sizeof(int);

    do {
        j=0;
        while (j < column && scanf("%d",&a[i][j++]) == 1);
    } while (++i < row);

}

我已经设法通过在函数内部计算来避免传递列数,所以问题真的是我能做什么这并不复杂,以避免传递行数,在这个情况下,以便我可以随时使用此功能扫描我在其他项目上创建的二维数组?

感谢您的帮助!!

【问题讨论】:

  • 您是否使用支持 C99 或 C11 的编译器? (基本上,您的编译器是 MSVC 还是 Turbo-C?如果是,那么与能够回答否相比,您遇到了问题。)
  • 我认为是 C11,我该如何检查? :S
  • 一种可能性:显示来自gcc --version 的输出,但如果您首先使用gcc,这不会成为问题。如果您不知道使用 Microsoft Visual Studio 或 Turbo-C,那么您很可能是安全的。如果您没有使用 GCC,请确定您正在使用的平台和编译器,但您可能会没事。
  • 是的,我正在使用带有 gnu gcc 编译器的代码块 :)
  • 当您使用 Code::Blocks 和 GNU GCC 时,应该没问题。您可能需要指定命令行选项 -std=c99-std=gnu99(或指定 11 而不是 99),但您的编译器基本上肯定可以处理 C99(也可能是 C11)。如果你有 GCC 5.1.0 或更高版本,默认编译模式是(终于!)-std=gnu11(默认支持 C11)。

标签: c arrays function parameters size


【解决方案1】:

如果您可以访问支持 C99 或 C11 的编译器,您应该能够使用如下所示的代码来处理 int 的任何二维数组:

#include <stdio.h>

extern void load_array(int n, int m, int a[n][m]);

int main(void)
{
    int array2d_2_5[2][5] = { { 25 } };
    int array2d_9_4[9][4] = { { 94 } };

    load_array(2, 5, array2d_2_5);
    load_array(9, 4, array2d_9_4);

    return(0);
}

void load_array(int n, int m, int a[n][m])
{
    int i = 0, j = 0;
    column= sizeof(*a) / sizeof(int);

    do
    {
        j = 0;
        while (j < m && scanf("%d", &a[i][j++]) == 1)
            ;
    } while (++i < n);
}

我并不完全热衷于do … while 循环,但我认为它可能会起作用。我很想使用load_array() 的替代定义,更像这样:

bool load_array(int n, int m, int a[n][m])
{
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (scanf("%d", &a[i][j++]) != 1)
                return false;
        }
    }
    return true;
}

这将使用 &lt;stdbool.h&gt; 标头和其他 C99 功能,例如在循环控制中声明变量。我会更改声明并适当地调用。至少通过这种方式,您可以判断加载数据时是否出现问题,而不必费力地抱有希望。

问题是只使用一个函数来读取或打印任何二维数组;处理任何类型的任何二维数组都非常困难。

【讨论】:

  • 谢谢,谢谢,谢谢!这是我一直在寻找的替代方案,我不想将数字放在函数的参数上,但这是完美的!我可以使用它后面的变量。
【解决方案2】:

将总长度作为参数传递。请确保array2d连续存储在内存中(如声明:int array2d[2][5];)

#include <stdio.h>

void load_array(int *a,int len) {

    int i = 0,j = 0,column;

    for (i = 0; i < len; i++) {

        if( 1 != scanf("%d", a+i)) {
            break;
        }
    }
}

int main() {

    int array2d[2][5] = {{0}};

    load_array((int*)array2d, 2*5);

    return(0);

}

【讨论】:

  • 用这样的强制转换来打击编译器表明存在问题。如果您按照您的建议进行操作,只需将&amp;array2d[0][0] 传递给函数,因为array2d[0][0]int,所以它的地址是int *。您的建议有效,但它丢失了“形状”信息;您无法区分 10x1、5x2、2x5 或 1x10 阵列。有时这无关紧要;其他时候,它会的。例如,如果输入函数希望在单行输入中为矩阵的一行提供适当数量的条目,则它需要知道形状。
【解决方案3】:

当您将数组作为参数传递给函数时,它会“忘记”它的大小;也就是说,它是从 char array[4][4] 转换为 char *array 或指向 int 的指针,因为数组“只是”一个连续的内存块。

为方便起见,可以指定最后一个维度的大小,否则没有任何意义。

如果你想让一个函数接受一个任意大小的数组,你可以做的是传入两个维度作为参数:

void load_array(int *a, int rows, int columns)
{
    int i, j;
    for (i = 0; i < rows; i++) {
        for (j = 0; j < columns; j++) {
            scanf("%d, a + i * columns + j);
        }
    }
}

【讨论】:

  • 是的,这也是我一直在想的,它会衰减为指向数组的指针,无论如何行数都会丢失,只是我使用了一个可以获取大小的代码任何带有函数的数组,所以你只需要传递数组的名称,然后计算它在函数内的尺寸......
  • 否; int **aint (*a)[4] 不同。您不能将双指针与二维数组一起使用。您必须设置额外的一组指针。
  • 哎呀,你是对的,我错误地多加了一颗星。修复该代码后,该代码似乎可以正常工作。 ideone.com/OU203e
【解决方案4】:

不要将其视为二维数组。它是一个数组数组,即 [[], [], [], []]

所以只需遍历每个“列”,然后以与找到列数相同的方式找到该“列”的“高度”。

(如果数组不是锯齿状的,那么你可以找到一个“列”的“高度”,即 sizeof(a[0])

【讨论】:

  • 但是如果我从参数中删除 5 我会得到一个编译错误,所以我所做的就是将它更改为 (*a) [ ] 无论如何它都会衰减,但是行数无论哪种方式都会丢失,如果我只是将参数保留为 this (*a) [ ],则会出现错误:无效使用未指定边界的数组。
  • 你应该先按照@chux 清理你的代码
猜你喜欢
  • 1970-01-01
  • 2013-11-16
  • 1970-01-01
  • 1970-01-01
  • 2019-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多