[英]Access a 2D array[x][y] as a 1D array[z] in C
I recently started writing chunks of C code as part of my university's programming lessons (so you can freely assume that I am a complete idiot). 最近,作为我大学编程课程的一部分,我开始编写C代码块(因此您可以自由地假设我是一个完整的白痴)。 I'm trying to write a function that writes a 2D array's data to a file, but I'm having difficulties. 我正在尝试编写一个将2D数组的数据写入文件的函数,但是遇到了困难。 I declare the array in main, I have its x and y dimensions saved as #define
s, and I want to call my function()
like so; 我在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);
}
The function itself is saved in a header file and is intended to be included at the very top of my main .c file. 该函数本身保存在头文件中,并打算包含在我的主.c文件的最顶部。 It goes something like this; 它是这样的:
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]);
}
}
}
I'm greeted with an error in the line fprintf(f,"%c",arry[i][j]);
我在行fprintf(f,"%c",arry[i][j]);
遇到了一个错误fprintf(f,"%c",arry[i][j]);
saying that the "subscripted value is neither array nor pointer nor vector", which is false since I know that arry
is an array. 说“下标值既不是数组也不是指针也不是向量”,这是错误的,因为我知道arry
是数组。 Furthermore, if I try to replace said line with something like fprintf(f,"%c",arry[i*j+j]);
此外,如果我尝试将上述行替换为fprintf(f,"%c",arry[i*j+j]);
, the error goes away, but the file output is gibberish (I'm assuming I'm only printing the addresses of the first-dimension elements of arry
). ,错误消失了,但是文件输出却变得乱七八糟(我假设我只打印arry
的第一维元素的地址)。
The question, then; 那么,这个问题; Why can't 2D arrays be accessed like their 1D counterparts, and how do I work around this? 为什么不能像2D数组那样访问2D数组,我该如何解决? I would imagine that an int array[][]={{0,1},{2,3}};
我会想象一个int array[][]={{0,1},{2,3}};
would give an output of 将给出一个输出
array[0] -> 0
array[1] -> 1
array[2] -> 2
array[3] -> 3
, but this is not the case -- it prints 0, 2, and then two memory addresses. ,但事实并非如此-它先输出0、2,然后输出两个内存地址。
I've tried declaring my function to accept arguments as void function(unsigned char arry[*value of x_res*][*value of y_res*],x_res,y_res)
, which works but is not how I would like the function to work. 我试过声明我的函数接受参数作为void function(unsigned char arry[*value of x_res*][*value of y_res*],x_res,y_res)
,该方法有效,但我不希望该函数起作用。
I've looked at some other online examples but it seems few people have had a similar problem. 我看过其他一些在线示例,但似乎很少有人遇到过类似的问题。 I tried some answers from this question but again things do not work. 我尝试过从这个问题中得到一些答案,但是事情还是不起作用。 For example, using void function(unsigned char **arry,x_res,y_res)
works with accessing the array as 2D ( arry[i][j]
), but again, like with the example above, most values (all that aren't in the first column) are trash. 例如,使用void function(unsigned char **arry,x_res,y_res)
可以将数组作为2D( arry[i][j]
)进行访问,但是与上面的示例一样,大多数值(都不是'第一列中的t)是垃圾。
In C99 and later, it is possible to have a VLA 在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]);
}
}
}
The problem is that support of an implementation for VLAs was made optional in C11 (ie a C11 compiler is not required to support them). 问题是在C11中对VLA的实现的支持是可选的(即,不需要C11编译器来支持它们)。 And VLAs are definitely not supported in C90 (the ISO C standard of 1990). 而且C90(1990年的ISO C标准)绝对不支持VLA。
An declared array is contiguous in memory, so can be treated like a flat 1D array. 声明的数组在内存中是连续的,因此可以将其视为平面一维数组。 For example; 例如;
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);
}
The type conversion in the first call of function()
is needed since a 2D array of unsigned char
cannot be implicitly converted to a unsigned char *
. 由于无法将unsigned char
的2D数组隐式转换为unsigned char *
因此需要在function()
的第一次调用中进行类型转换。 However, the address of x
and the address of x[0][0]
have the same value, even though they have different types. 但是, x
的地址和x[0][0]
的地址即使具有不同的类型也具有相同的值。
A gotcha with this technique is that the dimensions passed (first two arguments of function2()
) are not checked at compile time. 使用此技术的一个陷阱是,在编译时不检查传递的尺寸( function2()
前两个参数function2()
。 For example; 例如;
int xx[5][6];
function2(10, 20, (unsigned char *)xx); /* danger, Will Robinson!! */
function2(10, 20, &xx[0][0]); /* danger, danger!! */
will compile but, since the dimensions of xx
are less than the first two arguments tell function2()
to expect, will cause function2()
to have undefined behaviour for both calls. 将会编译,但是由于xx
的尺寸小于前两个参数告诉function2()
的期望,将导致function2()
的两个调用都具有未定义的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.