如何让用户在C

时间:2015-09-16 01:20:54

标签: c arrays

就像标题所说的那样。反正是否允许用户在C中指定二维数组的两个参数?该数组将被调用一个函数并在函数内进行更改。

函数至少需要第二个参数来表示数组的大小,我不想为数组的大小指定任意大数。

我应该指出我是一个非常新的C程序员,我对C一般都知之甚少。如果你让我接触到一个全新的概念,我不会被冒犯,我会问很多关于它的问题!

3 个答案:

答案 0 :(得分:1)

是的,因为C99你可以写:

void func(int rows, int cols, int array[rows][cols])
{
// stuff...
}

并称之为:

int main()
{
    int c = rand() % 10 + 1;
    int arr1[6][c];  func(6, c, arr1);
    int arr2[9][3]; func(9, 3, arr2);

    size_t large = 100000000;
    int (*arr3)[c] = malloc(sizeof(int[large][c]));
    func(large, c, arr3);
    free(arr3);
}

在C11中,出于政治原因,此功能被标记为“可选”,但除了MSVC之外的所有编译器都支持它。

答案 1 :(得分:1)

这表明VGA(可变长度阵列)正在工作。它基于SO 32565694的代码,该代码询问结构中的VLA。此代码避免使用结构。

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct
{
    int nr, nc;
    void *data;     // Actually double a[nr][nc]
} Matrix;

static double variant1(int nr, int nc, int r, int c)
{
    assert(nr != 0);
    return (r * nc) + c + 1;
}

static double variant2(int nr, int nc, int r, int c)
{
    return ((nr - r) * nc) + (nc - c) + 1;
}

typedef double (*Initializer)(int nr, int nc, int r, int c);

static void mat_init(int nr, int nc, double m[nr][nc], Initializer init)
{
    assert(m != 0 && nr > 0 && nc > 0);
    printf("Set: [%dx%d]\n", nr, nc);
    for (int i = 0; i < nr; i++)
    {
        printf("[%d]:", i);
        for (int j = 0; j < nc; j++)
        {
            double v = init(nr, nc, i, j);
            m[i][j] = v;
            printf(" %6.1f", v);
        }
        putchar('\n');
    }
}

static void mat_dump(const char *tag, int nr, int nc, double m[nr][nc])
{
    assert(m != 0 && nr > 0 && nc > 0);
    printf("Matrix %s: %dx%d\n", tag, nr, nc);
    for (int i = 0; i < nr; i++)
    {
        printf("[%d]:", i);
        for (int j = 0; j < nc; j++)
            printf(" %6.1f", m[i][j]);
        putchar('\n');
    }
}

static void mat_multiply(int r1, int c1, double m1[r1][c1],
                         int r2, int c2, double m2[r2][c2],
                         int r3, int c3, double m3[r3][c3])
{
    assert(r1 > 0 && c1 > 0 && r2 > 0 && c2 > 0 && r3 > 0 && c3 > 0);
    printf("m1[%d][%d] x m2[%d][%d] = m3[%d][%d]\n", r1, c1, r2, c2, r3, c3);
    assert(r1 == r3 && c2 == c3 && c1 == r2);

    for (int i = 0; i < r1; i++)
    {
        for (int j = 0; j < c2; j++)
        {
            double sum = 0.0;
            for (int k = 0; k < c1; k++)
                sum += m1[i][k] * m2[k][j];
            m3[i][j] = sum;
        }
    }
}

int main(void)
{
    int r1 = 3;
    int c1 = 5;
    int r2 = c1;
    int c2 = 4;
    int r3 = r1;
    int c3 = c2;

    double m1[r1][c1];
    double m2[r2][c2];
    double m3[r3][c3];

    printf("m1:\n");
    mat_init(r1, c1, m1, variant1);
    printf("m2:\n");
    mat_init(r2, c2, m2, variant2);

    mat_dump("m1", r1, c1, m1);
    mat_dump("m2", r2, c2, m2);
    mat_multiply(r1, c1, m1, r2, c2, m2, r3, c3, m3);
    mat_dump("m3", r3, c3, m3);

    return 0;
}

示例输出:

m1:
Set: [3x5]
[0]:    1.0    2.0    3.0    4.0    5.0
[1]:    6.0    7.0    8.0    9.0   10.0
[2]:   11.0   12.0   13.0   14.0   15.0
m2:
Set: [5x4]
[0]:   25.0   24.0   23.0   22.0
[1]:   21.0   20.0   19.0   18.0
[2]:   17.0   16.0   15.0   14.0
[3]:   13.0   12.0   11.0   10.0
[4]:    9.0    8.0    7.0    6.0
Matrix m1: 3x5
[0]:    1.0    2.0    3.0    4.0    5.0
[1]:    6.0    7.0    8.0    9.0   10.0
[2]:   11.0   12.0   13.0   14.0   15.0
Matrix m2: 5x4
[0]:   25.0   24.0   23.0   22.0
[1]:   21.0   20.0   19.0   18.0
[2]:   17.0   16.0   15.0   14.0
[3]:   13.0   12.0   11.0   10.0
[4]:    9.0    8.0    7.0    6.0
m1[3][5] x m2[5][4] = m3[3][4]
Matrix m3: 3x4
[0]:  215.0  200.0  185.0  170.0
[1]:  640.0  600.0  560.0  520.0
[2]: 1065.0 1000.0  935.0  870.0

使用命令行参数或用户输入来设置r1c1(或r2)和c2的值是完全可行的(但值对于此代码,r2c1r3 c3r1c1c2telnetlocalhost约束})。初始化代码可以正常工作,乘法也是如此。

答案 2 :(得分:0)

声明数组时,编译时应知道大小。为了做你所要求的,你应该使用动态分配,比如malloc。

您可以从用户读取一个int,然后为多维数组调用具有该大小的malloc