Arrays of Variable Length
变长数组, ISO C99 标准中正式支持,在 C89 模式下作为 GCC 的扩展特性。变长数组即数组长度为变量,除此之外与普通数组在声明语法上没有区别。变长数组在声明处分配空间 ( 在栈上分配空间而不是在堆上,这一点与函数 alloca/_alloca 相同,实际上用 gdb 调试发现,变长数组的空间分配就是通过调用 alloca 完成的 ) ,在作用域结束时自动收回空间 ( 包括因为使用 goto 或者其它手段中途结束 ) 。变长数组与使用 alloca/_alloca 分配空间的数组的区别在于: alloca 分配的空间在调用 alloca 的函数返回时收回,而变长数组的空间在变长数组名字作用域结束时收回 ( 通常是包含它的大括号结束 ) 。如果在一个函数中既使用 alloca 又使用变长数组,那么变长数组空间收回会导致最近一次的 alloca 空间被收回。
也可以把变长数组用作函数的参数。下面是一段变长数组的演示代码:
int n, t;
scanf ( "%d" , &t);
while( t--) {
scanf ( "%d" , &n);
({
int arr[n], i, sum = 0;
for( i = 0; i < n; i++) {
scanf ( "%d" , arr+i);
sum += arr[i];
}
printf ( "sum is: %d/n" , sum);
});
}
调试时遇到了一段不理解的代码,暂时附在这里:
0x00401628 <varlen_array+26>: mov 0x8(%ebp),%eax
0x0040162b <varlen_array+29>: dec %eax
0x0040162c <varlen_array+30>: inc %eax
0x0040162d <varlen_array+31>: add $0xf,%eax
0x00401630 <varlen_array+34>: shr $0x4,%eax
0x00401633 <varlen_array+37>: shl $0x4,%eax
先减 1 再加 1 ,然后加上 15 ,右移 4 位再左移 4 位,不知道为什么要这么做。而且在调试中发现,代码中调用 alloca ,编译器直接用 sub 指令移动 esp 指针,如果使用变长数组,反而去调用 alloca 了。
Macros with a Variable Number of Arguments.
宏可以 像函数一样接受可变参数列表, C99 正式支持这样的语法。这种宏的声明语法也和可变参数函数的声明语法一样。例如:#define debug(format, ...) fprintf (stderr, format, __VA_ARGS__)
首先复习一下在没有这种技术的情况下,如何实现可变参数宏的效果: