簡體   English   中英

C 語言的可變修改類型

[英]Variably modified type in C language

誰能解釋什么是可變修改類型?

在我的書中,他們說可變修改類型包含 VLA。 而已; 而已。

如何創建指向可變修改類型的指針?

可變修改類型是 VLA(可變長度數組)。 在具有靈活數組成員的結構中有一個類似的類型,但我不打算進一步討論靈活數組成員。

VLA 的關鍵點是數組的維數直到運行時才知道。 傳統上,在 C89 和標准之前,數組的所有維度除了第一個維度在編譯時必須是已知常量值(並且第一個維度可以指定為int a[]int b[][SIZE]int c[][SIZE1][SIZE2]其中大小是常量)。

void some_function(int n)
{
    int a[n];
    int c = n+1;
    int d = n+2;
    int b[c][d];
    another_function(n, a, c, d, b);
    ...
}

void another_function(int n, int a[n], int c, int d, int b[c][d])
{
    ...
}

ab都是可變長度 arrays。在 C99 之前,你不能這樣寫some_function() arrays 的大小必須在編譯時作為編譯時常量已知。 同樣, another_function()的表示法在 C99 之前是不合法的。

您可以並且仍然可以(出於向后兼容性的原因,如果沒有別的原因)編寫another_function()的適度模擬:

enum { FIXED_SIZE = 32 };

void yet_another_function(int a[], int n, int b[][FIXED_SIZE], int c)
{
    ...
}

這不是一個完美的模擬,因為 FIXED_SIZE 是固定大小,但純 C99 VLA 代碼在那里有一個可變維度。 因此,舊代碼通常會使用足夠大的 FIXED_SIZE 來應對最壞的情況。

another_function()內部,名稱ab基本上是指向可變修改類型的指針。

否則,您可以像對固定大小的數組一樣執行此操作:

int z[FIXED_SIZE];
int (*z_pointer)[FIXED_SIZE] = &z;

int v[n];
int (*v_pointer)[n] = &v;

VLA == 可變長度數組

在 C99 規范中引入了可變長度 Arrays 以允許這樣的事情:

int someArraySize;
int myArray[someArraySize];

可變修改類型是可變長度數組的類型。 因此,可變修改類型包含一個 VLA。 對於您的 b[c][d] 示例,其中 c 和 d 在運行時之前是未知的,b 是可變修改類型,恰好是可變長度多維數組。 b[c][d] 是一個由可變長度數組組成的可變長度數組——哎呀,多啰嗦。

這是我發現的一個很好的來源,它通過示例描述了這些 VLA 和 Variably Modified 類型:

http://gustedt.wordpress.com/2011/01/09/dont-be-afraid-of-variably-modified-types/

VMT 是一種通常用於分配 VMT 大小的堆塊的類型。 指向 VMT 的指針不是 VLA。

#include <stdlib.h>

int main( const int argc, char * const argv[argc])
{
    typedef char * VMT [argc] ;

    VMT * vmt_ptr = malloc(sizeof(VMT));

    * vmt_ptr[0] = argv[0] ;

    free(vmt_ptr);

   return 42;
}

有些人更喜歡稱它們為“堆上的 VLA”。 對於某些人來說,這違背了 VLA 的目的。 對於他們來說,VLA 是堆棧上的一個小(呃)數組。

 { // VMT is a type of VLA
   VMT VLA  ;
       VLA[0] = argv[0] ;
 }

這里沒有內存泄漏。 但后來有些人想知道大驚小怪是怎么回事。

{
    typedef char * VMT [argc] ;

    VMT * vmt_ptr = alloca(sizeof(VMT));

    * vmt_ptr[0] = argv[0] ;
}

他們正在使用 alloca,在此過程中使用 VMT。 有效地創建指向分配在堆棧空間上的塊的 VMT 指針。

所有三個片段都有有效的用例。 我還希望展示什么是 VMT。

強制神馬: https://godbolt.org/z/zGe4K5hez

暫無
暫無

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

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