首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C 語言函數返回二維陣列的正確姿勢與常見陷阱

     編輯:程式設計綜合問答

問題場景

想透過函數返回一個二維陣列,但編譯總是報錯或執行結果不符預期。許多初學者嘗試直接返回陣列指標,卻忽略了棧記憶體生命週期與指標類型相容性問題。

錯誤代碼分析

float* q[3];  // 全域指標陣列
float* TIME(float E[3][2]) {
    float F[3][2];  // 區域變數,函數結束即銷毀
    // ...
    for (int i = 0; i <= 2; i++) q[i] = F[i];
    return *q;  // 返回懸空指標,未定義行為
}

核心錯誤: 區域陣列 F 存放在棧上,函數返回後記憶體被釋放,指標指向無效區域。

正確解法:靜態儲存期 + 指標返回

#include <stdio.h>

int i, j;
float F[3][2];  // 靜態儲存期,生命週期贯穿整個程式

// 返回指向「含 2 個 float 的陣列」的指標
float (*TIME(float E[3][2]))[2] {
    for (i = 0; i <= 2; i++)
        for (j = 0; j <= 1; j++)
            F[i][j] = 2 * E[i][j];
    return F;
}

int main() {
    float f[3][2], A[3][2];
    float (*q)[2];  // 指向「含 2 個 float 陣列」的指標
    
    // 初始化測試資料
    for (i = 0; i <= 2; i++)
        for (j = 0; j <= 1; j++) {
            f[i][j] = j + i;
            printf("%f\n", f[i][j]);
        }
    
    q = TIME(f);  // 接收返回的指標
    
    // 輸出結果驗證
    for (i = 0; i <= 2; i++)
        for (j = 0; j <= 1; j++) {
            A[i][j] = *(*(q + i) + j);  // 正確解引用
            printf("%f\n", A[i][j]);
        }
    return 0;
}

關鍵點解析

宣告方式含義適用場景
float (*func())[2]返回指向「2 元素 float 陣列」的指標固定列數的二維陣列
float** func()返回二級指標動態分配、列數不固定
void func(float (*out)[2])透過輸出參數填充呼叫端負責記憶體,最安全

進階建議:動態記憶體分配

若陣列大小執行期才能決定,推薦使用 malloc/free:

float** create_matrix(int rows, int cols) {
    float** m = malloc(rows * sizeof(float*));
    for (int i = 0; i < rows; i++)
        m[i] = malloc(cols * sizeof(float));
    return m;
}
// 使用後必須逐行 free,再 free 指標陣列

總結

  • 絕不要返回區域陣列的指標
  • 靜態/全域陣列可安全返回指標,但非執行緒安全
  • 複雜場景優先考慮「呼叫端分配,函數填充」模式
  • C99 可使用 VLA(變長陣列)簡化語法,但仍受棧大小限制
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved