[英]Access a 2D array[x][y] as a 1D array[z] in C
最近,作为我大学编程课程的一部分,我开始编写C代码块(因此您可以自由地假设我是一个完整的白痴)。 我正在尝试编写一个将2D数组的数据写入文件的函数,但是遇到了困难。 我在main中声明该数组,将其x和y维保存为#define
,我想这样调用我的function()
;
include "function.h"
#define /* x_res, y_res */
int main(){
static unsigned char pic[x_res][y_res];
/* do some operations on pic*/
function(pic,x_res,y_res);
}
该函数本身保存在头文件中,并打算包含在我的主.c文件的最顶部。 它是这样的:
void function(unsigned char arry,int x_res,int y_res){
/* some calculations, declaring file pointer with fopen() */
for(int i=0;i<y_res;i++){
for(int j=0;j<x_res;j++){
fprintf(f,"%c",arry[i][j]);
}
}
}
我在行fprintf(f,"%c",arry[i][j]);
遇到了一个错误fprintf(f,"%c",arry[i][j]);
说“下标值既不是数组也不是指针也不是向量”,这是错误的,因为我知道arry
是数组。 此外,如果我尝试将上述行替换为fprintf(f,"%c",arry[i*j+j]);
,错误消失了,但是文件输出却变得乱七八糟(我假设我只打印arry
的第一维元素的地址)。
那么,这个问题; 为什么不能像2D数组那样访问2D数组,我该如何解决? 我会想象一个int array[][]={{0,1},{2,3}};
将给出一个输出
array[0] -> 0
array[1] -> 1
array[2] -> 2
array[3] -> 3
,但事实并非如此-它先输出0、2,然后输出两个内存地址。
我试过声明我的函数接受参数作为void function(unsigned char arry[*value of x_res*][*value of y_res*],x_res,y_res)
,该方法有效,但我不希望该函数起作用。
我看过其他一些在线示例,但似乎很少有人遇到过类似的问题。 我尝试过从这个问题中得到一些答案,但是事情还是不起作用。 例如,使用void function(unsigned char **arry,x_res,y_res)
可以将数组作为2D( arry[i][j]
)进行访问,但是与上面的示例一样,大多数值(都不是'第一列中的t)是垃圾。
在C99和更高版本中,可能会有一个VLA
void function(int x_res, int y_res, int char[][y_res])
{
for(int i=0;i<x_res;i++)
{
for(int j=0;j<y_res;j++)
{
fprintf(f,"%c",arry[i][j]);
}
}
}
问题是在C11中对VLA的实现的支持是可选的(即,不需要C11编译器来支持它们)。 而且C90(1990年的ISO C标准)绝对不支持VLA。
声明的数组在内存中是连续的,因此可以将其视为平面一维数组。 例如;
void function2(int x_res, int y_res, unsigned char *arr)
{
for(int i=0;i<x_res;i++)
{
for(int j=0;j<y_res;j++)
{
fprintf(f,"%c",arr[i*y_res + j]);
}
}
}
int main()
{
unsigned char x[10][20];
unsigned char y[10*20];
unsigned char *z = malloc(10*20*sizeof(*z));
/* initialise elements x, y, and z */
function2(10,20, (unsigned char *)x);
function2(10,20, &x[0][0]);
function2(10,20, y);
function2(10,20, z);
}
由于无法将unsigned char
的2D数组隐式转换为unsigned char *
因此需要在function()
的第一次调用中进行类型转换。 但是, x
的地址和x[0][0]
的地址即使具有不同的类型也具有相同的值。
使用此技术的一个陷阱是,在编译时不检查传递的尺寸( function2()
前两个参数function2()
。 例如;
int xx[5][6];
function2(10, 20, (unsigned char *)xx); /* danger, Will Robinson!! */
function2(10, 20, &xx[0][0]); /* danger, danger!! */
将会编译,但是由于xx
的尺寸小于前两个参数告诉function2()
的期望,将导致function2()
的两个调用都具有未定义的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.