簡體   English   中英

為什么在函數原型中使用“[*]”而不是“[]”?

[英]Why use “[*]” instead of “[]” in function prototype?

以下是為了在函數原型中添加用於聲明數組類型的花哨*星形語法的理由而寫的 - 只是為了在我們進入問題之前澄清:

函數原型可以使用具有可變長度數組類型的參數(第6.5.5.2節),使用特殊語法,如int minimum(int,int [*][*]); 這與其他C原型一致,其中不需要指定參數的名稱。

但我非常有信心我們可以通過簡單地只使用普通的陣列,像這樣未指定大小(在這里重新編寫命名的功能例如同樣的效果minimum在上面的報價給出什么,我相信完全相同的功能(除使用size_t而不是int作為第一個參數,這在案例中並不重要)):

#include <stdio.h>


int minimum(size_t, int (*)[]);

int (main)()
{
    size_t sz;

    scanf("%zu", &sz);

    int vla[sz];

    for(size_t i = 0; i < sz; ++i)
        vla[i] = i;

    minimum(sizeof(vla) / sizeof(*vla), &vla);

    int a[] = { 5, 4, 3, 2, 1, 0 };

    minimum(sizeof(a) / sizeof(*a), &a);
}


int minimum(size_t a, int (*b)[a])
{  
    for(size_t i = 0; i < sizeof(*b) / sizeof(**b); ++i)
        printf("%d ", (*b)[i]);

    return printf("\n");
}

因為我很確定標准中有一些地方說明2個陣列只有在它們的大小相等時才兼容,如果它們是可變的則無關緊要。

我的觀點也得到了證實,即minimum定義不會抱怨“沖突類型”,因為如果它的某些參數具有不兼容的類型(我不認為是這種情況,因為這兩個數組的大小都是在編譯時未指定 - 我引用minimum的第二個參數)。

好的除此之外 - 您能指出一個[*]單個用例,使用普通的未指定大小的數組無法替換嗎?

上面的代碼使用clang和gcc編譯時沒有任何警告。 它還產生預期的輸出。

對於任何不了解C的人(或任何認為他/她知道它的人) - 類型數組的函數參數被隱式轉換為“指向其元素類型的指針”。 所以這:

int minimum(int,int [*][*]);

調整為:

int minimum(int,int (*)[*]);

然后我認為它也可以寫成:

int minimum(int,int (*)[]);

沒有任何后果和與上述2種形式相同的行為。 從而使[*]形式過時。

[]只能用作多維數組最左邊的“維度說明符”,而[*]可以在任何地方使用。

在函數參數聲明中,最左邊(僅!) [...]無論如何都被調整為(*) ,因此可以在該位置使用(*) ,但代價是清晰度。

可以省略左下方[...]的維度,留下空括號。 這將使數組元素類型不完整。 這不是什么大問題,因為可以在接近使用點(例如在函數定義中)完成它。

下一個[...]需要一個不能省略的數字或* 這些聲明

int foo (int [*][*][*]);
int foo (int (*)[*][*]);
int foo (int (*)[ ][*]);

都是兼容的,但沒有一個兼容它們沒有將第三個維度指定為*或數字。 如果第三維確實是變量,則*是唯一的選擇。

因此, [*]至少對於尺寸3及以上是必要的。

好的除此之外 - 您能指出一個[*]的單個用例,使用普通的未指定大小的數組無法替換嗎?

當您傳遞三維VLA數組時會出現這種情況:

int minimum(size_t, int [*][*][*]);

這可以寫成:

int minimum(size_t, int (*)[*][*]);

甚至使用未指定大小的數組:

int minimum(size_t, int (*)[][*]);

但是你沒有可能省略或繞過最后的指示,因此它必須在[*]這樣的聲明中保留。

暫無
暫無

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

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