C中的数组数组,其中数组的长度不同

时间:2017-09-09 11:11:35

标签: c arrays

据我所知,您可以轻松制作具有固定长度的矩阵:

double m[][2];

但是,我希望有一个数据结构是一个数组,其中我存储了具有不同长度的double类型的数组。我该怎么做?

一个例子是:

arr1 = {1,2,3,4};
arr2 = {1,2};

3 个答案:

答案 0 :(得分:5)

Jagged arrays通常表示为指向C:

中指针的指针数组
double arr0[] = {4, 1, 7};
double arr1[] = {1, 2, 3, 4};
double arr2[] = {1, 2};
double *m[] = {arr0, arr1, arr2};

不幸的是,没有标准的语法用于与外部指针数组“在线”定义内部数组。

请注意,现在无法找到每个内部数组的长度,因此您需要添加某种“标记”,或分别存储长度:

#define SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
...
size_t len[] = { SIZE(arr0), SIZE(arr1), SIZE(arr2) };

答案 1 :(得分:1)

可以使用指针数组来完成,即

#include <stdio.h>

int main(void) {
    double* x[2];
    double a[2] = {1.0, 2.0};
    double b[4] = {1.0, 2.0, 3.0, 4.0};
    x[0] = a;
    x[1] = b;

    printf("%f %f\n", x[0][1], x[1][3]);
    return 0;
}

要跟踪数组的大小(也就是数组中元素的数量),您可以考虑使用结构数组。像:

#include <stdio.h>

struct z
{
    unsigned int size;
    double* p;
};

int main(void) {
    int i, j;
    struct z x[2];
    double a[2] = {1.0, 2.0};
    double b[4] = {1.0, 2.0, 3.0, 4.0};
    x[0].p = a;
    x[0].size = sizeof a / sizeof(double);
    x[1].p = b;
    x[1].size = sizeof b / sizeof(double);

    for (i=0; i<2; ++i)
    {
        for (j=0; j<x[i].size; ++j)
        {
            printf("x[%d][%d] %f\n", i, j, x[i].p[j]);
        }
    }
    return 0;
}

输出:

x[0][0] 1.000000
x[0][1] 2.000000
x[1][0] 1.000000
x[1][1] 2.000000
x[1][2] 3.000000
x[1][3] 4.000000

答案 2 :(得分:1)

您可以通过创建指针数组来完成此操作。在这种情况下,锯齿状数组的元素不一定是连续存储的,并且必须以某种方式保持各行的长度,以便可以使用锯齿状数组。

如果数组类型允许,另一个选项是使用2d数组,将每行的大小存储在每行的第一个元素中。这可能会使用比指针数组更多的内存,但元素将连续存储在内存中。

如果存在无法在数组中出现的值,则可以使用sentinel值而不是显式存储行大小。即使数组的类型不允许存储大小值(例如char[][]),也可以使用此方法。

#include <stdio.h>
#include <string.h>

int main(void)
{
    /* Jagged array using pointers */
    int array_1[] = { 1, 2, 3 };
    int array_2[] = { 5, 6 };
    int array_3[] = { 7, 8, 9, 10 };

    int *jagged_array_1[] = { array_1, array_2, array_3 };
    size_t array_sizes[] = { sizeof array_1 / sizeof *array_1,
                             sizeof array_2 / sizeof *array_2,
                             sizeof array_3 / sizeof *array_3 };

    for (size_t i = 0; i < 3; i++) {
        for (size_t j = 0; j < array_sizes[i]; j++) {
            printf("%4d", jagged_array_1[i][j]);
        }
       putchar('\n');
    }
    putchar('\n');

    /* Using the first element to store sizes */
    int jagged_array_2[3][5] = { { 0 } };

    jagged_array_2[0][0] = sizeof array_1 / sizeof *array_1;
    memcpy(&jagged_array_2[0][1], array_1, sizeof array_1);

    jagged_array_2[1][0] = sizeof array_2 / sizeof *array_2;
    memcpy(&jagged_array_2[1][1], array_2, sizeof array_2);

    jagged_array_2[2][0] = sizeof array_3 / sizeof *array_3;
    memcpy(&jagged_array_2[2][1], array_3, sizeof array_3);

    for (int m = 0; m < 3; m++) {
        for (int n = 0; n < jagged_array_2[m][0]; n++) {
            printf("%4d", jagged_array_2[m][n+1]);
        }
        putchar('\n');
    }
    putchar('\n');

    /* Using a sentinel element */
    int jagged_array_3[3][5] = { { 0 } };

    memcpy(jagged_array_3[0], array_1, sizeof array_1);
    jagged_array_3[0][sizeof array_1 / sizeof *array_1] = -1;

    memcpy(jagged_array_3[1], array_2, sizeof array_2);
    jagged_array_3[1][sizeof array_2 / sizeof *array_2] = -1;

    memcpy(jagged_array_3[2], array_3, sizeof array_3);
    jagged_array_3[2][sizeof array_3 / sizeof *array_3] = -1;

    for (size_t i = 0; i < 3; i++) {
        for (size_t j = 0; jagged_array_3[i][j] != -1; j++) {
            printf("%4d", jagged_array_3[i][j]);
        }
        putchar('\n');
    }
    putchar('\n');

    return 0;
}