将任意(可变)大小的二维数组传递给函数

问题描述 投票:0回答:1

我想将二维数组传递给函数,但是,我想用任意大小来做到这一点。

首先请看下面的代码:

#define MAX_ROWS 8
#define MAX_SIZE 32

static void foo(char array[][MAX_SIZE], size_t max_rows, size_t max_size) {
    for (size_t i = 0; i < max_rows; i++) {
        printf("%s\n", array[i]);
    }
}

int main(void) {
    char array[MAX_ROWS][MAX_SIZE];
    
    for (size_t i = 0; i < MAX_ROWS; i++) {
        snprintf(array[i], MAX_SIZE, "Row: %d", i);
    }
    
    foo(array, MAX_ROWS, MAX_SIZE);
    
    return 0;
}

A. 此代码按预期工作。但有一句话我不喜欢:

static void foo(char array[][MAX_SIZE], size_t max_rows, size_t max_size)

我不喜欢它,因为我不仅需要指定最大大小两次,还需要对第二维的最大大小进行硬编码,以使其在编译时可用。

B. 另一种方法是制作可变长度数组(VLA)。为此,我们需要更改参数的顺序,以便

size_t max_size
出现在数组之前:

static void foo(size_t max_rows, size_t max_size, char array[][max_size])
foo(MAX_ROWS, MAX_SIZE, array);

一方面我喜欢这个解决方案,但另一方面我不喜欢它。它是 C99 标准的一部分,但不受 MSVC 支持。因此,我根本无法使用它。

我也不确定是否会因为安全原因而阻止这种使用,即使大小 - 由于使用宏常量 - 仍然事实上是硬编码的,因此实际上不是可变的。

C. 据我了解,

char array[MAX_ROWS][MAX_SIZE]
内部只不过是一个大小为
max_rows * max_size * sizeof(char)
的缓冲区。所以我正在考虑以下解决方案,但这会导致
Segmentation Fault

static void foo(void *array0, size_t max_rows, size_t max_size) {
    size_t total_size = max_rows * max_size * sizeof(char);
    
    char *array = malloc(total_size);
    memcpy(array, array0, total_size);

    for (size_t i = 0; i < max_rows; i++) {
        printf("%s\n", array[i]);
    }

    free(array);
}
arrays c pointers
1个回答
0
投票

您不需要保留空间来访问数组的每个元素,只需对字符使用指针算术,这就是像 qsort 这样的函数在不知道传递数组的具体类型时的做法:

#include <stdio.h>

static void foo(void *array0, size_t max_rows, size_t max_size)
{
    char *array = array0;
    char *ptr = array;

    for (size_t i = 0; i < max_rows; i++) {
        printf("%s\n", ptr);
        ptr += max_size;
    }
}

int main(void)
{
    enum {MAX_ROWS = 3, MAX_SIZE = 4};

    char array[MAX_ROWS][MAX_SIZE] = {"abc", "cde", "fgh"};
    foo(array, MAX_ROWS, MAX_SIZE);
    return 0;
}

输出:

abc
cde
fgh
© www.soinside.com 2019 - 2024. All rights reserved.