C語言 二維數組作為函數參數的4種方式


前言

  多維數組中,二維數組是最常用的一種。在C語言編程中,二維數組的定義、取值以及賦值都比較容易,與一維數組類似。然而,在將二維數組作為函數參數傳遞時,參數結構較復雜,難以理解。本文章是實用型文章,注重代碼使用,不會講述過多理論。如果想要學習理論知識(非常推薦,可以對代碼的理解更透徹),可以查閱下方參考文獻列出書籍的第10章內容。話不多說,下面將給出一個C程序,以展示二維數組作為函數參數的4種方式。注:下面的代碼已在VS Code(使用Mingw64)和VS 2015下編譯運行過。

正文

  下面程序的功能是對一個int型二維數組的所有元素進行求和,並分別把求和結果打印在屏幕上。根據二維數組傳入函數的方式,定義了4個版本的求和函數。

#include <stdio.h>

#define ROW 2   //二維數組的行數
#define COL 2   //二維數組的列數

//4個版本的求和函數
//方式一:數組形式
int TwoDimArraySum1(int twoDimAr[][COL], int row, int col);

//方式二:指針形式,prArray是一個指向包含COL個int的數組的指針
int TwoDimArraySum2(int (*prArray)[COL], int row, int col);

//方式三:指針形式,pr是一個指向int的指針
int TwoDimArraySum3(int *pr, int row, int col);

//方式四:變長數組(C99開始支持)
int TwoDimArraySum4(int row, int col, int twoDimAr[row][col]);

int main(void)
{
    int twoDimArray[ROW][COL] = {{-2, 5}, {4, 9}};
    int result;

    //方式一
    result = TwoDimArraySum1(twoDimArray, ROW, COL);
    printf("Sum1函數結果:%d\n", result);

    //方式二
    result = TwoDimArraySum2(twoDimArray, ROW, COL);
    printf("Sum2函數結果:%d\n", result);

    //方式三
    result = TwoDimArraySum3(twoDimArray[0], ROW, COL);
    printf("Sum3函數結果:%d\n", result);

    //方式四
    result = TwoDimArraySum4(ROW, COL, twoDimArray);
    printf("Sum4函數結果:%d\n", result);

    return 0;
}

int TwoDimArraySum1(int twoDimAr[][COL], int row, int col)
{
    int i, j;
    int result = 0;

    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            //下面兩種尋址方式都行
            result += twoDimAr[i][j];
            // result += *(*(twoDimAr + i) + j);
        }
    }
    return result;
}

int TwoDimArraySum2(int (*prArray)[COL], int row, int col)
{
    int i, j;
    int result = 0;

    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            //下面兩種尋址方式都行
            result += prArray[i][j];
            // result += *(*(prArray + i) + j);
        }
    }
    return result;
}

int TwoDimArraySum3(int *pr, int row, int col)
{
    int i, j;
    int result = 0;

    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            //下面兩種尋址方式都行
            result += pr[i*row + j];
            // result += *(Pr + i*row + j);
        }
    }
    return result;
}

int TwoDimArraySum4(int row, int col, int twoDimAr[row][col])
{
   int i, j;
   int result = 0;

   for (int i = 0; i < row; i++)
   {
       for (int j = 0; j < col; j++)
       {
           //下面兩種尋址方式都行
           result += twoDimAr[i][j];
           // result += *(*(prArray + i) + j);
       }
   }
   return result;
}

  正如程序注釋所言,方式4(變長數組)是C99開始支持的,不是所有編譯器都支持。例如,VS 2015就不支持該語法。因此,在VS 2015環境下運行時,方式4被注釋了。下面給出VS Code(基於Mingw64)以及VS 2015環境下的運行結果。

左圖為VS Code;右圖為VS 2015

優缺點評價

  這里先給出結論,最推薦使用方式3。下面是簡要的分析。

  • 方式1和方式2實質上是相同的。它們兼容性很好。但是,它們定義必須事先給出第二維的長度,即不是對任意大小的二維數組都適用。
  • 方式3兼容性同樣很好,對任意大小的二維數組都適用。但是,它是最難理解的。理解它需要對二維數組元素的結構、二維數組元素的儲存以及二維數組與指針的關系有比較深刻的理解。
  • 方式4是最容易理解的了。但是,它的兼容性最差。

  此外還需要強調的是,對於該程序的求和函數,更安全、更易讀的寫法是將參數列表中接受二維數組數據的參數加上const修飾本程序沒加的原因是為了更好的突出其功能。const修飾的對象不同,產生的效果也不同。如果參數列表中接受二維數組數據的參數加上const修飾,它將無法修改二維數組的數據;如果只有待傳入的二維數組是用const修飾,參數列表中的參數不是const修飾的,那么上述方式都不被允許。因此,請根據實際情況,自行決定const的修飾對象和修飾位置。

關於更高維數組

  對於更高維的數組,上面四種方式仍然適用。除了方式3外,另外三種方式都很容易擴展成更高維的。對於方式3,雖然最推薦它,但是它隨着維數的增多,它變得更復雜更難理解。而且基於方式3,還可以延伸出其他方式。這里以三維數組舉例,方式3還可以延伸出這樣一種方式,該方式中接受三維數組的形參是一個指向一維數組的指針。對於這種由方式3延伸的方式,我是不推薦的,它比方式3更復雜,使用它還不如使用方式3。

參考文獻

Stephen Prata寫的《C Primer Plus》第五版


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM