0

我想在 C 中声明一个全局二维数组,并在运行时分配连续内存,因为在编译时次要维度是未知的。我想用 2 索引符号 A[i][j] 取消对数组的引用。如果数组不是全局 c99 表示法“double A[m][n]”会很方便,但在我的情况下不适用。什么是正确的策略?

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

//TO DO
//DECLARE array here

void fun1() {
    array[3][2] = 42.0;
}

int main(int argc,char *argv[])
{
    int rows = atol(argv[1]);
    int cols = atol(argv[2]);

    //TO DO
    //Allocate memory for array here
    fun1();
    printf("Array[3][2]=%f\n",array[3][2]);

    return(0);
}
4

2 回答 2

1

不幸的是,在 C 中不太可能实现您的要求。

宏有一个稍微难看的解决方案。由于宏指的是全局数组本身和包含其第二维的全局变量,因此您必须小心不要在使用宏的任何函数中隐藏全局变量。在这里,我使用了以下划线结尾的笨拙名称来避免名称重用。

除此之外,它应该工作:

void*  global_array_void_;
size_t global_array_minor_dim_;

#define global_array ((double(*)[global_array_minor_dim_])global_array_void_)    

在使用宏之前,您需要分配它并初始化全局变量:

void init_global_array(int rows, int cols) {
    global_array_minor_dim_ = cols
    global_array_void_ = malloc(rows * cols * sizeof global_array[0][0]);
}

从那时起,您可以global_array像使用常规数组一样使用 use:

void f(int r, int c, double v) {
    global_array[r][c] = v;
}

以大肠杆菌为生

演员表中的类型((double (*)[cols])(array_void_))可能并不明显。它表示一个指向 s 数组的指针cols double,它double[][cols]会衰减为指针。请注意,double[][cols]不会衰减到double**,这是一种完全不同(且不兼容)的类型。

使用该定义,sizeof global_array[r]具有正确的值:cols * sizeof(double). 与之对比sizeof argv[i]


一种更传统的方法是使用函数来计算精确索引。这仍然取决于可用的次要维度:

double* global_array;
size_t global_array_minor_dim_;

void init_global_array(int rows, int cols) {
    global_array_minor_dim_ = cols
    global_array_void_ = malloc(rows * cols * sizeof global_array[0][0]);
}

double* global_array_at(int r, int c) {
    return &global_array[r * global_array_minor_dim_ + c];
}

现在您可以*global_array_at(r, c)用作global_array[r][c]. 在 C 中,不可能消除*并且仍然有赋值工作(在 C++ 中,函数可能返回 adouble&而不是 a double*),但这可以再次通过宏来解决。

于 2015-12-13T01:55:35.317 回答
-2

这是一个示例供您遵循:

#include <stdlib.h>
void main(void)
{
    int **f;
    int n = 2, m = 3;

    f = (int **)malloc(sizeof(int)*n *m);

    f[1][2] = 3;
}
于 2015-12-12T12:34:34.190 回答