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