簡體   English   中英

如何使用 function 返回 C 中的二維數組?

[英]How to return 2D array in C with a function?

我在 C 中有兩個二維數組。 我們稱它們為 a[row][col] 和 b[row][col]。 我在數組 a 中生成了隨機值。 現在我想編寫一個 function 來計算值,返回二維數組,並且 output 將分配給數組 b(這是一個生命的護航游戲)。

#include <stdio.h>
#include <stdlib.h>

int row, col = 0;

//creates row boundary
int create_row_line()
{
    printf("\n");
    for (int i = 0; i < col; i++)
    {
        printf(" -----");
    }
    printf("\n");
}

//returns the count of alive neighbours
int count_alive_neighbours(int a[row][col], int r, int c)
{
    int i, j, count = 0;
    for (i = r - 1; i <= r + 1; i++)
    {
        for (j = c - 1; j <= c + 1; j++)
        {
            if ((i < 0 || j < 0) || (i >= row || j >= col) || (i == r && j == c))
            {
                continue;
            }
            if (a[i][j] == 1)
            {
                count++;
            }
        }
    }
    return count;
}

int print_state(int x[row][col]){
    create_row_line();
    for (int i = 0; i < row; i++)
    {
        printf(":");
        for (int j = 0; j < col; j++)
        {
            printf("  %d  :", x[i][j]);
        }
        create_row_line();
    }
}

int count_values(int x[row][col]){
    int y[row][col];
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {
            int neighbours_alive = count_alive_neighbours(x, i, j);
            // printf("%d" ,neighbours_alive);
            if ((x[i][j] == 0) && (neighbours_alive == 3))
            {
                y[i][j] = 1;
            }
            else if ((x[i][j] == 1) && (neighbours_alive == 3 || neighbours_alive == 2))
            {
                y[i][j] = 1;
            }
            else
            {
                y[i][j] = 0;
            }
        }
    }
    return y;
}

int main()
{
    //change row and column value to set the canvas size
    printf("Enter number of rows: ");
    scanf("%d", &row);
    printf("Enter number of cols: ");
    scanf("%d", &col);

    int a[row][col], b[row][col];
    int i, j, neighbours_alive;

    // generate matrix
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            a[i][j] = rand() % 2;
        }
    }

    // print initial state
    printf("Initial state:");
    print_state(a);

    char quit;
    do {
        printf("Press enter to print next generation. To quit, enter 'q'.");
        scanf("%c", &quit);
        int** b = count_values(a);
        print_state(b);
        int** a = b;
    } while(quit != 'q');

    return 0;
} 

但是有一個錯誤。 我是一個可憐的 C 程序員,不知道應該怎么做才能獲得理想的效果。 在將 output 從 function 分配給數組 b 之后,我想分配 a=b 並從中進行循環以生成下一代。

所以問題是如何將 C 中的一個二維數組的值分配給另一個數組,以及如何從 function 返回二維數組並將結果分配給現有的二維數組。 感謝您的任何幫助

一種簡單但不高效的方法是您可以定義一個結構來保存二維數組。 然后你可以簡單地從 function 中返回 struct object 並相互分配。

typedef struct {
    int array[row][col];
} S2dArray;

S2dArray count_values(S2dArray x){
   S2dArray y;
   ....
   return y;
}

int main() {
    S2dArray a, b;
    ....
    b = count_values(a);
    print_state(b);
    a = b;
    ....
}

Arrays 是“不可修改的左值”,因此不能是賦值運算符的左參數。 要復制數組,只需使用memcpy() 例如:

int a[row][col], b[row][col];

memcpy(a, b, sizeof(int[row][col]));

返回一個數組是一個棘手的話題,尤其是在您使用可變長度 arrays 時。 它在線程中討論。

您必須以void*或在 2D arrays 的情況下返回指向數組的指針,可以返回指向未定義大小的數組的不完整類型的指針int(*)[]

此外,必須動態分配數組以將其生命周期延長到分配 function 結束之后。 記住在不再使用時釋放 memory。

void* count_values(int x[row][col]){
    int (*y)[col] = malloc(sizeof(int[row][col]));
    ...
    return y;
}

int main() {
  ...
  int (*b)[col] = count_values(a);
  ...
  free(b);
}

您提到的錯誤應該包括一些非致命的運行時錯誤,因為函數被定義為返回一個值,但沒有返回語句......

int create_row_line()
{
    printf("\n");
    for (int i = 0; i < col; i++)
    {
        printf(" -----");
    }
    printf("\n");
    
    return 0;//added
}  

要么使 function 原型void create_row_line() ,要么在底部添加一個return語句。

“如何使用函數返回 C 中的二維數組”

一種方法是使用 VLA 排列將VLA數組作為參數傳遞。 這將允許更改 function 中的值,然后返回更新后的數組。 下面是一個通用的例子來說明。

請注意數組本身之前的數組大小的 position:

void populate2D(int x, int y, int (*arr)[x][y]);

int main(void)
{
    int x=3, y=4;
    int arr[x][y];
    memset(arr, 0, sizeof arr);//initialize array
    populate2D(x, y, &arr);//passing array sizes, and pointer to array
    
    return 0;
}

void populate2D(int x, int y, int (*arr)[x][y])
{
    for(int i=0;i<x;i++)
    {
        for(int j = 0;j<y;j++)
        {
            (*arr)[i][j] = i*j;
        }
    }
}

Arrays 對象不能分配給、從函數返回或作為 function 調用的參數傳遞。 在后一種情況下,function 調用參數被轉換為指向第一個元素的指針,並且聲明為 T 類型數組的 function 參數被“調整”為指向 T 類型的指針(因此void foo(int a[6])是調整為void foo(int *a) ,例如)。

由於main已經有兩個 arrays ab您可以將它們都傳遞給count_values ,更改count_values以接受兩個 arrays ,如下所示:

void count_values(const int x[row][col], int y[row][col])
{
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {
            /* put next generation in y[i][j] here */
        }
    }
}

並從main中調用它,如下所示:

        count_values(a, b);
        print_state(b);
        memcpy(b, a, sizeof(a));

(注意: memcpy#include <string.h>聲明。)

而不是每次都將a復制到b ,您可以擁有一個 3-D 數組int a[2][row][col]; 並為每一代翻轉a[0]a[1]的用法:

    int flip = 0;
    int a[2][row][col];
    int i, j, neighbours_alive;

    // generate matrix
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            a[flip][i][j] = rand() % 2;
        }
    }

    // print initial state
    printf("Initial state:");
    print_state(a[flip]);

    char quit;
    do {
        printf("Press enter to print next generation. To quit, enter 'q'.");
        scanf("%c", &quit);
        // a[flip] contains the current generation,
        // a[1-flip] will contain the next generation.
        b = count_values(a[flip], a[1-flip]);
        // flip the usage of a[0] and a[1]
        flip = 1 - flip;
        // a[1-flip] now contains the previous generation
        // a[flip] now contains the new current generation
        print_state(a[flip]);
    } while(quit != 'q');

一個可能的改進是將行數和列數傳遞為 function arguments 而不是使用全局變量:

void create_row_line(int col)
{
    /* print stuff */
}

int count_alive_neighbours(int row, int col, const int a[row][col], int r, int c)
{
    int count = 0;
    /* count neighbours */
    return count;
}

void print_state(int row, int col, const int x[row][col])
{
    /* print state */
}

void count_values(int row, int col, const int x[row][col], int y[row][col])
{
    /* put next generation in y */
}

對應的 function 調用:

    create_row_line(col);
    int neighbours_alive = count_alive_neighbours(row, col, x, i, j);
    print_state(row, col, a[flip]);
    count_values(row, col, a[flip], a[1-flip]);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM