繁体   English   中英

在C中将2D数组[x] [y]作为1D数组[z]访问

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM