簡體   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