Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在运行时声明全局连续二维数组。维度在编译时C未知_C_Dynamic_Allocation_Contiguous - Fatal编程技术网

在运行时声明全局连续二维数组。维度在编译时C未知

在运行时声明全局连续二维数组。维度在编译时C未知,c,dynamic,allocation,contiguous,C,Dynamic,Allocation,Contiguous,我想在C中声明一个全局2d数组,并在运行时分配连续的内存,因为在编译时次要维度是未知的。 我想用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; }

我想在C中声明一个全局2d数组,并在运行时分配连续的内存,因为在编译时次要维度是未知的。 我想用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);
}
#包括
#包括
//做
//在此声明数组
void fun1(){
数组[3][2]=42.0;
}
int main(int argc,char*argv[])
{
int rows=atol(argv[1]);
int cols=atol(argv[2]);
//做
//在此处为数组分配内存
fun1();
printf(“数组[3][2]=%f\n”,数组[3][2]);
返回(0);
}

以下是一个示例供您参考:

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

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

    f[1][2] = 3;
}
#包括
真空总管(真空)
{
int**f;
int n=2,m=3;
f=(int**)malloc(sizeof(int)*n*m);
f[1][2]=3;
}

不幸的是,在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

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

强制转换
((double(*)[cols])(array_void_u))中的类型可能不明显。它表示指向
cols
double
s数组的指针,这是
double[][cols]
将作为指针衰减的对象。请注意,
double[][cols]
不会衰减为
double**
,这是一种完全不同(且不兼容)的类型

根据该定义,
sizeof global\u array[r]
具有正确的值:
cols*sizeof(double)
。将其与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];
}

现在,您可以使用位于(r,c)的
*全局数组
替换
全局数组[r][c]
。在C中,不可能消除<代码> */COD>,仍然有赋值工作(C++中,函数可以返回一个<代码> double和<代码>,而不是<代码>双*<代码>),但是这可以用宏来解决,

您的问题标题在编译时C<代码< <代码> >但是在帖子中,你说
在运行时分配连续内存
。所以它是哪一个?维度是通过命令行参数传递的,但是数组必须声明为全局数组。然后您需要在运行时分配它;调用程序的命令行参数在编译时显然是未知的。请编辑问题以反映这一点。我做了一些修改。我希望现在更清楚了。你发布的代码没有编译,格式不好,使用了一种不好的做法(铸造
malloc
)的结果。它编译得很好。格式没问题。有些空行可以删除,但缩进是正确的。变量名很弱,因为没有上下文,但这是不可避免的。铸造malloc是解决购买OP时出现的问题的一种方法。可能还有其他解决方案。如果你喜欢的话,可以自己写。而且,即使语法错误被修复了,它也不起作用<如果
f
int**
但它不引用二维数组中的位置,则code>f[1][2]
编译。它希望
f[1]
成为指针数组的索引。@nicomp:OP要求在连续内存中使用2d数组。您提供了指向1D数组的指针的1D数组,但不分配或初始化thr索引数组。因此,这不是问题的答案。尼科普:如果“正确地操纵索引”,你的意思是“把
f[i][j]
写成
f[i*m+j]
,那么这就行了(前提是
f
被声明为
int*
,而不是
int**
)。但是OP需要一个可以编写
f[i][j]的解决方案
而您的示例代码实际上使用了
f[i][j]
。而且,这不是巧合,它会出错。现在,如果您不同意我的分析,您可以通过编辑答案中的代码来轻松证明我错了,这样它就不会出错(理想情况下,在不将
f[1][2]=3;
更改为
f[1*3+2]=3;
).这应该很简单,不是吗?