以下是红龙书的节选。它处理过程激活记录中可变长度数据项的处理。
Pascal
在语言中几乎是独一无二的,它要求过程本地的数组具有可以在编译时确定的长度。更常见的是,本地数组的大小可能取决于传递给过程的参数值。在这种情况下,在调用过程之前,无法确定过程本地的所有数据的大小。图 7.15 建议了处理可变长度数据的常用策略,其中过程
p
具有三个局部数组。这些数组的存储不是 ; 的激活记录的一部分p
。只有一个指向每个数组开头的指针出现在激活记录中。这些指针的相对地址在编译时是已知的,因此目标代码可以通过指针访问数组元素。图 7.15 还显示了一个
q
由 调用的过程p
。的激活记录q
在 的数组之后开始p
,而可变长度的数组在此之后q
开始。
在上面摘录的第一部分中,文本讨论了Pascal
编程语言的特性,然后他们讨论了相同的可能实现。现在我不熟悉Pascal
并想了解这种情况的处理方式C
。
我知道可以C
使用malloc
及其姊妹函数动态创建数组,这会导致在堆上分配内存,并将指向第一个字节的指针返回给我们。根本不是问题。
如果我们创建数组,C
其中数组的大小是一个常量,如下所示:
int function() {
int a[100];
}
然后将该数组放置在local data
如下所示的激活记录部分中:
在上面的例子中,数组的大小a
在编译时就知道了。没有问题。
现在的情况:“更多时候,本地数组的大小可能取决于传递给过程的参数值。在这种情况下,直到调用过程才能确定过程本地的所有数据的大小。 "
情况1:
现在让我们考虑下面的代码:
int function(int n){
int a[n];
}
int main() {
function(10);
}
现在在上面的情况下,参数的大小n
可以function
在编译时知道,因此数组的大小a
虽然变量可以在编译时知道。有了这个逻辑C
,上面的数组是不是按照龙书a
里的方式分配?fig 7.15
案例二:
int function(int n){
int a[n];
}
int main() {
int x;
scanf("%d",&x);
function(x);
}
现在在上面的情况下,参数的大小n
只能function
在运行时知道(?)还是仍然是上面的情况,即在编译时知道?现在在这段代码中,数组a
分配在哪里。堆还是栈?
我去了这里,这里和这里,但没有找到我正在寻找的解释......
这里我说的是C99