簡體   English   中英

將指針返回到數組的函數

[英]Function returning a Pointer to an Array

我成功地使用了C可變長度數組,我現在有以下內容:

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

int (*foo(size_t row, size_t col))[3];

int main(void){
    size_t row, col;


    printf("Give the ROW: ");
    if ( scanf("%zu",&row) != 1){
        printf("Error, scanf ROW\n");
        exit(1);
    }

    printf("Give the COL: ");
    if ( scanf("%zu",&col) != 1){
        printf("Error, scanf COL\n");
        exit(2);
    }

    int (*arr)[col] = foo(row, col);

    for ( size_t i = 0; i < row; i++){
        for( size_t j = 0; j < col; j++){
            printf("%d ",*(*(arr+i)+j));
        }
    }

    free(arr);
}


int (*foo(size_t row, size_t col))[3]{
    int (*arr)[col] = malloc(row * col * sizeof(int));
    int l=0;

    if (arr == NULL){
        printf("Error, malloc\n");
        exit(3);
    }

    for ( size_t i = 0; i < row; i++){
        for( size_t j = 0; j < col; j++){
            *(*(arr+i)+j) = l;
            l++;
        }
    }

    return arr;
}

輸出:

Give the ROW: 2
Give the COL: 5
0 1 2 3 4 5 6 7 8 9

現在這個:

int (*foo(size_t row, size_t col))[3]{ /* code */ }

意味着,如果我理解正確,將foo聲明為具有兩個參數(size_t row,size_t col)的函數,該參數返回指向int數組3的指針。

我並不完全能夠理解這種函數,當我只在運行時知道大小時,使用可變長度數組對我來說更復雜,但我發現這是一件好事。 我只使用C11標准。

這里有任何方式int (*foo(size_t row, size_t col))[3]我有這個[3],我不清楚它是如何工作的,如何在運行時使它成為可能(當然只有可能),像int (*foo(size_t row, size_t col))[SIZE]

我讀了一些關於C書,但是沒有關於這種情況的確切解釋,谷歌也沒有幫助,所以我有兩個問題:

1)這是可能的int (*foo(size_t row, size_t col))[SIZE] ,其中SIZE必須是參數? 或者我應該以另一種方式聲明這個功能?

2)這是我在這里嘗試過的正確方法,還是有另一種選擇?

我只是試圖返回一個指向一個數組的指針,該數組在運行時知道大小而不是編譯時間。 mallocfree的調用只發生一次,這是一個很好的方法,因為每當調用malloc ,我們的程序會干擾內核分配內存並將頁面標記為可寫。所以這種方法對kernel較小。 它可以用一個與VLA一起工作的malloc編寫

編輯:

@ChronoKitsune說我應該使用/ try [] (未指定大小的數組),在這種情況下函數將變成這樣:

int (*foo(size_t row, size_t col))[]{ /* code */ }

這是我應該使用的嗎?

這里有任何方式int (*foo(size_t row, size_t col))[3]我有這個[3] ,我不清楚它是如何工作的

類型聲明最容易從里到外讀取。 我會開始簡單,並建立你的榜樣。 如果你寫

int foo[3];

要么

int (foo)[3];

你將foo聲明為3個int的數組。 這里的括號提供了一個優先導向分組函數,就像在表達式中一樣,但它們是不必要的,因為在兩種情況下類型的解釋方式都相同。

如果你寫

int (*foo)[3];

你宣稱foo是一個指向 3 int數組的指針 同樣地,你可以讀到這就是說foo指向的東西是一個3個int的數組,隱含foo是一個指針。 在這種情況下,括號是必要的; 如果沒有它們,你會將foo聲明為3 int *的數組。

如果你寫

int (*foo(size_t row, size_t col))[3];

你聲明foo是一個帶有兩個size_t類型參數的函數,它的返回值指向一個3 int的數組。

如何在運行時使其成為可能(當然只有在可能的情況下),例如int (*foo(size_t row, size_t col))[SIZE]

如果SIZE不是編譯時常量,那么你不能這樣做。 C2011認為

如果標識符被聲明為具有可變修改類型,則它應該沒有鏈接,並且具有塊范圍或函數原型范圍。 [...]

(6.7.6.2/2)

換句話說,因為所有函數都具有文件范圍以及內部或外部鏈接,所以函數返回類型不能是VLA,指向VLA的指針或任何此類型(這些是“可變修改”類型)。

通常,在這種情況下,一個返回指向數組的第一個元素的指針,而不是指向整個數組的指針。 指向地址的方式相同,但類型不同:

int *foo(size_t row, size_t col);

返回類型不包含有關指向數組長度的信息,但如果C允許函數返回可變修改類型,那么無論如何,這將依賴於代碼可以知道任何特定上下文中的變量維度的機制。 換句話說,如果你不知道與函數的返回類型無關的預期數組長度,那么你無論如何也無法使用可變修改的返回類型。

如果確實需要的功能都返回一個指針元件的運行時間確定的數量,並且還元素的數量,則可以返回同時含有結構,也可以通過指針參數返回的一個或兩個的值。

更新

如@ChronoKitsune所建議的那樣,也可以聲明你的函數返回一個指向未指定大小的數組的指針。 語法是

int (*bar(size_t row, size_t col))[];

,但你會發現幾乎在所有方面都難以使用返回類型。 例如,聲明可以保存返回值的變量更加棘手和丑陋:

int (*array_ptr)[] = bar(x, y);

並訪問指向數組的元素:

int z = (*array_ptr)[1];

與之形成鮮明對比

int *ptr = foo(x, y);
int w = ptr[2];

暫無
暫無

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

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