簡體   English   中英

有人可以解釋一下這個聲明中發生了什么嗎?

[英]Can someone explain me what is going on in this statement?

基本上我理解指針。 但是當涉及到也涉及指針的矩陣的動態分配時,我在這個過程中迷失了方向。 我想知道如何翻譯這段代碼才能理解它。

(*a)[i] = (int*)malloc((*m) * sizeof(int));

讀取矩陣的函數如下所示:

void reading(int *n, int *m, int ***a) {
    int i, j;
    printf("n=");
    scanf("%d", &*n);
    printf("m=");
    scanf("%d", &*m);
    (*a) = (int**)malloc((*n) * sizeof(int*));   
    for (i = 0; i < *n; i++)                     
        (*a)[i] = (int*)malloc((*m) * sizeof(int)); 
    for (i = 0; i < *n; i++) {
        for (j = 0; j < *m; j++) {
            printf("a[%d][%d]=", i, j);
            scanf("%d", &(*a)[i][j]);
        }
    }
}

還有聲明中***a是什么意思。 我在大學時被告知,第一個星號代表動態分配,另外兩個代表涉及矩陣的事實。 對於向量動態分配是**v等等......但我無法在腦海中自然地解釋它以了解其中發生的事情。

首先讓我回答你關於這條特定線路的問題:

(*a)[i] = (int*)malloc((*m) * sizeof(int));

這樣做是分配一個正好包含*m整數的數組,並將指向它的指針保存到指向int的指針數組*a ,該數組之前分配為:

(*a) = (int**)malloc((*n) * sizeof(int*));

現在,如果仍然不清楚發生了什么,以更有意義的方式重新編寫代碼會有所幫助。 為了使事情更容易,您可以使用臨時變量來工作,並將值分配給僅在函數末尾作為參數傳遞的指針。 使用更有意義的名稱也有很大幫助。

void read_matrix(int *rows, int *columns, int ***matrix) {
    int i, j, r, c;
    int **mat;

    printf("n = ");
    scanf("%d", &r);

    printf("m = ");
    scanf("%d", &c);

    // Allocate space for a matrix (i.e. an array of r integer pointers).
    mat = malloc(r * sizeof(int*));

    // Allocate space for each row of the matrix (i.e. r arrays of c integers).
    for (i = 0; i < r; i++)
        mat[i] = malloc(c * sizeof(int));

    for (i = 0; i < r; i++) {
        for (j = 0; j < c; j++) {
            printf("a[%d][%d] = ", i, j);
            scanf("%d", &mat[i][j]);
        }
    }

    *rows = r;
    *columns = c;
    *matrix = mat;
}

由於我們現在將值的賦值移到函數末尾的參數中,我們擺脫了所有煩人的指針取消引用運算符 ( * ),代碼看起來更清晰。

您可以看到以前是:

(*a)[i] = (int*)malloc((*m) * sizeof(int));

現在變成了:

mat[i] = malloc(c * sizeof(int));

這更容易理解。 這是為包含c整數的數組(矩陣的一行)分配空間。

以前是:

(*a) = (int**)malloc((*n) * sizeof(int*));

現在變成了:

mat = malloc(r * sizeof(int*));

這是分配一個包含r整數指針的數組(這意味着一個包含r行的矩陣,如果每個指針指向一行)。

你沒有展示這個函數是如何調用的,但大概它看起來像這樣:

int n, m;
int **matrix;
reading(&n, &m, &matrix);

所以在這種情況下, matrix被定義為一個指針到指針。 它可以保存一個int *數組的第一個元素的地址,每個元素都可以保存一個int數組的第一個元素的地址。

&matrix隨后被傳遞給這個函數,你有一個指針到指針到指針,這是什么說法areading是。 在這種情況下, a包含一個指向單個int **的指針,特別是調用函數中的matrix 通過在reading取消引用a ,您實際上是在調用函數中訪問matrix

所以現在進入這一行:

(*a) = (int**)malloc((*n) * sizeof(int*));

這為*n int *數組分配空間並將其分配給*a ,(即調用函數中的matrix 。所以現在你有一個int *數組。現在:

for (i = 0; i < *n; i++)                     
    (*a)[i] = (int*)malloc((*m) * sizeof(int)); 

這會遍歷int *數組的元素,並為每個元素分配一個指向*m int足夠大的內存塊的指針。

因此,您現在有效地擁有了一個二維數組int 但是請注意,這與實際的二維int數組不同,后者將被聲明為int arr[n][m]

首先,你在一個函數中做了太多不同的事情,這讓它有點混亂。 我建議您將獲取矩陣大小的邏輯與創建矩陣的邏輯分開:

void get_size(int *n, int *m) {
    printf("n=");
    scanf("%d", n);
    printf("m=");
    scanf("%d", m);
}

int **create_matrix(int n, int m) {
    int **matrix = malloc(n * sizeof(int*));   
    for (int i = 0; i < n; i++)                     
        matrix[i] = malloc(m * sizeof(int)); 
    return matrix;
}

void fill_matrix(int **matrix, int n, int m) {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            printf("a[%d][%d]=", i, j);
            scanf("%d", [i][j]);
        }
    }
}

從這里可以更容易地看到正在發生的事情, * s 和& s 更少。

你的矩陣被實現為一個數組數組,所以int **matrix = malloc(n * sizeof(int*)); 為外部數組分配內存,而matrix[i] = malloc(m * sizeof(int)); 為每個內部數組分配內存。

int ***a聲明a指向指向int的指針的指針。 調用者需要擁有自己的int **並將其地址傳遞給此函數。 例如,調用者可能定義int **x; 並將&x傳遞給此函數以獲取參數a 我將使用x來指代調用者的int **

(*a) = (int**)malloc((*n) * sizeof(int*)); 將調用者的指針 ( x ) 設置為指向*n指向int指針的空間。 這是為構建*n行矩陣做准備——將為每一行分配內存,我們將有一個指向該內存的指針,因此我們需要n指針。

然后這些行:

for (i = 0; i < *n; i++)                     
    (*a)[i] = (int*)malloc((*m) * sizeof(int));

*n行分配內存。 第二行為m int數組分配內存並將x[i]為指向該內存的第一個元素。 請注意,由於aint ****aint ** ,而(*a)[i]int * 因此, *a指向一個int *元素的數組。

最后,這些行:

for (i = 0; i < *n; i++) {
    for (j = 0; j < *m; j++) {
        printf("a[%d][%d]=", i, j);
        scanf("%d", &(*a)[i][j]);
    }
}

設置*n by *m數組的每個元素:對於每個元素x[i][j] (稱為(*a)[i][j] ,它傳遞元素的地址( &(*a)[i][j])到要從輸入流設置的scanf

暫無
暫無

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

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