簡體   English   中英

在函數中解引用數組指針

[英]Dereferencing array pointer in a function

您如何引用一個指向數組的指針以獲取存儲在其中的值? 例如:

void testFunction(int **test){
  printf("%d", *test[1]);
}

int main()
{   int test[10];
    test[1] = 5;
    testFunction(&test);
    return 0;
}

我得到一個錯誤。 有人可以解釋嗎?

您如何引用一個指向數組的指針以獲取存儲在其中的值?

對於每個指針,您都可以使用*運算符。 (哦,請注意運算符的優先級!)

void foo(int (*arr)[5])
{
    printf("%d\n", (*arr)[0]);
}

int main()
{
    int arr[5] = { 0, 1, 2, 3, 4 };
    foo(&arr);
    return 0;
}

您的代碼將生成有關傳遞給函數的不兼容類型的診斷信息。 例如,海灣合作委員會抱怨:

prog.c: In function 'main':
prog.c:9: warning: passing argument 1 of 'testFunction' from incompatible pointer type

您應注意編譯器發出的所有診斷信息,並確保您理解它們,並采取適當措施加以解決。 對於這個特定的對象,如果您打算傳遞指向數組的指針,則需要編寫函數來接受這樣的事情。 然后,當取消引用指針時,便有了一個數組。 因此,您就像訪問它一樣。

void testFunction(int (*test)[10]){
  printf("%d", (*test)[1]);
}

[]優先級比* ,因此函數參數參數和訪問printf()的值都需要括號。 當推導指向int[10]的指針時,結果值是main定義的數組test的第一個元素的地址。 然后, []操作訪問數組的第二個元素,您將獲得所需的值。


如果您注意到以下斷言始終為真,則您可能會更加確信,對數組的指針使用int **test是錯誤的:

int test[10];
assert(&test == (void *)test);

如編譯器警告所指示,指向int的指針的指針與指向int[10]的指針不同。 所指向的類型確定了取消引用所導致的類型。

所以:

int test[10] = { [1] = 5 };
testFunction(&test);

這會將test的地址傳遞給testFunction 變量的地址與其在內存中的位置相對應。 這與數組沒有太大區別,但是數組變量在內存中的位置是其第一個元素的地址。 因此,上面的&test返回的地址&test單獨的test返回的地址相同。

當您將此指針值當作指向testFunction指向int的指針的指針時,這將帶來災難性的后果。 首先,請注意您忽略了適當的運算符優先級,因此第一個取消引用是:

test[1]

由於您將test參數聲明為指向int的指針,因此這會將test的地址增加sizeof(int *)並將結果視為int * 然后,您再次取消引用:

*test[1]

現在,它使用test[1]的值,並再次對其進行取消引用,以嘗試獲取int 但是, test[1]返回的地址與main定義的數組test沒有關系,並且您正在訪問完全沒有意義的內存位置。

即使您使用指針指向int參數類型的指針來關注優先級,也會產生類似的問題。

(*test)[1]

現在,將指向int[10]的指針視為首先推導指向int指針。 這導致main test數組的第一個sizeof(int **)字節被視為指向int的指針。 在這一點上,這已經是一個荒謬的值,但是現在,數組取消引用使此值增加sizeof(int)個字節,並對該值進行引用以嘗試獲取int

另一個用戶給出了一個通常如何完成此操作的示例,但是如果您堅持要傳遞int **,則由於運算符優先級,其語法如下:

void testFunction(int **test){
  printf("%d", (*test)[1]);
}

int main()
{   int test[10];
    test[1] = 5;

    int *testptr= &test[0];  // or int *testptr= test;
    testFunction(&testptr);  // this passes an int **
    return 0;
}

但是在c語言中,數組的名稱是指向數組元素的指針,因此更常用int * ptrtest和ptrtest [1]。

暫無
暫無

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

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